From c25d464d18637d77197e53514f7916b31937e8b2 Mon Sep 17 00:00:00 2001 From: Jerome Date: Thu, 8 Jan 2026 20:08:50 +0000 Subject: [PATCH] feat: publish example servers to npm (#184) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: publish example servers to npm Make example MCP App servers publishable to npm under the @modelcontextprotocol scope: - server-basic-react - server-basic-vanillajs - server-budget-allocator - server-cohort-heatmap - server-customer-segmentation - server-scenario-modeler - server-system-monitor - server-threejs - server-wiki-explorer Changes: - Remove `private: true` from example package.json files - Add proper npm metadata (description, repository, license, files) - Update ext-apps dependency from relative to ^0.2.2 - Copy server-utils.ts into each package for standalone use - Add publish-examples job to npm-publish.yml workflow The examples will be published automatically when a GitHub release is created, after the main SDK package is published. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * feat: publish examples with pkg-pr-new for PR testing * feat: export createServer from example servers * style: format integration-server/server.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * fix: update e2e snapshots for basic-server examples Update golden screenshots for basic-react and basic-vanillajs after the tool output was simplified from JSON to plain text in #182. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * merge * refactor: update sheet-music-server and video-resource-server to new publishing pattern - Move server-utils.ts from src/ to root level - Add npm publishing metadata (scoped name, repository, license, files) - Change ext-apps dependency from local to versioned ^0.2.2 - Update server.ts to handle stdio mode inline * update package-lock * fix: update package-lock.json for renamed server packages * feat: add NASA public domain video to video-resource-server Added 'nasa-earth' option - NASA ISS Earth observations (6.4MB). Source: archive.org/details/NASA-Ultra-High-Definition (public domain) * fix: add default videoId for video-resource-server * fix: use existing bunny-1mb as default video, remove nasa-earth * refactor: update new framework examples to publishing pattern Add publishing metadata for: - @modelcontextprotocol/server-basic-preact - @modelcontextprotocol/server-basic-solid - @modelcontextprotocol/server-basic-svelte - @modelcontextprotocol/server-basic-vue Changes: - Move server-utils.ts from src/ to root - Add npm publishing metadata - Update ext-apps dep to versioned ^0.2.2 - Add stdio mode support in main() * fix: add missing @rollup/rollup-win32-arm64-msvc to optionalDependencies This fixes the Windows ARM64 CI build failure caused by npm's optional dependency bug. The package.json was missing this platform-specific rollup binding. --------- Co-authored-by: Claude Co-authored-by: Olivier Chafik --- .github/workflows/npm-publish.yml | 44 + .github/workflows/publish.yml | 14 +- examples/basic-server-preact/package.json | 25 +- examples/basic-server-preact/server-utils.ts | 68 + examples/basic-server-preact/server.ts | 19 +- .../basic-server-preact/src/server-utils.ts | 110 - examples/basic-server-react/package.json | 24 +- examples/basic-server-react/server-utils.ts | 68 + examples/basic-server-react/server.ts | 34 +- .../basic-server-react/src/server-utils.ts | 110 - examples/basic-server-solid/package.json | 25 +- examples/basic-server-solid/server-utils.ts | 68 + examples/basic-server-solid/server.ts | 19 +- .../basic-server-solid/src/server-utils.ts | 110 - examples/basic-server-svelte/package.json | 24 +- examples/basic-server-svelte/server-utils.ts | 68 + examples/basic-server-svelte/server.ts | 19 +- .../basic-server-svelte/src/server-utils.ts | 110 - examples/basic-server-vanillajs/package.json | 24 +- .../basic-server-vanillajs/server-utils.ts | 68 + examples/basic-server-vanillajs/server.ts | 45 +- .../src/server-utils.ts | 110 - examples/basic-server-vue/package.json | 25 +- examples/basic-server-vue/server-utils.ts | 68 + examples/basic-server-vue/server.ts | 19 +- examples/basic-server-vue/src/server-utils.ts | 110 - examples/budget-allocator-server/package.json | 24 +- .../budget-allocator-server/server-utils.ts | 68 + examples/budget-allocator-server/server.ts | 24 +- .../src/server-utils.ts | 110 - examples/cohort-heatmap-server/package.json | 24 +- .../cohort-heatmap-server/server-utils.ts | 68 + examples/cohort-heatmap-server/server.ts | 19 +- .../cohort-heatmap-server/src/server-utils.ts | 110 - .../customer-segmentation-server/package.json | 24 +- .../server-utils.ts | 68 + .../customer-segmentation-server/server.ts | 25 +- .../src/server-utils.ts | 110 - examples/integration-server/server-utils.ts | 68 + examples/integration-server/server.ts | 42 +- .../integration-server/src/server-utils.ts | 110 - examples/scenario-modeler-server/package.json | 24 +- .../scenario-modeler-server/server-utils.ts | 68 + examples/scenario-modeler-server/server.ts | 27 +- .../src/server-utils.ts | 110 - examples/sheet-music-server/package.json | 32 +- examples/sheet-music-server/server-utils.ts | 68 + examples/sheet-music-server/server.ts | 17 +- .../sheet-music-server/src/server-utils.ts | 110 - examples/system-monitor-server/package.json | 24 +- .../system-monitor-server/server-utils.ts | 68 + examples/system-monitor-server/server.ts | 19 +- .../system-monitor-server/src/server-utils.ts | 110 - examples/threejs-server/package.json | 24 +- examples/threejs-server/server-utils.ts | 68 + examples/threejs-server/server.ts | 20 +- examples/threejs-server/src/server-utils.ts | 110 - examples/video-resource-server/package.json | 25 +- .../video-resource-server/server-utils.ts | 68 + examples/video-resource-server/server.ts | 11 +- .../video-resource-server/src/server-utils.ts | 110 - examples/wiki-explorer-server/package.json | 24 +- examples/wiki-explorer-server/server-utils.ts | 68 + examples/wiki-explorer-server/server.ts | 19 +- .../wiki-explorer-server/src/server-utils.ts | 110 - package-lock.json | 2000 +++++++++++------ package.json | 1 + src/generated/schema.json | 654 +++++- .../servers.spec.ts-snapshots/basic-react.png | Bin 51482 -> 46545 bytes .../basic-vanillajs.png | Bin 50405 -> 47385 bytes 70 files changed, 3581 insertions(+), 2730 deletions(-) create mode 100644 examples/basic-server-preact/server-utils.ts delete mode 100644 examples/basic-server-preact/src/server-utils.ts create mode 100644 examples/basic-server-react/server-utils.ts delete mode 100644 examples/basic-server-react/src/server-utils.ts create mode 100644 examples/basic-server-solid/server-utils.ts delete mode 100644 examples/basic-server-solid/src/server-utils.ts create mode 100644 examples/basic-server-svelte/server-utils.ts delete mode 100644 examples/basic-server-svelte/src/server-utils.ts create mode 100644 examples/basic-server-vanillajs/server-utils.ts delete mode 100644 examples/basic-server-vanillajs/src/server-utils.ts create mode 100644 examples/basic-server-vue/server-utils.ts delete mode 100644 examples/basic-server-vue/src/server-utils.ts create mode 100644 examples/budget-allocator-server/server-utils.ts delete mode 100644 examples/budget-allocator-server/src/server-utils.ts create mode 100644 examples/cohort-heatmap-server/server-utils.ts delete mode 100644 examples/cohort-heatmap-server/src/server-utils.ts create mode 100644 examples/customer-segmentation-server/server-utils.ts delete mode 100644 examples/customer-segmentation-server/src/server-utils.ts create mode 100644 examples/integration-server/server-utils.ts delete mode 100644 examples/integration-server/src/server-utils.ts create mode 100644 examples/scenario-modeler-server/server-utils.ts delete mode 100644 examples/scenario-modeler-server/src/server-utils.ts create mode 100644 examples/sheet-music-server/server-utils.ts delete mode 100644 examples/sheet-music-server/src/server-utils.ts create mode 100644 examples/system-monitor-server/server-utils.ts delete mode 100644 examples/system-monitor-server/src/server-utils.ts create mode 100644 examples/threejs-server/server-utils.ts delete mode 100644 examples/threejs-server/src/server-utils.ts create mode 100644 examples/video-resource-server/server-utils.ts delete mode 100644 examples/video-resource-server/src/server-utils.ts create mode 100644 examples/wiki-explorer-server/server-utils.ts delete mode 100644 examples/wiki-explorer-server/src/server-utils.ts diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index c30a965..325a838 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -83,3 +83,47 @@ jobs: - run: npm publish --provenance --access public ${{ steps.npm-tag.outputs.tag }} env: NODE_AUTH_TOKEN: ${{ secrets.NPM_SECRET }} + + publish-examples: + runs-on: ubuntu-latest + if: github.event_name == 'release' + environment: Release + needs: [publish] + + permissions: + contents: read + id-token: write + + strategy: + fail-fast: false + matrix: + example: + - basic-server-react + - basic-server-vanillajs + - budget-allocator-server + - cohort-heatmap-server + - customer-segmentation-server + - scenario-modeler-server + - system-monitor-server + - threejs-server + - wiki-explorer-server + + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - uses: actions/setup-node@v4 + with: + node-version: "22" + cache: npm + registry-url: "https://registry.npmjs.org" + - run: npm ci + + - name: Build example + run: npm run build --workspace examples/${{ matrix.example }} + + - name: Publish example + run: npm publish --workspace examples/${{ matrix.example }} --provenance --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_SECRET }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d1614b1..4174e6f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,4 +20,16 @@ jobs: cache: npm - run: npm ci - run: npm run build - - run: npx pkg-pr-new publish + - run: npm run examples:build + - run: | + npx pkg-pr-new publish \ + . \ + ./examples/basic-server-react \ + ./examples/basic-server-vanillajs \ + ./examples/budget-allocator-server \ + ./examples/cohort-heatmap-server \ + ./examples/customer-segmentation-server \ + ./examples/scenario-modeler-server \ + ./examples/system-monitor-server \ + ./examples/threejs-server \ + ./examples/wiki-explorer-server diff --git a/examples/basic-server-preact/package.json b/examples/basic-server-preact/package.json index a7f5dd0..47fdc03 100644 --- a/examples/basic-server-preact/package.json +++ b/examples/basic-server-preact/package.json @@ -1,17 +1,30 @@ { - "name": "basic-server-preact", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-basic-preact", + "version": "0.1.0", "type": "module", + "description": "Basic MCP App Server example using Preact", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/basic-server-preact" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve": "bun server.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "preact": "^10.0.0", "zod": "^4.1.13" @@ -23,7 +36,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/basic-server-preact/server-utils.ts b/examples/basic-server-preact/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/basic-server-preact/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/basic-server-preact/server.ts b/examples/basic-server-preact/server.ts index ce0d71b..2f4af3d 100644 --- a/examples/basic-server-preact/server.ts +++ b/examples/basic-server-preact/server.ts @@ -1,9 +1,10 @@ -import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; -import { startServer } from "./src/server-utils.js"; +import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -55,4 +56,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (Preact)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-preact/src/server-utils.ts b/examples/basic-server-preact/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/basic-server-preact/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/basic-server-react/package.json b/examples/basic-server-react/package.json index 5927040..0918555 100644 --- a/examples/basic-server-react/package.json +++ b/examples/basic-server-react/package.json @@ -1,17 +1,30 @@ { - "name": "basic-server-react", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-basic-react", + "version": "0.1.0", "type": "module", + "description": "Basic MCP App Server example using React", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/basic-server-react" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve": "bun server.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "react": "^19.2.0", "react-dom": "^19.2.0", @@ -26,6 +39,7 @@ "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/basic-server-react/server-utils.ts b/examples/basic-server-react/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/basic-server-react/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/basic-server-react/server.ts b/examples/basic-server-react/server.ts index 6d048da..21be751 100644 --- a/examples/basic-server-react/server.ts +++ b/examples/basic-server-react/server.ts @@ -1,53 +1,45 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); /** * Creates a new MCP server instance with tools and resources registered. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Basic MCP App Server (React)", version: "1.0.0", }); - // Two-part registration: tool + resource, tied together by the resource URI. const resourceUri = "ui://get-time/mcp-app.html"; - // Register a tool with UI metadata. When the host calls this tool, it reads - // `_meta[RESOURCE_URI_META_KEY]` to know which resource to fetch and render - // as an interactive UI. registerAppTool(server, "get-time", { title: "Get Time", - description: "Returns the current server time as an ISO 8601 string.", + description: "Returns the current server time.", inputSchema: {}, _meta: { [RESOURCE_URI_META_KEY]: resourceUri }, }, async (): Promise => { - const time = new Date().toISOString(); - return { content: [{ type: "text", text: time }] }; + return { content: [{ type: "text", text: new Date().toISOString() }] }; }, ); - // Register the resource, which returns the bundled HTML/JavaScript for the UI. registerAppResource(server, resourceUri, resourceUri, { mimeType: RESOURCE_MIME_TYPE }, async (): Promise => { const html = await fs.readFile(path.join(DIST_DIR, "mcp-app.html"), "utf-8"); - return { - contents: [ - { uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html }, - ], + contents: [{ uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html }], }; }, ); @@ -55,4 +47,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (React)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-react/src/server-utils.ts b/examples/basic-server-react/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/basic-server-react/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/basic-server-solid/package.json b/examples/basic-server-solid/package.json index da875b8..f943ee1 100644 --- a/examples/basic-server-solid/package.json +++ b/examples/basic-server-solid/package.json @@ -1,17 +1,30 @@ { - "name": "basic-server-solid", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-basic-solid", + "version": "0.1.0", "type": "module", + "description": "Basic MCP App Server example using Solid", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/basic-server-solid" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve": "bun server.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "solid-js": "^1.9.0", "zod": "^4.1.13" @@ -22,7 +35,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/basic-server-solid/server-utils.ts b/examples/basic-server-solid/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/basic-server-solid/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/basic-server-solid/server.ts b/examples/basic-server-solid/server.ts index b7ede98..902649c 100644 --- a/examples/basic-server-solid/server.ts +++ b/examples/basic-server-solid/server.ts @@ -1,9 +1,10 @@ -import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; -import { startServer } from "./src/server-utils.js"; +import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -55,4 +56,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (Solid)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-solid/src/server-utils.ts b/examples/basic-server-solid/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/basic-server-solid/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/basic-server-svelte/package.json b/examples/basic-server-svelte/package.json index 88f695a..c1b165e 100644 --- a/examples/basic-server-svelte/package.json +++ b/examples/basic-server-svelte/package.json @@ -1,17 +1,30 @@ { - "name": "basic-server-svelte", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-basic-svelte", + "version": "0.1.0", "type": "module", + "description": "Basic MCP App Server example using Svelte", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/basic-server-svelte" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve": "bun server.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "svelte": "^5.0.0", "zod": "^4.1.13" @@ -23,6 +36,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/basic-server-svelte/server-utils.ts b/examples/basic-server-svelte/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/basic-server-svelte/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/basic-server-svelte/server.ts b/examples/basic-server-svelte/server.ts index 45f8641..a9c2f4a 100644 --- a/examples/basic-server-svelte/server.ts +++ b/examples/basic-server-svelte/server.ts @@ -1,9 +1,10 @@ -import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; -import { startServer } from "./src/server-utils.js"; +import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -55,4 +56,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (Svelte)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-svelte/src/server-utils.ts b/examples/basic-server-svelte/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/basic-server-svelte/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/basic-server-vanillajs/package.json b/examples/basic-server-vanillajs/package.json index 5bc5a71..aba360f 100644 --- a/examples/basic-server-vanillajs/package.json +++ b/examples/basic-server-vanillajs/package.json @@ -1,17 +1,30 @@ { - "name": "basic-server-vanillajs", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-basic-vanillajs", + "version": "0.1.0", "type": "module", + "description": "Basic MCP App Server example using vanilla JavaScript", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/basic-server-vanillajs" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve": "bun server.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "zod": "^4.1.13" }, @@ -21,6 +34,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/basic-server-vanillajs/server-utils.ts b/examples/basic-server-vanillajs/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/basic-server-vanillajs/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/basic-server-vanillajs/server.ts b/examples/basic-server-vanillajs/server.ts index a756b29..2717fc3 100644 --- a/examples/basic-server-vanillajs/server.ts +++ b/examples/basic-server-vanillajs/server.ts @@ -1,52 +1,55 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); +const RESOURCE_URI = "ui://get-time/mcp-app.html"; /** * Creates a new MCP server instance with tools and resources registered. + * Each HTTP session needs its own server instance because McpServer only supports one transport. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Basic MCP App Server (Vanilla JS)", version: "1.0.0", }); - // Two-part registration: tool + resource, tied together by the resource URI. - const resourceUri = "ui://get-time/mcp-app.html"; - - // Register a tool with UI metadata. When the host calls this tool, it reads - // `_meta[RESOURCE_URI_META_KEY]` to know which resource to fetch and render - // as an interactive UI. + // MCP Apps require two-part registration: a tool (what the LLM calls) and a + // resource (the UI it renders). The `_meta` field on the tool links to the + // resource URI, telling hosts which UI to display when the tool executes. registerAppTool(server, "get-time", { title: "Get Time", description: "Returns the current server time as an ISO 8601 string.", inputSchema: {}, - _meta: { [RESOURCE_URI_META_KEY]: resourceUri }, + _meta: { [RESOURCE_URI_META_KEY]: RESOURCE_URI }, }, async (): Promise => { const time = new Date().toISOString(); - return { content: [{ type: "text", text: time }] }; + return { + content: [{ type: "text", text: JSON.stringify({ time }) }], + }; }, ); - // Register the resource, which returns the bundled HTML/JavaScript for the UI. registerAppResource(server, - resourceUri, - resourceUri, + RESOURCE_URI, + RESOURCE_URI, { mimeType: RESOURCE_MIME_TYPE }, async (): Promise => { const html = await fs.readFile(path.join(DIST_DIR, "mcp-app.html"), "utf-8"); return { contents: [ - { uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html }, + // Per the MCP App specification, "text/html;profile=mcp-app" signals + // to the Host that this resource is indeed for an MCP App UI. + { uri: RESOURCE_URI, mimeType: RESOURCE_MIME_TYPE, text: html }, ], }; }, @@ -55,4 +58,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3102", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (Vanilla JS)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-vanillajs/src/server-utils.ts b/examples/basic-server-vanillajs/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/basic-server-vanillajs/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/basic-server-vue/package.json b/examples/basic-server-vue/package.json index d1719fc..6e8ae8c 100644 --- a/examples/basic-server-vue/package.json +++ b/examples/basic-server-vue/package.json @@ -1,17 +1,30 @@ { - "name": "basic-server-vue", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-basic-vue", + "version": "0.1.0", "type": "module", + "description": "Basic MCP App Server example using Vue", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/basic-server-vue" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve": "bun server.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "vue": "^3.5.0", "zod": "^4.1.13" @@ -23,7 +36,7 @@ "@vitejs/plugin-vue": "^5.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/basic-server-vue/server-utils.ts b/examples/basic-server-vue/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/basic-server-vue/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/basic-server-vue/server.ts b/examples/basic-server-vue/server.ts index 6f00912..dcb0831 100644 --- a/examples/basic-server-vue/server.ts +++ b/examples/basic-server-vue/server.ts @@ -1,9 +1,10 @@ -import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; -import { startServer } from "./src/server-utils.js"; +import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -55,4 +56,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Basic MCP App Server (Vue)" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/basic-server-vue/src/server-utils.ts b/examples/basic-server-vue/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/basic-server-vue/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/budget-allocator-server/package.json b/examples/budget-allocator-server/package.json index 86a9510..b353042 100644 --- a/examples/budget-allocator-server/package.json +++ b/examples/budget-allocator-server/package.json @@ -1,8 +1,20 @@ { - "name": "budget-allocator-server", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-budget-allocator", + "version": "0.1.0", "type": "module", + "description": "Budget allocator MCP App Server with interactive visualization", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/budget-allocator-server" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", @@ -11,10 +23,11 @@ "start": "npm run start:http", "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", "zod": "^4.1.13" @@ -25,6 +38,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/budget-allocator-server/server-utils.ts b/examples/budget-allocator-server/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/budget-allocator-server/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/budget-allocator-server/server.ts b/examples/budget-allocator-server/server.ts index 2796fa7..3b780d1 100755 --- a/examples/budget-allocator-server/server.ts +++ b/examples/budget-allocator-server/server.ts @@ -5,6 +5,7 @@ * and industry benchmarks by company stage. */ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -18,7 +19,7 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -231,8 +232,9 @@ const resourceUri = "ui://budget-allocator/mcp-app.html"; /** * Creates a new MCP server instance with tools and resources registered. + * Each HTTP session needs its own server instance because McpServer only supports one transport. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Budget Allocator Server", version: "1.0.0", @@ -305,4 +307,20 @@ function createServer(): McpServer { return server; } -startServer(createServer); +// --------------------------------------------------------------------------- +// Server Startup +// --------------------------------------------------------------------------- + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3103", 10); + await startServer(createServer, { port, name: "Budget Allocator Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/budget-allocator-server/src/server-utils.ts b/examples/budget-allocator-server/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/budget-allocator-server/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/cohort-heatmap-server/package.json b/examples/cohort-heatmap-server/package.json index aff8000..ebe5dfd 100644 --- a/examples/cohort-heatmap-server/package.json +++ b/examples/cohort-heatmap-server/package.json @@ -1,8 +1,20 @@ { - "name": "cohort-heatmap-server", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-cohort-heatmap", + "version": "0.1.0", "type": "module", + "description": "Cohort heatmap MCP App Server for retention analysis", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/cohort-heatmap-server" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", @@ -11,10 +23,11 @@ "start": "npm run start:http", "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "react": "^19.2.0", "react-dom": "^19.2.0", @@ -29,6 +42,7 @@ "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/cohort-heatmap-server/server-utils.ts b/examples/cohort-heatmap-server/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/cohort-heatmap-server/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/cohort-heatmap-server/server.ts b/examples/cohort-heatmap-server/server.ts index 4c26243..ccbe408 100644 --- a/examples/cohort-heatmap-server/server.ts +++ b/examples/cohort-heatmap-server/server.ts @@ -1,4 +1,5 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; @@ -9,7 +10,7 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -151,7 +152,7 @@ function generateCohortData( }; } -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Cohort Heatmap Server", version: "1.0.0", @@ -210,4 +211,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3104", 10); + await startServer(createServer, { port, name: "Cohort Heatmap Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/cohort-heatmap-server/src/server-utils.ts b/examples/cohort-heatmap-server/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/cohort-heatmap-server/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/customer-segmentation-server/package.json b/examples/customer-segmentation-server/package.json index b8b7f19..ec9551b 100644 --- a/examples/customer-segmentation-server/package.json +++ b/examples/customer-segmentation-server/package.json @@ -1,8 +1,20 @@ { - "name": "customer-segmentation-server", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-customer-segmentation", + "version": "0.1.0", "type": "module", + "description": "Customer segmentation MCP App Server with filtering", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/customer-segmentation-server" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", @@ -11,10 +23,11 @@ "start": "npm run start:http", "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", "zod": "^4.1.13" @@ -25,6 +38,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/customer-segmentation-server/server-utils.ts b/examples/customer-segmentation-server/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/customer-segmentation-server/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/customer-segmentation-server/server.ts b/examples/customer-segmentation-server/server.ts index b91ccc6..4736f61 100644 --- a/examples/customer-segmentation-server/server.ts +++ b/examples/customer-segmentation-server/server.ts @@ -1,4 +1,5 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -12,7 +13,7 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { startServer } from "./server-utils.js"; import { generateCustomers, generateSegmentSummaries, @@ -29,7 +30,7 @@ const GetCustomerDataInputSchema = z.object({ .describe("Filter by segment (default: All)"), }); -// Cache generated data for consistency across requests +// Cache generated data for session consistency let cachedCustomers: Customer[] | null = null; let cachedSegments: SegmentSummary[] | null = null; @@ -57,8 +58,9 @@ function getCustomerData(segmentFilter?: string): { /** * Creates a new MCP server instance with tools and resources registered. + * Each HTTP session needs its own server instance because McpServer only supports one transport. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Customer Segmentation Server", version: "1.0.0", @@ -117,4 +119,19 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3105", 10); + await startServer(createServer, { + port, + name: "Customer Segmentation Server", + }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/customer-segmentation-server/src/server-utils.ts b/examples/customer-segmentation-server/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/customer-segmentation-server/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/integration-server/server-utils.ts b/examples/integration-server/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/integration-server/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/integration-server/server.ts b/examples/integration-server/server.ts index b9ebd3b..d2edd23 100644 --- a/examples/integration-server/server.ts +++ b/examples/integration-server/server.ts @@ -1,17 +1,18 @@ -import { - registerAppResource, - registerAppTool, - RESOURCE_MIME_TYPE, - RESOURCE_URI_META_KEY, -} from "@modelcontextprotocol/ext-apps/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; -import { startServer } from "./src/server-utils.js"; +import { + registerAppTool, + registerAppResource, + RESOURCE_MIME_TYPE, + RESOURCE_URI_META_KEY, +} from "@modelcontextprotocol/ext-apps/server"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); const RESOURCE_URI = "ui://get-time/mcp-app.html"; @@ -19,7 +20,7 @@ const RESOURCE_URI = "ui://get-time/mcp-app.html"; /** * Creates a new MCP server instance with tools and resources registered. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Integration Test Server", version: "1.0.0", @@ -30,14 +31,18 @@ function createServer(): McpServer { "get-time", { title: "Get Time", - description: "Returns the current server time as an ISO 8601 string.", + description: "Returns the current server time.", inputSchema: {}, _meta: { [RESOURCE_URI_META_KEY]: RESOURCE_URI }, }, async (): Promise => { - const time = new Date().toISOString(); return { - content: [{ type: "text", text: JSON.stringify({ time }) }], + content: [ + { + type: "text", + text: JSON.stringify({ time: new Date().toISOString() }), + }, + ], }; }, ); @@ -52,7 +57,6 @@ function createServer(): McpServer { path.join(DIST_DIR, "mcp-app.html"), "utf-8", ); - return { contents: [ { uri: RESOURCE_URI, mimeType: RESOURCE_MIME_TYPE, text: html }, @@ -64,4 +68,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Integration Test Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/integration-server/src/server-utils.ts b/examples/integration-server/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/integration-server/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/scenario-modeler-server/package.json b/examples/scenario-modeler-server/package.json index 95c13fc..d13875c 100644 --- a/examples/scenario-modeler-server/package.json +++ b/examples/scenario-modeler-server/package.json @@ -1,8 +1,20 @@ { - "name": "scenario-modeler-server", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-scenario-modeler", + "version": "0.1.0", "type": "module", + "description": "Financial scenario modeling MCP App Server", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/scenario-modeler-server" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", @@ -11,10 +23,11 @@ "start": "npm run start:http", "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", "react": "^19.2.0", @@ -30,6 +43,7 @@ "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/scenario-modeler-server/server-utils.ts b/examples/scenario-modeler-server/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/scenario-modeler-server/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/scenario-modeler-server/server.ts b/examples/scenario-modeler-server/server.ts index fc8b7f5..3ce2066 100644 --- a/examples/scenario-modeler-server/server.ts +++ b/examples/scenario-modeler-server/server.ts @@ -1,4 +1,5 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -12,7 +13,7 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -248,8 +249,9 @@ const DEFAULT_INPUTS: ScenarioInputs = { /** * Creates a new MCP server instance with tools and resources registered. + * Each HTTP session needs its own server instance because McpServer only supports one transport. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "SaaS Scenario Modeler", version: "1.0.0", @@ -318,4 +320,23 @@ function createServer(): McpServer { return server; } -startServer(createServer); +// ============================================================================ +// Server Startup +// ============================================================================ + +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3106", 10); + await startServer(createServer, { + port, + name: "SaaS Scenario Modeler Server", + }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/scenario-modeler-server/src/server-utils.ts b/examples/scenario-modeler-server/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/scenario-modeler-server/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/sheet-music-server/package.json b/examples/sheet-music-server/package.json index a2cd1ca..81008c5 100644 --- a/examples/sheet-music-server/package.json +++ b/examples/sheet-music-server/package.json @@ -1,20 +1,30 @@ { - "name": "sheet-music-server", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-sheet-music", + "version": "0.1.0", "type": "module", + "description": "MCP App Server for rendering and playing sheet music from ABC notation", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/sheet-music-server" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", - "serve:http": "bun server.ts", - "serve:stdio": "bun server.ts --stdio", - "start": "npm run start:http", - "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", - "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'" + "serve": "bun server.ts", + "start": "cross-env NODE_ENV=development npm run build && npm run serve", + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "abcjs": "^6.4.4", "zod": "^4.1.13" @@ -25,7 +35,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/sheet-music-server/server-utils.ts b/examples/sheet-music-server/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/sheet-music-server/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/sheet-music-server/server.ts b/examples/sheet-music-server/server.ts index d6da53f..88337d3 100644 --- a/examples/sheet-music-server/server.ts +++ b/examples/sheet-music-server/server.ts @@ -13,7 +13,8 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -116,4 +117,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Sheet Music Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/sheet-music-server/src/server-utils.ts b/examples/sheet-music-server/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/sheet-music-server/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/system-monitor-server/package.json b/examples/system-monitor-server/package.json index 6adfbb9..d8198d1 100644 --- a/examples/system-monitor-server/package.json +++ b/examples/system-monitor-server/package.json @@ -1,8 +1,20 @@ { - "name": "system-monitor-server", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-system-monitor", + "version": "0.1.0", "type": "module", + "description": "System monitor MCP App Server with real-time stats", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/system-monitor-server" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", @@ -11,10 +23,11 @@ "start": "npm run start:http", "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", "systeminformation": "^5.27.11", @@ -26,6 +39,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/system-monitor-server/server-utils.ts b/examples/system-monitor-server/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/system-monitor-server/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/system-monitor-server/server.ts b/examples/system-monitor-server/server.ts index 7530050..4cf5888 100644 --- a/examples/system-monitor-server/server.ts +++ b/examples/system-monitor-server/server.ts @@ -1,4 +1,5 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -14,7 +15,7 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { startServer } from "./server-utils.js"; // Schemas - types are derived from these using z.infer const CpuCoreSchema = z.object({ @@ -106,7 +107,7 @@ async function getMemoryStats(): Promise { }; } -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "System Monitor Server", version: "1.0.0", @@ -180,4 +181,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3107", 10); + await startServer(createServer, { port, name: "System Monitor Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/system-monitor-server/src/server-utils.ts b/examples/system-monitor-server/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/system-monitor-server/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/threejs-server/package.json b/examples/threejs-server/package.json index bdc00f5..8145b8e 100644 --- a/examples/threejs-server/package.json +++ b/examples/threejs-server/package.json @@ -1,8 +1,20 @@ { - "name": "threejs-server", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-threejs", + "version": "0.1.0", "type": "module", + "description": "Three.js 3D visualization MCP App Server", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/threejs-server" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", @@ -11,10 +23,11 @@ "start": "npm run start:http", "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "react": "^19.2.0", "react-dom": "^19.2.0", @@ -31,6 +44,7 @@ "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/threejs-server/server-utils.ts b/examples/threejs-server/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/threejs-server/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/threejs-server/server.ts b/examples/threejs-server/server.ts index 8732a5f..e2f28c7 100644 --- a/examples/threejs-server/server.ts +++ b/examples/threejs-server/server.ts @@ -4,6 +4,7 @@ * Provides tools for rendering interactive 3D scenes using Three.js. */ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; import fs from "node:fs/promises"; import path from "node:path"; @@ -14,7 +15,7 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -137,8 +138,9 @@ const resourceUri = "ui://threejs/mcp-app.html"; /** * Creates a new MCP server instance with tools and resources registered. + * Each HTTP session needs its own server instance because McpServer only supports one transport. */ -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Three.js Server", version: "1.0.0", @@ -221,4 +223,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3108", 10); + await startServer(createServer, { port, name: "Three.js Server" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/threejs-server/src/server-utils.ts b/examples/threejs-server/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/threejs-server/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/video-resource-server/package.json b/examples/video-resource-server/package.json index b5efd1c..1de4cac 100644 --- a/examples/video-resource-server/package.json +++ b/examples/video-resource-server/package.json @@ -1,17 +1,30 @@ { - "name": "video-resource-server", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-video-resource", + "version": "0.1.0", "type": "module", + "description": "MCP App Server demonstrating video resources served as base64 blobs", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/video-resource-server" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", "serve": "bun server.ts", "start": "cross-env NODE_ENV=development npm run build && npm run serve", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "zod": "^4.1.13" }, @@ -21,7 +34,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", diff --git a/examples/video-resource-server/server-utils.ts b/examples/video-resource-server/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/video-resource-server/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/video-resource-server/server.ts b/examples/video-resource-server/server.ts index 2ee36bf..70effca 100644 --- a/examples/video-resource-server/server.ts +++ b/examples/video-resource-server/server.ts @@ -21,7 +21,8 @@ import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); const RESOURCE_URI = "ui://video-player/mcp-app.html"; @@ -123,6 +124,7 @@ ${Object.entries(VIDEO_LIBRARY) inputSchema: { videoId: z .enum(Object.keys(VIDEO_LIBRARY) as [string, ...string[]]) + .default("bunny-1mb") .describe( `Video ID to play. Available: ${Object.keys(VIDEO_LIBRARY).join(", ")}`, ), @@ -168,7 +170,12 @@ ${Object.entries(VIDEO_LIBRARY) } async function main() { - await startServer(createServer); + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3001", 10); + await startServer(createServer, { port, name: "Video Resource Server" }); + } } main().catch((e) => { diff --git a/examples/video-resource-server/src/server-utils.ts b/examples/video-resource-server/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/video-resource-server/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/examples/wiki-explorer-server/package.json b/examples/wiki-explorer-server/package.json index 5c389c3..47fba40 100644 --- a/examples/wiki-explorer-server/package.json +++ b/examples/wiki-explorer-server/package.json @@ -1,8 +1,20 @@ { - "name": "wiki-explorer-server", - "version": "1.0.0", - "private": true, + "name": "@modelcontextprotocol/server-wiki-explorer", + "version": "0.1.0", "type": "module", + "description": "Wikipedia link explorer MCP App Server with graph visualization", + "repository": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/ext-apps", + "directory": "examples/wiki-explorer-server" + }, + "license": "MIT", + "main": "server.ts", + "files": [ + "server.ts", + "server-utils.ts", + "dist" + ], "scripts": { "build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build", "watch": "cross-env INPUT=mcp-app.html vite build --watch", @@ -11,10 +23,11 @@ "start": "npm run start:http", "start:http": "cross-env NODE_ENV=development npm run build && npm run serve:http", "start:stdio": "cross-env NODE_ENV=development npm run build && npm run serve:stdio", - "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'" + "dev": "cross-env NODE_ENV=development concurrently 'npm run watch' 'npm run serve:http'", + "prepublishOnly": "npm run build" }, "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "cheerio": "^1.0.0", "zod": "^4.1.13" @@ -25,6 +38,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "force-graph": "^1.49.0", "typescript": "^5.9.3", diff --git a/examples/wiki-explorer-server/server-utils.ts b/examples/wiki-explorer-server/server-utils.ts new file mode 100644 index 0000000..c700c81 --- /dev/null +++ b/examples/wiki-explorer-server/server-utils.ts @@ -0,0 +1,68 @@ +/** + * Shared utilities for running MCP servers with Streamable HTTP transport. + */ + +import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import cors from "cors"; +import type { Request, Response } from "express"; + +export interface ServerOptions { + port: number; + name?: string; +} + +/** + * Starts an MCP server with Streamable HTTP transport in stateless mode. + * + * @param createServer - Factory function that creates a new McpServer instance per request. + * @param options - Server configuration options. + */ +export async function startServer( + createServer: () => McpServer, + options: ServerOptions, +): Promise { + const { port, name = "MCP Server" } = options; + + const app = createMcpExpressApp({ host: "0.0.0.0" }); + app.use(cors()); + + app.all("/mcp", async (req: Request, res: Response) => { + const server = createServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + }); + + res.on("close", () => { + transport.close().catch(() => {}); + server.close().catch(() => {}); + }); + + try { + await server.connect(transport); + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error("MCP error:", error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: "2.0", + error: { code: -32603, message: "Internal server error" }, + id: null, + }); + } + } + }); + + const httpServer = app.listen(port, () => { + console.log(`${name} listening on http://localhost:${port}/mcp`); + }); + + const shutdown = () => { + console.log("\nShutting down..."); + httpServer.close(() => process.exit(0)); + }; + + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); +} diff --git a/examples/wiki-explorer-server/server.ts b/examples/wiki-explorer-server/server.ts index 99670c6..063cacf 100644 --- a/examples/wiki-explorer-server/server.ts +++ b/examples/wiki-explorer-server/server.ts @@ -1,4 +1,5 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { CallToolResult, ReadResourceResult, @@ -13,7 +14,7 @@ import { registerAppResource, registerAppTool, } from "@modelcontextprotocol/ext-apps/server"; -import { startServer } from "./src/server-utils.js"; +import { startServer } from "./server-utils.js"; const DIST_DIR = path.join(import.meta.dirname, "dist"); @@ -71,7 +72,7 @@ function extractWikiLinks(pageUrl: URL, html: string): PageInfo[] { })); } -function createServer(): McpServer { +export function createServer(): McpServer { const server = new McpServer({ name: "Wiki Explorer", version: "1.0.0", @@ -151,4 +152,16 @@ function createServer(): McpServer { return server; } -startServer(createServer); +async function main() { + if (process.argv.includes("--stdio")) { + await createServer().connect(new StdioServerTransport()); + } else { + const port = parseInt(process.env.PORT ?? "3109", 10); + await startServer(createServer, { port, name: "Wiki Explorer" }); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/examples/wiki-explorer-server/src/server-utils.ts b/examples/wiki-explorer-server/src/server-utils.ts deleted file mode 100644 index 4052423..0000000 --- a/examples/wiki-explorer-server/src/server-utils.ts +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Shared utilities for running MCP servers with various transports. - */ - -import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js"; -import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import cors from "cors"; -import type { Request, Response } from "express"; - -/** - * Starts an MCP server using the appropriate transport based on command-line arguments. - * - * If `--stdio` is passed, uses stdio transport. Otherwise, uses Streamable HTTP transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startServer( - createServer: () => McpServer, -): Promise { - try { - if (process.argv.includes("--stdio")) { - await startStdioServer(createServer); - } else { - await startStreamableHttpServer(createServer); - } - } catch (e) { - console.error(e); - process.exit(1); - } -} - -/** - * Starts an MCP server with stdio transport. - * - * @param createServer - Factory function that creates a new McpServer instance. - */ -export async function startStdioServer( - createServer: () => McpServer, -): Promise { - await createServer().connect(new StdioServerTransport()); -} - -/** - * Starts an MCP server with Streamable HTTP transport in stateless mode. - * - * Each request creates a fresh server and transport instance, which are - * closed when the response ends (no session tracking). - * - * The server listens on the port specified by the PORT environment variable, - * defaulting to 3001 if not set. - * - * @param createServer - Factory function that creates a new McpServer instance per request. - */ -export async function startStreamableHttpServer( - createServer: () => McpServer, -): Promise { - const port = parseInt(process.env.PORT ?? "3001", 10); - - // Express app - bind to all interfaces for development/testing - const expressApp = createMcpExpressApp({ host: "0.0.0.0" }); - expressApp.use(cors()); - - expressApp.all("/mcp", async (req: Request, res: Response) => { - // Create fresh server and transport for each request (stateless mode) - const server = createServer(); - const transport = new StreamableHTTPServerTransport({ - sessionIdGenerator: undefined, - }); - - // Clean up when response ends - res.on("close", () => { - transport.close().catch(() => {}); - server.close().catch(() => {}); - }); - - try { - await server.connect(transport); - await transport.handleRequest(req, res, req.body); - } catch (error) { - console.error("MCP error:", error); - if (!res.headersSent) { - res.status(500).json({ - jsonrpc: "2.0", - error: { code: -32603, message: "Internal server error" }, - id: null, - }); - } - } - }); - - const { promise, resolve, reject } = Promise.withResolvers(); - - const httpServer = expressApp.listen(port, (err?: Error) => { - if (err) return reject(err); - console.log(`Server listening on http://localhost:${port}/mcp`); - resolve(); - }); - - const shutdown = () => { - console.log("\nShutting down..."); - httpServer.close(() => process.exit(0)); - }; - - process.on("SIGINT", shutdown); - process.on("SIGTERM", shutdown); - - return promise; -} diff --git a/package-lock.json b/package-lock.json index 467deeb..ad85c00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,6 +50,7 @@ "@rollup/rollup-darwin-x64": "^4.53.3", "@rollup/rollup-linux-arm64-gnu": "^4.53.3", "@rollup/rollup-linux-x64-gnu": "^4.53.3", + "@rollup/rollup-win32-arm64-msvc": "^4.53.3", "@rollup/rollup-win32-x64-msvc": "^4.53.3" }, "peerDependencies": { @@ -94,7 +95,9 @@ } }, "examples/basic-host/node_modules/@types/node": { - "version": "22.19.1", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -103,13 +106,17 @@ }, "examples/basic-host/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "examples/basic-server-preact": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-basic-preact", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "preact": "^10.0.0", "zod": "^4.1.13" @@ -121,7 +128,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -138,25 +145,6 @@ "undici-types": "~6.21.0" } }, - "examples/basic-server-preact/node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, "examples/basic-server-preact/node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -165,9 +153,11 @@ "license": "MIT" }, "examples/basic-server-react": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-basic-react", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "react": "^19.2.0", "react-dom": "^19.2.0", @@ -182,6 +172,7 @@ "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -189,7 +180,9 @@ } }, "examples/basic-server-react/node_modules/@types/node": { - "version": "22.19.1", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -198,13 +191,17 @@ }, "examples/basic-server-react/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "examples/basic-server-solid": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-basic-solid", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "solid-js": "^1.9.0", "zod": "^4.1.13" @@ -215,7 +212,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -233,25 +230,6 @@ "undici-types": "~6.21.0" } }, - "examples/basic-server-solid/node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, "examples/basic-server-solid/node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -260,9 +238,11 @@ "license": "MIT" }, "examples/basic-server-svelte": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-basic-svelte", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "svelte": "^5.0.0", "zod": "^4.1.13" @@ -274,6 +254,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -298,9 +279,11 @@ "license": "MIT" }, "examples/basic-server-vanillajs": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-basic-vanillajs", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "zod": "^4.1.13" }, @@ -310,6 +293,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -317,7 +301,9 @@ } }, "examples/basic-server-vanillajs/node_modules/@types/node": { - "version": "22.19.1", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -326,13 +312,17 @@ }, "examples/basic-server-vanillajs/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "examples/basic-server-vue": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-basic-vue", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "vue": "^3.5.0", "zod": "^4.1.13" @@ -344,7 +334,7 @@ "@vitejs/plugin-vue": "^5.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -361,25 +351,6 @@ "undici-types": "~6.21.0" } }, - "examples/basic-server-vue/node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, "examples/basic-server-vue/node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -388,9 +359,11 @@ "license": "MIT" }, "examples/budget-allocator-server": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-budget-allocator", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", "zod": "^4.1.13" @@ -401,6 +374,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -408,7 +382,9 @@ } }, "examples/budget-allocator-server/node_modules/@types/node": { - "version": "22.19.1", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -417,13 +393,17 @@ }, "examples/budget-allocator-server/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "examples/cohort-heatmap-server": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-cohort-heatmap", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "react": "^19.2.0", "react-dom": "^19.2.0", @@ -438,6 +418,7 @@ "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -445,7 +426,9 @@ } }, "examples/cohort-heatmap-server/node_modules/@types/node": { - "version": "22.19.1", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -454,13 +437,17 @@ }, "examples/cohort-heatmap-server/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "examples/customer-segmentation-server": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-customer-segmentation", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", "zod": "^4.1.13" @@ -471,6 +458,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -478,7 +466,9 @@ } }, "examples/customer-segmentation-server/node_modules/@types/node": { - "version": "22.19.1", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -487,6 +477,8 @@ }, "examples/customer-segmentation-server/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -516,6 +508,8 @@ }, "examples/integration-server/node_modules/@types/node": { "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -524,13 +518,17 @@ }, "examples/integration-server/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "examples/scenario-modeler-server": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-scenario-modeler", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", "react": "^19.2.0", @@ -546,6 +544,7 @@ "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -553,7 +552,9 @@ } }, "examples/scenario-modeler-server/node_modules/@types/node": { - "version": "22.19.1", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -562,13 +563,17 @@ }, "examples/scenario-modeler-server/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "examples/sheet-music-server": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-sheet-music", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "abcjs": "^6.4.4", "zod": "^4.1.13" @@ -579,7 +584,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -596,25 +601,6 @@ "undici-types": "~6.21.0" } }, - "examples/sheet-music-server/node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, "examples/sheet-music-server/node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -623,9 +609,11 @@ "license": "MIT" }, "examples/system-monitor-server": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-system-monitor", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "chart.js": "^4.4.0", "systeminformation": "^5.27.11", @@ -637,6 +625,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -644,7 +633,9 @@ } }, "examples/system-monitor-server/node_modules/@types/node": { - "version": "22.19.1", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -653,13 +644,17 @@ }, "examples/system-monitor-server/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "examples/threejs-server": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-threejs", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "react": "^19.2.0", "react-dom": "^19.2.0", @@ -676,6 +671,7 @@ "@vitejs/plugin-react": "^4.3.4", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -683,7 +679,9 @@ } }, "examples/threejs-server/node_modules/@types/node": { - "version": "22.19.1", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -692,13 +690,17 @@ }, "examples/threejs-server/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "examples/video-resource-server": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-video-resource", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "zod": "^4.1.13" }, @@ -708,7 +710,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "express": "^5.1.0", "typescript": "^5.9.3", "vite": "^6.0.0", @@ -725,25 +727,6 @@ "undici-types": "~6.21.0" } }, - "examples/video-resource-server/node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, "examples/video-resource-server/node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -752,9 +735,11 @@ "license": "MIT" }, "examples/wiki-explorer-server": { - "version": "1.0.0", + "name": "@modelcontextprotocol/server-wiki-explorer", + "version": "0.1.0", + "license": "MIT", "dependencies": { - "@modelcontextprotocol/ext-apps": "../..", + "@modelcontextprotocol/ext-apps": "^0.2.2", "@modelcontextprotocol/sdk": "^1.24.0", "cheerio": "^1.0.0", "zod": "^4.1.13" @@ -765,6 +750,7 @@ "@types/node": "^22.0.0", "concurrently": "^9.2.1", "cors": "^2.8.5", + "cross-env": "^10.1.0", "express": "^5.1.0", "force-graph": "^1.49.0", "typescript": "^5.9.3", @@ -773,7 +759,9 @@ } }, "examples/wiki-explorer-server/node_modules/@types/node": { - "version": "22.19.2", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { @@ -782,11 +770,15 @@ }, "examples/wiki-explorer-server/node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "node_modules/@babel/code-frame": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, "license": "MIT", "dependencies": { @@ -800,6 +792,8 @@ }, "node_modules/@babel/compat-data": { "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", "dev": true, "license": "MIT", "engines": { @@ -808,9 +802,10 @@ }, "node_modules/@babel/core": { "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -838,6 +833,8 @@ }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -846,6 +843,8 @@ }, "node_modules/@babel/generator": { "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -874,6 +873,8 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dev": true, "license": "MIT", "dependencies": { @@ -889,6 +890,8 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -897,6 +900,8 @@ }, "node_modules/@babel/helper-globals": { "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, "license": "MIT", "engines": { @@ -905,6 +910,8 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dev": true, "license": "MIT", "dependencies": { @@ -917,6 +924,8 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "dev": true, "license": "MIT", "dependencies": { @@ -933,6 +942,8 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "dev": true, "license": "MIT", "engines": { @@ -941,6 +952,8 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -948,6 +961,8 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -955,6 +970,8 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "license": "MIT", "engines": { @@ -963,6 +980,8 @@ }, "node_modules/@babel/helpers": { "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, "license": "MIT", "dependencies": { @@ -975,6 +994,8 @@ }, "node_modules/@babel/parser": { "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "license": "MIT", "dependencies": { "@babel/types": "^7.28.5" @@ -1040,6 +1061,8 @@ }, "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", "dev": true, "license": "MIT", "dependencies": { @@ -1054,6 +1077,8 @@ }, "node_modules/@babel/plugin-transform-react-jsx-source": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", "dev": true, "license": "MIT", "dependencies": { @@ -1068,6 +1093,8 @@ }, "node_modules/@babel/template": { "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, "license": "MIT", "dependencies": { @@ -1081,6 +1108,8 @@ }, "node_modules/@babel/traverse": { "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1098,6 +1127,8 @@ }, "node_modules/@babel/types": { "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -1109,6 +1140,8 @@ }, "node_modules/@clack/core": { "version": "1.0.0-alpha.4", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.0.0-alpha.4.tgz", + "integrity": "sha512-VCtU+vjyKPMSakVrB9q1bOnXN7QW/w4+YQDQCOF59GrzydW+169i0fVx/qzRRXJgt8KGj/pZZ/JxXroFZIDByg==", "dev": true, "license": "MIT", "dependencies": { @@ -1118,6 +1151,8 @@ }, "node_modules/@clack/prompts": { "version": "1.0.0-alpha.4", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.0.0-alpha.4.tgz", + "integrity": "sha512-KnmtDF2xQGoI5AlBme9akHtvCRV0RKAARUXHBQO2tMwnY8B08/4zPWigT7uLK25UPrMCEqnyQPkKRjNdhPbf8g==", "dev": true, "license": "MIT", "dependencies": { @@ -1128,11 +1163,15 @@ }, "node_modules/@dimforge/rapier3d-compat": { "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz", + "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==", "dev": true, "license": "Apache-2.0" }, "node_modules/@epic-web/invariant": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz", + "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==", "dev": true, "license": "MIT" }, @@ -1410,6 +1449,8 @@ }, "node_modules/@esbuild/linux-x64": { "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", "cpu": [ "x64" ], @@ -1577,19 +1618,35 @@ } }, "node_modules/@gerrit0/mini-shiki": { - "version": "3.19.0", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.21.0.tgz", + "integrity": "sha512-9PrsT5DjZA+w3lur/aOIx3FlDeHdyCEFlv9U+fmsVyjPZh61G5SYURQ/1ebe2U63KbDmI2V8IhIUegWb8hjOyg==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/engine-oniguruma": "^3.19.0", - "@shikijs/langs": "^3.19.0", - "@shikijs/themes": "^3.19.0", - "@shikijs/types": "^3.19.0", + "@shikijs/engine-oniguruma": "^3.21.0", + "@shikijs/langs": "^3.21.0", + "@shikijs/themes": "^3.21.0", + "@shikijs/types": "^3.21.0", "@shikijs/vscode-textmate": "^10.0.2" } }, + "node_modules/@hono/node-server": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.7.tgz", + "integrity": "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -1598,6 +1655,8 @@ }, "node_modules/@jridgewell/remapping": { "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -1606,6 +1665,8 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1613,10 +1674,14 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1625,6 +1690,8 @@ }, "node_modules/@kurkle/color": { "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", "license": "MIT" }, "node_modules/@modelcontextprotocol/ext-apps": { @@ -1636,9 +1703,12 @@ "link": true }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.24.3", + "version": "1.25.2", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.25.2.tgz", + "integrity": "sha512-LZFeo4F9M5qOhC/Uc1aQSrBHxMrvxett+9KLHt7OhcExtoiRN9DKgbZffMP/nxjutWDQpfMDfP3nkHI4X9ijww==", "license": "MIT", "dependencies": { + "@hono/node-server": "^1.19.7", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", @@ -1649,6 +1719,7 @@ "express": "^5.0.1", "express-rate-limit": "^7.5.0", "jose": "^6.1.1", + "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", @@ -1670,8 +1741,70 @@ } } }, + "node_modules/@modelcontextprotocol/server-basic-preact": { + "resolved": "examples/basic-server-preact", + "link": true + }, + "node_modules/@modelcontextprotocol/server-basic-react": { + "resolved": "examples/basic-server-react", + "link": true + }, + "node_modules/@modelcontextprotocol/server-basic-solid": { + "resolved": "examples/basic-server-solid", + "link": true + }, + "node_modules/@modelcontextprotocol/server-basic-svelte": { + "resolved": "examples/basic-server-svelte", + "link": true + }, + "node_modules/@modelcontextprotocol/server-basic-vanillajs": { + "resolved": "examples/basic-server-vanillajs", + "link": true + }, + "node_modules/@modelcontextprotocol/server-basic-vue": { + "resolved": "examples/basic-server-vue", + "link": true + }, + "node_modules/@modelcontextprotocol/server-budget-allocator": { + "resolved": "examples/budget-allocator-server", + "link": true + }, + "node_modules/@modelcontextprotocol/server-cohort-heatmap": { + "resolved": "examples/cohort-heatmap-server", + "link": true + }, + "node_modules/@modelcontextprotocol/server-customer-segmentation": { + "resolved": "examples/customer-segmentation-server", + "link": true + }, + "node_modules/@modelcontextprotocol/server-scenario-modeler": { + "resolved": "examples/scenario-modeler-server", + "link": true + }, + "node_modules/@modelcontextprotocol/server-sheet-music": { + "resolved": "examples/sheet-music-server", + "link": true + }, + "node_modules/@modelcontextprotocol/server-system-monitor": { + "resolved": "examples/system-monitor-server", + "link": true + }, + "node_modules/@modelcontextprotocol/server-threejs": { + "resolved": "examples/threejs-server", + "link": true + }, + "node_modules/@modelcontextprotocol/server-video-resource": { + "resolved": "examples/video-resource-server", + "link": true + }, + "node_modules/@modelcontextprotocol/server-wiki-explorer": { + "resolved": "examples/wiki-explorer-server", + "link": true + }, "node_modules/@oclif/core": { "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-4.8.0.tgz", + "integrity": "sha512-jteNUQKgJHLHFbbz806aGZqf+RJJ7t4gwF4MYa8fCwCxQ8/klJNWc0MvaJiBebk7Mc+J39mdlsB4XraaCKznFw==", "dev": true, "license": "MIT", "dependencies": { @@ -1700,6 +1833,8 @@ }, "node_modules/@oclif/core/node_modules/brace-expansion": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1708,6 +1843,8 @@ }, "node_modules/@oclif/core/node_modules/minimatch": { "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -1787,6 +1924,8 @@ }, "node_modules/@oven/bun-linux-x64": { "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.3.5.tgz", + "integrity": "sha512-n7zhKTSDZS0yOYg5Rq8easZu5Y/o47sv0c7yGr2ciFdcie9uYV55fZ7QMqhWMGK33ezCSikh5EDkUMCIvfWpjA==", "cpu": [ "x64" ], @@ -1798,6 +1937,8 @@ }, "node_modules/@oven/bun-linux-x64-baseline": { "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.3.5.tgz", + "integrity": "sha512-FeCQyBU62DMuB0nn01vPnf3McXrKOsrK9p7sHaBFYycw0mmoU8kCq/WkBkGMnLuvQljJSyen8QBTx+fXdNupWg==", "cpu": [ "x64" ], @@ -1809,6 +1950,8 @@ }, "node_modules/@oven/bun-linux-x64-musl": { "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl/-/bun-linux-x64-musl-1.3.5.tgz", + "integrity": "sha512-XkCCHkByYn8BIDvoxnny898znju4xnW2kvFE8FT5+0Y62cWdcBGMZ9RdsEUTeRz16k8hHtJpaSfLcEmNTFIwRQ==", "cpu": [ "x64" ], @@ -1820,6 +1963,8 @@ }, "node_modules/@oven/bun-linux-x64-musl-baseline": { "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl-baseline/-/bun-linux-x64-musl-baseline-1.3.5.tgz", + "integrity": "sha512-TJiYC7KCr0XxFTsxgwQOeE7dncrEL/RSyL0EzSL3xRkrxJMWBCvCSjQn7LV1i6T7hFst0+3KoN3VWvD5BinqHA==", "cpu": [ "x64" ], @@ -1857,6 +2002,8 @@ }, "node_modules/@playwright/test": { "version": "1.57.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.57.0.tgz", + "integrity": "sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1934,6 +2081,8 @@ }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", "dev": true, "license": "MIT" }, @@ -1958,38 +2107,10 @@ "dev": true, "license": "MIT" }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", - "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", - "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.5.tgz", - "integrity": "sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", + "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", "cpu": [ "arm64" ], @@ -2000,9 +2121,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.5.tgz", - "integrity": "sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", + "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", "cpu": [ "x64" ], @@ -2012,66 +2133,10 @@ "darwin" ] }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", - "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", - "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", - "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", - "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.5.tgz", - "integrity": "sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", + "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", "cpu": [ "arm64" ], @@ -2081,92 +2146,10 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", - "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", - "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", - "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", - "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", - "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", - "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.3", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", + "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", "cpu": [ "x64" ], @@ -2176,70 +2159,13 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", - "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", - "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", - "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", + "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", "cpu": [ "arm64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", - "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", - "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", - "cpu": [ - "x64" - ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2247,9 +2173,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.5.tgz", - "integrity": "sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", + "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", "cpu": [ "x64" ], @@ -2260,32 +2186,40 @@ ] }, "node_modules/@shikijs/engine-oniguruma": { - "version": "3.19.0", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.21.0.tgz", + "integrity": "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.19.0", + "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "node_modules/@shikijs/langs": { - "version": "3.19.0", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.21.0.tgz", + "integrity": "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.19.0" + "@shikijs/types": "3.21.0" } }, "node_modules/@shikijs/themes": { - "version": "3.19.0", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.21.0.tgz", + "integrity": "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "3.19.0" + "@shikijs/types": "3.21.0" } }, "node_modules/@shikijs/types": { - "version": "3.19.0", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.21.0.tgz", + "integrity": "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==", "dev": true, "license": "MIT", "dependencies": { @@ -2295,6 +2229,8 @@ }, "node_modules/@shikijs/vscode-textmate": { "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", "dev": true, "license": "MIT" }, @@ -2313,7 +2249,6 @@ "integrity": "sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.1", @@ -2350,11 +2285,15 @@ }, "node_modules/@tweenjs/tween.js": { "version": "23.1.3", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", + "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", "dev": true, "license": "MIT" }, "node_modules/@types/babel__core": { "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "license": "MIT", "dependencies": { @@ -2367,6 +2306,8 @@ }, "node_modules/@types/babel__generator": { "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, "license": "MIT", "dependencies": { @@ -2375,6 +2316,8 @@ }, "node_modules/@types/babel__template": { "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "license": "MIT", "dependencies": { @@ -2384,6 +2327,8 @@ }, "node_modules/@types/babel__traverse": { "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2392,6 +2337,8 @@ }, "node_modules/@types/body-parser": { "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "dev": true, "license": "MIT", "dependencies": { @@ -2400,15 +2347,19 @@ } }, "node_modules/@types/bun": { - "version": "1.3.3", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.3.5.tgz", + "integrity": "sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w==", "dev": true, "license": "MIT", "dependencies": { - "bun-types": "1.3.3" + "bun-types": "1.3.5" } }, "node_modules/@types/chai": { "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", "dependencies": { @@ -2418,6 +2369,8 @@ }, "node_modules/@types/connect": { "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, "license": "MIT", "dependencies": { @@ -2426,6 +2379,8 @@ }, "node_modules/@types/cors": { "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", "dev": true, "license": "MIT", "dependencies": { @@ -2434,15 +2389,21 @@ }, "node_modules/@types/deep-eql": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, "node_modules/@types/express": { "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", + "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", "dev": true, "license": "MIT", "dependencies": { @@ -2453,6 +2414,8 @@ }, "node_modules/@types/express-serve-static-core": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.0.tgz", + "integrity": "sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==", "dev": true, "license": "MIT", "dependencies": { @@ -2464,6 +2427,8 @@ }, "node_modules/@types/hast": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2472,39 +2437,49 @@ }, "node_modules/@types/http-errors": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", "dev": true, "license": "MIT" }, "node_modules/@types/node": { - "version": "24.10.1", + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", + "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } }, "node_modules/@types/qs": { "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", "dev": true, "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true, "license": "MIT" }, "node_modules/@types/react": { "version": "19.2.7", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", + "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2513,6 +2488,8 @@ }, "node_modules/@types/send": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2521,6 +2498,8 @@ }, "node_modules/@types/serve-static": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2530,11 +2509,15 @@ }, "node_modules/@types/stats.js": { "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz", + "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==", "dev": true, "license": "MIT" }, "node_modules/@types/three": { "version": "0.181.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.181.0.tgz", + "integrity": "sha512-MLF1ks8yRM2k71D7RprFpDb9DOX0p22DbdPqT/uAkc6AtQXjxWCVDjCy23G9t1o8HcQPk7woD2NIyiaWcWPYmA==", "dev": true, "license": "MIT", "dependencies": { @@ -2549,16 +2532,22 @@ }, "node_modules/@types/unist": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "dev": true, "license": "MIT" }, "node_modules/@types/webxr": { "version": "0.5.24", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz", + "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==", "dev": true, "license": "MIT" }, "node_modules/@typescript/vfs": { "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.6.2.tgz", + "integrity": "sha512-hoBwJwcbKHmvd2QVebiytN1aELvpk9B74B4L1mFm/XT1Q/VOYAWl2vQ9AWRFtQq8zmz6enTpfTV8WRc4ATjW/g==", "dev": true, "license": "MIT", "dependencies": { @@ -2570,6 +2559,8 @@ }, "node_modules/@vitejs/plugin-react": { "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", "dev": true, "license": "MIT", "dependencies": { @@ -2603,6 +2594,8 @@ }, "node_modules/@vitest/expect": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", "dev": true, "license": "MIT", "dependencies": { @@ -2618,6 +2611,8 @@ }, "node_modules/@vitest/mocker": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2643,6 +2638,8 @@ }, "node_modules/@vitest/pretty-format": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", "dev": true, "license": "MIT", "dependencies": { @@ -2654,6 +2651,8 @@ }, "node_modules/@vitest/runner": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2667,6 +2666,8 @@ }, "node_modules/@vitest/snapshot": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2680,6 +2681,8 @@ }, "node_modules/@vitest/spy": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", "dev": true, "license": "MIT", "dependencies": { @@ -2691,6 +2694,8 @@ }, "node_modules/@vitest/utils": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", "dev": true, "license": "MIT", "dependencies": { @@ -2827,14 +2832,16 @@ "license": "MIT" }, "node_modules/@webgpu/types": { - "version": "0.1.67", + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.68.tgz", + "integrity": "sha512-3ab1B59Ojb6RwjOspYLsTpCzbNB3ZaamIAxBMmvnNkiDoLTZUOBXZ9p5nAYVEkQlDdf6qAZWi1pqj9+ypiqznA==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/abcjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/abcjs/-/abcjs-6.5.2.tgz", - "integrity": "sha512-XLDZPy/4TZbOqPsLwuu0Umsl79NTAcObEkboPxdYZXI8/fU6PNh59SAnkZOnEPVbyT8EXfBUjgNoe/uKd3T0xQ==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/abcjs/-/abcjs-6.6.0.tgz", + "integrity": "sha512-lYS+qwOOxFcFY5ZjNmS1l4RT6BxGd2juBOzLD5/PfLZ+jd0zz29CMI/SwxCWb0+cdKjTBc/EHO43lUGB93FaAw==", "license": "MIT", "funding": { "type": "github", @@ -2843,6 +2850,8 @@ }, "node_modules/accepts": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "license": "MIT", "dependencies": { "mime-types": "^3.0.0", @@ -2854,6 +2863,8 @@ }, "node_modules/accessor-fn": { "version": "1.5.3", + "resolved": "https://registry.npmjs.org/accessor-fn/-/accessor-fn-1.5.3.tgz", + "integrity": "sha512-rkAofCwe/FvYFUlMB0v0gWmhqtfAtV1IUkdPbfhTUyYniu5LrC0A0UJkTH0Jv3S8SvwkmfuAlY+mQIJATdocMA==", "dev": true, "license": "MIT", "engines": { @@ -2865,7 +2876,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2875,6 +2885,8 @@ }, "node_modules/ajv": { "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -2889,6 +2901,8 @@ }, "node_modules/ajv-formats": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -2904,6 +2918,8 @@ }, "node_modules/ansi-escapes": { "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2918,6 +2934,8 @@ }, "node_modules/ansi-regex": { "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -2929,6 +2947,8 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { @@ -2943,6 +2963,8 @@ }, "node_modules/ansis": { "version": "3.17.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz", + "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==", "dev": true, "license": "ISC", "engines": { @@ -2951,6 +2973,8 @@ }, "node_modules/anymatch": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "license": "ISC", "dependencies": { @@ -2963,6 +2987,8 @@ }, "node_modules/argparse": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, @@ -2977,6 +3003,8 @@ }, "node_modules/assertion-error": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { @@ -2985,6 +3013,8 @@ }, "node_modules/async": { "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true, "license": "MIT" }, @@ -3058,43 +3088,25 @@ }, "node_modules/balanced-match": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.4", + "version": "2.9.13", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.13.tgz", + "integrity": "sha512-WhtvB2NG2wjr04+h77sg3klAIwrgOqnjS49GGudnUPGFFgg7G17y7Qecqp+2Dr5kUDxNRBca0SK7cG8JwzkWDQ==", "dev": true, "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" } }, - "node_modules/basic-server-preact": { - "resolved": "examples/basic-server-preact", - "link": true - }, - "node_modules/basic-server-react": { - "resolved": "examples/basic-server-react", - "link": true - }, - "node_modules/basic-server-solid": { - "resolved": "examples/basic-server-solid", - "link": true - }, - "node_modules/basic-server-svelte": { - "resolved": "examples/basic-server-svelte", - "link": true - }, - "node_modules/basic-server-vanillajs": { - "resolved": "examples/basic-server-vanillajs", - "link": true - }, - "node_modules/basic-server-vue": { - "resolved": "examples/basic-server-vue", - "link": true - }, "node_modules/bezier-js": { "version": "6.1.4", + "resolved": "https://registry.npmjs.org/bezier-js/-/bezier-js-6.1.4.tgz", + "integrity": "sha512-PA0FW9ZpcHbojUCMu28z9Vg/fNkwTj5YhusSAjHHDfHDGLxJ6YUKrAN2vk1fP2MMOxVw4Oko16FMlRGVBGqLKg==", "dev": true, "license": "MIT", "funding": { @@ -3104,6 +3116,8 @@ }, "node_modules/binary-extensions": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "license": "MIT", "engines": { @@ -3114,7 +3128,9 @@ } }, "node_modules/body-parser": { - "version": "2.2.1", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", @@ -3123,7 +3139,7 @@ "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", - "qs": "^6.14.0", + "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" }, @@ -3137,10 +3153,14 @@ }, "node_modules/boolbase": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "license": "ISC" }, "node_modules/brace-expansion": { "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -3150,6 +3170,8 @@ }, "node_modules/braces": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { @@ -3161,6 +3183,8 @@ }, "node_modules/browserslist": { "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -3177,7 +3201,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -3192,12 +3215,10 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/budget-allocator-server": { - "resolved": "examples/budget-allocator-server", - "link": true - }, "node_modules/bun-types": { - "version": "1.3.3", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.3.5.tgz", + "integrity": "sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw==", "dev": true, "license": "MIT", "dependencies": { @@ -3206,6 +3227,8 @@ }, "node_modules/bytes": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -3213,6 +3236,8 @@ }, "node_modules/cac": { "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, "license": "MIT", "engines": { @@ -3221,6 +3246,8 @@ }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -3232,6 +3259,8 @@ }, "node_modules/call-bound": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -3245,7 +3274,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001759", + "version": "1.0.30001763", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001763.tgz", + "integrity": "sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ==", "dev": true, "funding": [ { @@ -3265,6 +3296,8 @@ }, "node_modules/canvas-color-tracker": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/canvas-color-tracker/-/canvas-color-tracker-1.3.2.tgz", + "integrity": "sha512-ryQkDX26yJ3CXzb3hxUVNlg1NKE4REc5crLBq661Nxzr8TNd236SaEf2ffYLXyI5tSABSeguHLqcVq4vf9L3Zg==", "dev": true, "license": "MIT", "dependencies": { @@ -3276,6 +3309,8 @@ }, "node_modules/chai": { "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", "dev": true, "license": "MIT", "dependencies": { @@ -3291,6 +3326,8 @@ }, "node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { @@ -3306,6 +3343,8 @@ }, "node_modules/chalk/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { @@ -3317,6 +3356,8 @@ }, "node_modules/chart.js": { "version": "4.5.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz", + "integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==", "license": "MIT", "dependencies": { "@kurkle/color": "^0.3.0" @@ -3326,7 +3367,9 @@ } }, "node_modules/check-error": { - "version": "2.1.1", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", "dev": true, "license": "MIT", "engines": { @@ -3335,6 +3378,8 @@ }, "node_modules/cheerio": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz", + "integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==", "license": "MIT", "dependencies": { "cheerio-select": "^2.1.0", @@ -3358,6 +3403,8 @@ }, "node_modules/cheerio-select": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -3373,6 +3420,8 @@ }, "node_modules/chokidar": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -3396,6 +3445,8 @@ }, "node_modules/clean-stack": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", "dev": true, "license": "MIT", "dependencies": { @@ -3410,6 +3461,8 @@ }, "node_modules/cli-cursor": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, "license": "MIT", "dependencies": { @@ -3424,6 +3477,8 @@ }, "node_modules/cli-spinners": { "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, "license": "MIT", "engines": { @@ -3435,6 +3490,8 @@ }, "node_modules/cli-truncate": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", + "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", "dev": true, "license": "MIT", "dependencies": { @@ -3450,6 +3507,8 @@ }, "node_modules/cli-truncate/node_modules/string-width": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", "dev": true, "license": "MIT", "dependencies": { @@ -3465,6 +3524,8 @@ }, "node_modules/cliui": { "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "license": "ISC", "dependencies": { @@ -3478,6 +3539,8 @@ }, "node_modules/cliui/node_modules/ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -3486,6 +3549,8 @@ }, "node_modules/cliui/node_modules/strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -3504,12 +3569,10 @@ "node": ">=6" } }, - "node_modules/cohort-heatmap-server": { - "resolved": "examples/cohort-heatmap-server", - "link": true - }, "node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3521,21 +3584,29 @@ }, "node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/colorette": { "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true, "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "license": "MIT" }, "node_modules/concurrently": { "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", "dev": true, "license": "MIT", "dependencies": { @@ -3559,6 +3630,8 @@ }, "node_modules/content-disposition": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", "license": "MIT", "engines": { "node": ">=18" @@ -3570,6 +3643,8 @@ }, "node_modules/content-type": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -3577,11 +3652,15 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, "node_modules/cookie": { "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -3589,6 +3668,8 @@ }, "node_modules/cookie-signature": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "license": "MIT", "engines": { "node": ">=6.6.0" @@ -3596,6 +3677,8 @@ }, "node_modules/cors": { "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -3607,6 +3690,8 @@ }, "node_modules/cross-env": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz", + "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==", "dev": true, "license": "MIT", "dependencies": { @@ -3623,6 +3708,8 @@ }, "node_modules/cross-spawn": { "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -3635,6 +3722,8 @@ }, "node_modules/css-select": { "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -3649,6 +3738,8 @@ }, "node_modules/css-what": { "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", "license": "BSD-2-Clause", "engines": { "node": ">= 6" @@ -3659,14 +3750,14 @@ }, "node_modules/csstype": { "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, - "node_modules/customer-segmentation-server": { - "resolved": "examples/customer-segmentation-server", - "link": true - }, "node_modules/d3-array": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", "dev": true, "license": "ISC", "dependencies": { @@ -3678,11 +3769,15 @@ }, "node_modules/d3-binarytree": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d3-binarytree/-/d3-binarytree-1.0.2.tgz", + "integrity": "sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==", "dev": true, "license": "MIT" }, "node_modules/d3-color": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", "dev": true, "license": "ISC", "engines": { @@ -3691,6 +3786,8 @@ }, "node_modules/d3-dispatch": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", "dev": true, "license": "ISC", "engines": { @@ -3699,6 +3796,8 @@ }, "node_modules/d3-drag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", "dev": true, "license": "ISC", "dependencies": { @@ -3711,6 +3810,8 @@ }, "node_modules/d3-ease": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -3719,6 +3820,8 @@ }, "node_modules/d3-force-3d": { "version": "3.0.6", + "resolved": "https://registry.npmjs.org/d3-force-3d/-/d3-force-3d-3.0.6.tgz", + "integrity": "sha512-4tsKHUPLOVkyfEffZo1v6sFHvGFwAIIjt/W8IThbp08DYAsXZck+2pSHEG5W1+gQgEvFLdZkYvmJAbRM2EzMnA==", "dev": true, "license": "MIT", "dependencies": { @@ -3734,6 +3837,8 @@ }, "node_modules/d3-format": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", "dev": true, "license": "ISC", "engines": { @@ -3742,6 +3847,8 @@ }, "node_modules/d3-interpolate": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", "dev": true, "license": "ISC", "dependencies": { @@ -3753,11 +3860,15 @@ }, "node_modules/d3-octree": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-octree/-/d3-octree-1.1.0.tgz", + "integrity": "sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A==", "dev": true, "license": "MIT" }, "node_modules/d3-quadtree": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", "dev": true, "license": "ISC", "engines": { @@ -3766,6 +3877,8 @@ }, "node_modules/d3-scale": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", "dev": true, "license": "ISC", "dependencies": { @@ -3781,6 +3894,8 @@ }, "node_modules/d3-scale-chromatic": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", "dev": true, "license": "ISC", "dependencies": { @@ -3793,15 +3908,18 @@ }, "node_modules/d3-selection": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "dev": true, "license": "ISC", - "peer": true, "engines": { "node": ">=12" } }, "node_modules/d3-time": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", "dev": true, "license": "ISC", "dependencies": { @@ -3813,6 +3931,8 @@ }, "node_modules/d3-time-format": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", "dev": true, "license": "ISC", "dependencies": { @@ -3824,6 +3944,8 @@ }, "node_modules/d3-timer": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", "dev": true, "license": "ISC", "engines": { @@ -3832,6 +3954,8 @@ }, "node_modules/d3-transition": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", "dev": true, "license": "ISC", "dependencies": { @@ -3850,6 +3974,8 @@ }, "node_modules/d3-zoom": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", "dev": true, "license": "ISC", "dependencies": { @@ -3865,6 +3991,8 @@ }, "node_modules/debug": { "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -3880,6 +4008,8 @@ }, "node_modules/deep-eql": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", "engines": { @@ -3898,6 +4028,8 @@ }, "node_modules/depd": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -3911,6 +4043,8 @@ }, "node_modules/dom-serializer": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", @@ -3923,6 +4057,8 @@ }, "node_modules/domelementtype": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "funding": [ { "type": "github", @@ -3933,6 +4069,8 @@ }, "node_modules/domhandler": { "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" @@ -3946,6 +4084,8 @@ }, "node_modules/domutils": { "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", @@ -3958,6 +4098,8 @@ }, "node_modules/dunder-proto": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -3970,10 +4112,14 @@ }, "node_modules/ee-first": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, "node_modules/ejs": { "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3987,17 +4133,23 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.266", + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", "dev": true, "license": "ISC" }, "node_modules/emoji-regex": { "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -4005,6 +4157,8 @@ }, "node_modules/encoding-sniffer": { "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", "license": "MIT", "dependencies": { "iconv-lite": "^0.6.3", @@ -4016,6 +4170,8 @@ }, "node_modules/encoding-sniffer/node_modules/iconv-lite": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -4026,6 +4182,8 @@ }, "node_modules/entities": { "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -4036,6 +4194,8 @@ }, "node_modules/environment": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "dev": true, "license": "MIT", "engines": { @@ -4047,6 +4207,8 @@ }, "node_modules/es-define-property": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -4054,6 +4216,8 @@ }, "node_modules/es-errors": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -4061,11 +4225,15 @@ }, "node_modules/es-module-lexer": { "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "dev": true, "license": "MIT" }, "node_modules/es-object-atoms": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -4076,6 +4244,8 @@ }, "node_modules/esbuild": { "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -4116,6 +4286,8 @@ }, "node_modules/escalade": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -4124,10 +4296,14 @@ }, "node_modules/escape-html": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { @@ -4154,6 +4330,8 @@ }, "node_modules/estree-walker": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { @@ -4162,6 +4340,8 @@ }, "node_modules/etag": { "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -4169,11 +4349,15 @@ }, "node_modules/eventemitter3": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "dev": true, "license": "MIT" }, "node_modules/eventsource": { "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", "license": "MIT", "dependencies": { "eventsource-parser": "^3.0.1" @@ -4184,13 +4368,17 @@ }, "node_modules/eventsource-parser": { "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", "license": "MIT", "engines": { "node": ">=18.0.0" } }, "node_modules/expect-type": { - "version": "1.2.2", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4199,8 +4387,9 @@ }, "node_modules/express": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", - "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -4241,6 +4430,8 @@ }, "node_modules/express-rate-limit": { "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", "license": "MIT", "engines": { "node": ">= 16" @@ -4254,10 +4445,14 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, "node_modules/fast-uri": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "funding": [ { "type": "github", @@ -4272,11 +4467,15 @@ }, "node_modules/fflate": { "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", "dev": true, "license": "MIT" }, "node_modules/filelist": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4285,6 +4484,8 @@ }, "node_modules/filelist/node_modules/brace-expansion": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4293,6 +4494,8 @@ }, "node_modules/filelist/node_modules/minimatch": { "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", "dependencies": { @@ -4304,6 +4507,8 @@ }, "node_modules/fill-range": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { @@ -4315,6 +4520,8 @@ }, "node_modules/finalhandler": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -4334,6 +4541,8 @@ }, "node_modules/float-tooltip": { "version": "1.7.5", + "resolved": "https://registry.npmjs.org/float-tooltip/-/float-tooltip-1.7.5.tgz", + "integrity": "sha512-/kXzuDnnBqyyWyhDMH7+PfP8J/oXiAavGzcRxASOMRHFuReDtofizLLJsf7nnDLAfEaMW4pVWaXrAjtnglpEkg==", "dev": true, "license": "MIT", "dependencies": { @@ -4347,6 +4556,8 @@ }, "node_modules/force-graph": { "version": "1.51.0", + "resolved": "https://registry.npmjs.org/force-graph/-/force-graph-1.51.0.tgz", + "integrity": "sha512-aTnihCmiMA0ItLJLCbrQYS9mzriopW24goFPgUnKAAmAlPogTSmFWqoBPMXzIfPb7bs04Hur5zEI4WYgLW3Sig==", "dev": true, "license": "MIT", "dependencies": { @@ -4372,6 +4583,8 @@ }, "node_modules/forwarded": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -4379,6 +4592,8 @@ }, "node_modules/fresh": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -4389,7 +4604,6 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -4401,6 +4615,8 @@ }, "node_modules/function-bind": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4408,6 +4624,8 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", "engines": { @@ -4416,6 +4634,8 @@ }, "node_modules/get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "license": "ISC", "engines": { @@ -4424,6 +4644,8 @@ }, "node_modules/get-east-asian-width": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", "dev": true, "license": "MIT", "engines": { @@ -4435,6 +4657,8 @@ }, "node_modules/get-intrinsic": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -4457,6 +4681,8 @@ }, "node_modules/get-package-type": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, "license": "MIT", "engines": { @@ -4465,6 +4691,8 @@ }, "node_modules/get-proto": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -4476,6 +4704,8 @@ }, "node_modules/get-tsconfig": { "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4487,6 +4717,8 @@ }, "node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "license": "ISC", "dependencies": { @@ -4498,6 +4730,8 @@ }, "node_modules/gopd": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -4508,6 +4742,8 @@ }, "node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { @@ -4516,6 +4752,8 @@ }, "node_modules/has-symbols": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -4526,6 +4764,8 @@ }, "node_modules/hasown": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -4544,6 +4784,16 @@ "he": "bin/he" } }, + "node_modules/hono": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.3.tgz", + "integrity": "sha512-PmQi306+M/ct/m5s66Hrg+adPnkD5jiO6IjA7WhWw0gSBSo1EcRegwuI1deZ+wd5pzCGynCcn2DprnE4/yEV4w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" + } + }, "node_modules/html-entities": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", @@ -4553,6 +4803,8 @@ }, "node_modules/htmlparser2": { "version": "10.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -4570,6 +4822,8 @@ }, "node_modules/htmlparser2/node_modules/entities": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -4580,6 +4834,8 @@ }, "node_modules/http-errors": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { "depd": "~2.0.0", @@ -4598,6 +4854,8 @@ }, "node_modules/husky": { "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", "dev": true, "license": "MIT", "bin": { @@ -4611,7 +4869,9 @@ } }, "node_modules/iconv-lite": { - "version": "0.7.0", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -4626,11 +4886,15 @@ }, "node_modules/ignore-by-default": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true, "license": "ISC" }, "node_modules/indent-string": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, "license": "MIT", "engines": { @@ -4639,6 +4903,8 @@ }, "node_modules/index-array-by": { "version": "1.4.2", + "resolved": "https://registry.npmjs.org/index-array-by/-/index-array-by-1.4.2.tgz", + "integrity": "sha512-SP23P27OUKzXWEC/TOyWlwLviofQkCSCKONnc62eItjp69yCZZPqDQtr3Pw5gJDnPeUMqExmKydNZaJO0FU9pw==", "dev": true, "license": "MIT", "engines": { @@ -4647,6 +4913,8 @@ }, "node_modules/inherits": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/integration-server": { @@ -4655,6 +4923,8 @@ }, "node_modules/internmap": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", "dev": true, "license": "ISC", "engines": { @@ -4663,6 +4933,8 @@ }, "node_modules/ipaddr.js": { "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -4670,6 +4942,8 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "license": "MIT", "dependencies": { @@ -4681,6 +4955,8 @@ }, "node_modules/is-docker": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, "license": "MIT", "bin": { @@ -4695,6 +4971,8 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { @@ -4703,6 +4981,8 @@ }, "node_modules/is-fullwidth-code-point": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4717,6 +4997,8 @@ }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { @@ -4728,6 +5010,8 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", "engines": { @@ -4736,6 +5020,8 @@ }, "node_modules/is-promise": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, "node_modules/is-reference": { @@ -4762,6 +5048,8 @@ }, "node_modules/is-wsl": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "license": "MIT", "dependencies": { @@ -4773,10 +5061,14 @@ }, "node_modules/isexe": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, "node_modules/jake": { "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4793,6 +5085,8 @@ }, "node_modules/jose": { "version": "6.1.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", + "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -4800,11 +5094,15 @@ }, "node_modules/js-tokens": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, "license": "MIT" }, "node_modules/jsesc": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", "bin": { @@ -4816,10 +5114,20 @@ }, "node_modules/json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, "node_modules/json5": { "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", "bin": { @@ -4831,6 +5139,8 @@ }, "node_modules/kapsule": { "version": "1.16.3", + "resolved": "https://registry.npmjs.org/kapsule/-/kapsule-1.16.3.tgz", + "integrity": "sha512-4+5mNNf4vZDSwPhKprKwz3330iisPrb08JyMgbsdFrimBCKNHecua/WBwvVg3n7vwx0C1ARjfhwIpbrbd9n5wg==", "dev": true, "license": "MIT", "dependencies": { @@ -4859,6 +5169,8 @@ }, "node_modules/lilconfig": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, "license": "MIT", "engines": { @@ -4870,6 +5182,8 @@ }, "node_modules/linkify-it": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4878,6 +5192,8 @@ }, "node_modules/listr2": { "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", "dev": true, "license": "MIT", "dependencies": { @@ -4894,6 +5210,8 @@ }, "node_modules/listr2/node_modules/ansi-styles": { "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -4905,11 +5223,15 @@ }, "node_modules/listr2/node_modules/emoji-regex": { "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, "license": "MIT" }, "node_modules/listr2/node_modules/string-width": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4926,6 +5248,8 @@ }, "node_modules/listr2/node_modules/wrap-ansi": { "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, "license": "MIT", "dependencies": { @@ -4947,12 +5271,16 @@ "license": "MIT" }, "node_modules/lodash-es": { - "version": "4.17.21", + "version": "4.17.22", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.22.tgz", + "integrity": "sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q==", "dev": true, "license": "MIT" }, "node_modules/log-update": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", "dev": true, "license": "MIT", "dependencies": { @@ -4971,6 +5299,8 @@ }, "node_modules/log-update/node_modules/ansi-escapes": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", + "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==", "dev": true, "license": "MIT", "dependencies": { @@ -4985,6 +5315,8 @@ }, "node_modules/log-update/node_modules/ansi-styles": { "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -4996,11 +5328,15 @@ }, "node_modules/log-update/node_modules/emoji-regex": { "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, "license": "MIT" }, "node_modules/log-update/node_modules/string-width": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5017,6 +5353,8 @@ }, "node_modules/log-update/node_modules/wrap-ansi": { "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, "license": "MIT", "dependencies": { @@ -5033,11 +5371,15 @@ }, "node_modules/loupe": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", "dev": true, "license": "MIT" }, "node_modules/lru-cache": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "license": "ISC", "dependencies": { @@ -5046,11 +5388,15 @@ }, "node_modules/lunr": { "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "dev": true, "license": "MIT" }, "node_modules/magic-string": { "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -5058,6 +5404,8 @@ }, "node_modules/markdown-it": { "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "license": "MIT", "dependencies": { @@ -5074,6 +5422,8 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -5081,11 +5431,15 @@ }, "node_modules/mdurl": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true, "license": "MIT" }, "node_modules/media-typer": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -5109,6 +5463,8 @@ }, "node_modules/merge-descriptors": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "license": "MIT", "engines": { "node": ">=18" @@ -5119,11 +5475,15 @@ }, "node_modules/meshoptimizer": { "version": "0.22.0", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.22.0.tgz", + "integrity": "sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==", "dev": true, "license": "MIT" }, "node_modules/micromatch": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -5136,6 +5496,8 @@ }, "node_modules/mime-db": { "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -5143,6 +5505,8 @@ }, "node_modules/mime-types": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" @@ -5157,6 +5521,8 @@ }, "node_modules/mimic-function": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", "dev": true, "license": "MIT", "engines": { @@ -5168,6 +5534,8 @@ }, "node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -5179,10 +5547,14 @@ }, "node_modules/ms": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", @@ -5199,6 +5571,8 @@ }, "node_modules/negotiator": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -5217,11 +5591,15 @@ }, "node_modules/node-releases": { "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, "node_modules/nodemon": { "version": "3.1.11", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.11.tgz", + "integrity": "sha512-is96t8F/1//UHAjNPHpbsNY46ELPpftGUoSVNXwUfMk/qdjSylYrWSu1XavVTBOn526kFiOR733ATgNBCQyH0g==", "dev": true, "license": "MIT", "dependencies": { @@ -5249,6 +5627,8 @@ }, "node_modules/nodemon/node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "license": "MIT", "engines": { @@ -5257,6 +5637,8 @@ }, "node_modules/nodemon/node_modules/supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "license": "MIT", "dependencies": { @@ -5268,6 +5650,8 @@ }, "node_modules/normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "license": "MIT", "engines": { @@ -5276,6 +5660,8 @@ }, "node_modules/nth-check": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" @@ -5286,6 +5672,8 @@ }, "node_modules/object-assign": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5293,6 +5681,8 @@ }, "node_modules/object-inspect": { "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -5303,6 +5693,8 @@ }, "node_modules/on-finished": { "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -5313,6 +5705,8 @@ }, "node_modules/once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { "wrappy": "1" @@ -5320,6 +5714,8 @@ }, "node_modules/onetime": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5334,6 +5730,8 @@ }, "node_modules/parse5": { "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", "license": "MIT", "dependencies": { "entities": "^6.0.0" @@ -5344,6 +5742,8 @@ }, "node_modules/parse5-htmlparser2-tree-adapter": { "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", "license": "MIT", "dependencies": { "domhandler": "^5.0.3", @@ -5355,6 +5755,8 @@ }, "node_modules/parse5-parser-stream": { "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", "license": "MIT", "dependencies": { "parse5": "^7.0.0" @@ -5365,6 +5767,8 @@ }, "node_modules/parse5/node_modules/entities": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -5375,6 +5779,8 @@ }, "node_modules/parseurl": { "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -5382,6 +5788,8 @@ }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { "node": ">=8" @@ -5389,6 +5797,8 @@ }, "node_modules/path-to-regexp": { "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", "license": "MIT", "funding": { "type": "opencollective", @@ -5397,11 +5807,15 @@ }, "node_modules/pathe": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, "node_modules/pathval": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", "engines": { @@ -5410,10 +5824,14 @@ }, "node_modules/picocolors": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { @@ -5425,6 +5843,8 @@ }, "node_modules/pkce-challenge": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", "license": "MIT", "engines": { "node": ">=16.20.0" @@ -5432,6 +5852,8 @@ }, "node_modules/playwright": { "version": "1.57.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.57.0.tgz", + "integrity": "sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5449,6 +5871,8 @@ }, "node_modules/playwright-core": { "version": "1.57.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.57.0.tgz", + "integrity": "sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -5463,7 +5887,6 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -5475,6 +5898,8 @@ }, "node_modules/postcss": { "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "funding": [ { "type": "opencollective", @@ -5500,9 +5925,10 @@ } }, "node_modules/preact": { - "version": "10.28.0", + "version": "10.28.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.2.tgz", + "integrity": "sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==", "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -5526,6 +5952,8 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -5537,11 +5965,15 @@ }, "node_modules/pstree.remy": { "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true, "license": "MIT" }, "node_modules/punycode.js": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", "dev": true, "license": "MIT", "engines": { @@ -5549,7 +5981,9 @@ } }, "node_modules/qs": { - "version": "6.14.0", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -5563,6 +5997,8 @@ }, "node_modules/range-parser": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -5570,6 +6006,8 @@ }, "node_modules/raw-body": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "license": "MIT", "dependencies": { "bytes": "~3.1.2", @@ -5582,25 +6020,30 @@ } }, "node_modules/react": { - "version": "19.2.1", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.2.1", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.1" + "react": "^19.2.3" } }, "node_modules/react-refresh": { "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", "dev": true, "license": "MIT", "engines": { @@ -5609,6 +6052,8 @@ }, "node_modules/readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", "dependencies": { @@ -5620,6 +6065,8 @@ }, "node_modules/require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "license": "MIT", "engines": { @@ -5628,6 +6075,8 @@ }, "node_modules/require-from-string": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5635,6 +6084,8 @@ }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, "license": "MIT", "funding": { @@ -5643,6 +6094,8 @@ }, "node_modules/restore-cursor": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "dev": true, "license": "MIT", "dependencies": { @@ -5658,11 +6111,15 @@ }, "node_modules/rfdc": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true, "license": "MIT" }, "node_modules/rollup": { - "version": "4.53.3", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz", + "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==", "dev": true, "license": "MIT", "dependencies": { @@ -5676,89 +6133,38 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.53.3", - "@rollup/rollup-android-arm64": "4.53.3", - "@rollup/rollup-darwin-arm64": "4.53.3", - "@rollup/rollup-darwin-x64": "4.53.3", - "@rollup/rollup-freebsd-arm64": "4.53.3", - "@rollup/rollup-freebsd-x64": "4.53.3", - "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", - "@rollup/rollup-linux-arm-musleabihf": "4.53.3", - "@rollup/rollup-linux-arm64-gnu": "4.53.3", - "@rollup/rollup-linux-arm64-musl": "4.53.3", - "@rollup/rollup-linux-loong64-gnu": "4.53.3", - "@rollup/rollup-linux-ppc64-gnu": "4.53.3", - "@rollup/rollup-linux-riscv64-gnu": "4.53.3", - "@rollup/rollup-linux-riscv64-musl": "4.53.3", - "@rollup/rollup-linux-s390x-gnu": "4.53.3", - "@rollup/rollup-linux-x64-gnu": "4.53.3", - "@rollup/rollup-linux-x64-musl": "4.53.3", - "@rollup/rollup-openharmony-arm64": "4.53.3", - "@rollup/rollup-win32-arm64-msvc": "4.53.3", - "@rollup/rollup-win32-ia32-msvc": "4.53.3", - "@rollup/rollup-win32-x64-gnu": "4.53.3", - "@rollup/rollup-win32-x64-msvc": "4.53.3", + "@rollup/rollup-android-arm-eabi": "4.55.1", + "@rollup/rollup-android-arm64": "4.55.1", + "@rollup/rollup-darwin-arm64": "4.55.1", + "@rollup/rollup-darwin-x64": "4.55.1", + "@rollup/rollup-freebsd-arm64": "4.55.1", + "@rollup/rollup-freebsd-x64": "4.55.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", + "@rollup/rollup-linux-arm-musleabihf": "4.55.1", + "@rollup/rollup-linux-arm64-gnu": "4.55.1", + "@rollup/rollup-linux-arm64-musl": "4.55.1", + "@rollup/rollup-linux-loong64-gnu": "4.55.1", + "@rollup/rollup-linux-loong64-musl": "4.55.1", + "@rollup/rollup-linux-ppc64-gnu": "4.55.1", + "@rollup/rollup-linux-ppc64-musl": "4.55.1", + "@rollup/rollup-linux-riscv64-gnu": "4.55.1", + "@rollup/rollup-linux-riscv64-musl": "4.55.1", + "@rollup/rollup-linux-s390x-gnu": "4.55.1", + "@rollup/rollup-linux-x64-gnu": "4.55.1", + "@rollup/rollup-linux-x64-musl": "4.55.1", + "@rollup/rollup-openbsd-x64": "4.55.1", + "@rollup/rollup-openharmony-arm64": "4.55.1", + "@rollup/rollup-win32-arm64-msvc": "4.55.1", + "@rollup/rollup-win32-ia32-msvc": "4.55.1", + "@rollup/rollup-win32-x64-gnu": "4.55.1", + "@rollup/rollup-win32-x64-msvc": "4.55.1", "fsevents": "~2.3.2" } }, - "node_modules/rollup/node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", - "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/rollup/node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", - "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", - "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/rollup/node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", - "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/router": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -5773,6 +6179,8 @@ }, "node_modules/rxjs": { "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5781,18 +6189,20 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, - "node_modules/scenario-modeler-server": { - "resolved": "examples/scenario-modeler-server", - "link": true - }, "node_modules/scheduler": { "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, "node_modules/semver": { "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -5803,23 +6213,29 @@ } }, "node_modules/send": { - "version": "1.2.0", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { - "debug": "^4.3.5", + "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.0", - "mime-types": "^3.0.1", + "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.1" + "statuses": "^2.0.2" }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/seroval": { @@ -5827,7 +6243,6 @@ "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.3.2.tgz", "integrity": "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=10" } @@ -5845,7 +6260,9 @@ } }, "node_modules/serve-static": { - "version": "2.2.0", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", @@ -5855,14 +6272,22 @@ }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/setprototypeof": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -5873,17 +6298,17 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/sheet-music-server": { - "resolved": "examples/sheet-music-server", - "link": true - }, "node_modules/shell-quote": { "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", "dev": true, "license": "MIT", "engines": { @@ -5895,6 +6320,8 @@ }, "node_modules/side-channel": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -5912,6 +6339,8 @@ }, "node_modules/side-channel-list": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -5926,6 +6355,8 @@ }, "node_modules/side-channel-map": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -5942,6 +6373,8 @@ }, "node_modules/side-channel-weakmap": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -5959,11 +6392,15 @@ }, "node_modules/siginfo": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, "node_modules/signal-exit": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "license": "ISC", "engines": { @@ -5985,6 +6422,8 @@ }, "node_modules/simple-update-notifier": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", "dev": true, "license": "MIT", "dependencies": { @@ -5996,11 +6435,15 @@ }, "node_modules/sisteransi": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true, "license": "MIT" }, "node_modules/slash": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, "license": "MIT", "engines": { @@ -6012,6 +6455,8 @@ }, "node_modules/slice-ansi": { "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "dev": true, "license": "MIT", "dependencies": { @@ -6027,6 +6472,8 @@ }, "node_modules/slice-ansi/node_modules/ansi-styles": { "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -6041,7 +6488,6 @@ "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.10.tgz", "integrity": "sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==", "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", @@ -6075,6 +6521,8 @@ }, "node_modules/source-map-js": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -6092,11 +6540,15 @@ }, "node_modules/stackback": { "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, "node_modules/statuses": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -6104,11 +6556,15 @@ }, "node_modules/std-env": { "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", "dev": true, "license": "MIT" }, "node_modules/string-width": { "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { @@ -6122,6 +6578,8 @@ }, "node_modules/string-width/node_modules/ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -6130,6 +6588,8 @@ }, "node_modules/string-width/node_modules/is-fullwidth-code-point": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { @@ -6138,6 +6598,8 @@ }, "node_modules/string-width/node_modules/strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -6149,6 +6611,8 @@ }, "node_modules/strip-ansi": { "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -6163,6 +6627,8 @@ }, "node_modules/strip-literal": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", "dev": true, "license": "MIT", "dependencies": { @@ -6174,11 +6640,15 @@ }, "node_modules/strip-literal/node_modules/js-tokens": { "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true, "license": "MIT" }, "node_modules/supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -6192,11 +6662,10 @@ } }, "node_modules/svelte": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.46.0.tgz", - "integrity": "sha512-ZhLtvroYxUxr+HQJfMZEDRsGsmU46x12RvAv/zi9584f5KOX7bUrEbhPJ7cKFmUvZTJXi/CFZUYwDC6M1FigPw==", + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.46.1.tgz", + "integrity": "sha512-ynjfCHD3nP2el70kN5Pmg37sSi0EjOm9FgHYQdC4giWG/hzO3AatzXXJJgP305uIhGQxSufJLuYWtkY8uK/8RA==", "license": "MIT", - "peer": true, "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", @@ -6218,12 +6687,10 @@ "node": ">=18" } }, - "node_modules/system-monitor-server": { - "resolved": "examples/system-monitor-server", - "link": true - }, "node_modules/systeminformation": { - "version": "5.27.11", + "version": "5.30.2", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.30.2.tgz", + "integrity": "sha512-Rrt5oFTWluUVuPlbtn3o9ja+nvjdF3Um4DG0KxqfYvpzcx7Q9plZBTjJiJy9mAouua4+OI7IUGBaG9Zyt9NgxA==", "license": "MIT", "os": [ "darwin", @@ -6248,6 +6715,8 @@ }, "node_modules/text-camel-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-camel-case/-/text-camel-case-1.2.9.tgz", + "integrity": "sha512-wKYs9SgRxYizJE1mneR7BbLNlGw2IYzJAS8XwkWIry0CTbO1gvvPkFsx5Z1/hr+VqUaBqx9q3yKd30HpZLdMsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6256,6 +6725,8 @@ }, "node_modules/text-capital-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-capital-case/-/text-capital-case-1.2.9.tgz", + "integrity": "sha512-X5zV8U8pxtq2xS2t46lgAWqZdDbgWMKq03MQSNwY2CJdQCsdTNh144E2Q/q9wBxWzSBUXn+jRc9kF+Gs8/pGhA==", "dev": true, "license": "MIT", "dependencies": { @@ -6265,6 +6736,8 @@ }, "node_modules/text-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-case/-/text-case-1.2.9.tgz", + "integrity": "sha512-zZVdA8rMcjx9zhekdUuOPZShc25UTV7W8/ddKbgbPtfCEvIiToPtWiSd2lXLSuiGMovNhJ4+Tw49xll9o9ts+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -6292,6 +6765,8 @@ }, "node_modules/text-constant-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-constant-case/-/text-constant-case-1.2.9.tgz", + "integrity": "sha512-Vosm6nC7Gag+JFakJHwqS9AXRNgl07j5KZ7srU9cYuKRzYwrxzeJ4RpEogRBNHw7CfmOm0j5FGEznblWtu7pIw==", "dev": true, "license": "MIT", "dependencies": { @@ -6301,6 +6776,8 @@ }, "node_modules/text-dot-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-dot-case/-/text-dot-case-1.2.9.tgz", + "integrity": "sha512-N83hsnvGdSO9q9AfNSB9Cy1LFDNN2MCx53LcxtaPoDWPUTk47fv0JlvIY1tgY0wyzCiThF03kVj3jworvAOScA==", "dev": true, "license": "MIT", "dependencies": { @@ -6309,6 +6786,8 @@ }, "node_modules/text-header-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-header-case/-/text-header-case-1.2.9.tgz", + "integrity": "sha512-TqryEKcYisQAfWLbtT3xPnZlMZ/mySO1uS+LUg+B0eNuqgETrSzVpXIUj5E6Zf/EyJHgpZf4VndbAXtOMJuT4w==", "dev": true, "license": "MIT", "dependencies": { @@ -6317,16 +6796,22 @@ }, "node_modules/text-is-lower-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-is-lower-case/-/text-is-lower-case-1.2.9.tgz", + "integrity": "sha512-cEurrWSnYVYqL8FSwl5cK4mdfqF7qNDCcKJgXI3NnfTesiB8umxAhdlQoErrRYI1xEvYr2WN0MI333EehUhQjg==", "dev": true, "license": "MIT" }, "node_modules/text-is-upper-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-is-upper-case/-/text-is-upper-case-1.2.9.tgz", + "integrity": "sha512-HxsWr3VCsXXiLlhD0c+Ey+mS2lOTCiSJbkepjaXNHl2bp33KiscQaiG0qLwQmmpZQm4SJCg2s9FkndxS0RNDLQ==", "dev": true, "license": "MIT" }, "node_modules/text-kebab-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-kebab-case/-/text-kebab-case-1.2.9.tgz", + "integrity": "sha512-nOUyNR5Ej2B9D/wyyXfwUEv26+pQuOb1pEX+ojE37mCIWo8QeOxw5y6nxuqDmG7NrEPzbO6265UMV+EICH13Cw==", "dev": true, "license": "MIT", "dependencies": { @@ -6335,16 +6820,22 @@ }, "node_modules/text-lower-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-lower-case/-/text-lower-case-1.2.9.tgz", + "integrity": "sha512-53AOnDrhPpiAUQkgY1SHleKUXp/u7GsqRX13NcCREZscmtjLLJ099uxMRjkK7q2KwHkFYVPl9ytkQlTkTQLS0w==", "dev": true, "license": "MIT" }, "node_modules/text-lower-case-first": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-lower-case-first/-/text-lower-case-first-1.2.9.tgz", + "integrity": "sha512-iiphHTV7PVH0MljrEQUA9iBE7jfDpXoi4RQju3WzZU3BRVbS6540cNZgxR19hWa0z6z/7cJTH0Ls9LPBaiUfKg==", "dev": true, "license": "MIT" }, "node_modules/text-no-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-no-case/-/text-no-case-1.2.9.tgz", + "integrity": "sha512-IcCt328KaapimSrytP4ThfC8URmHZb2DgOqCL9BYvGjpxY2lDiqCkIQk9sClZtwcELs2gTnq83a7jNc573FTLA==", "dev": true, "license": "MIT", "dependencies": { @@ -6353,6 +6844,8 @@ }, "node_modules/text-param-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-param-case/-/text-param-case-1.2.9.tgz", + "integrity": "sha512-nR/Ju9amY3aQS1en2CUCgqN/ZiZIVdDyjlJ3xX5J92ChBevGuA4o9K10fh3JGMkbzK97Vcb+bWQJ4Q+Svz+GyQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6361,6 +6854,8 @@ }, "node_modules/text-pascal-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-pascal-case/-/text-pascal-case-1.2.9.tgz", + "integrity": "sha512-o6ZxMGjWDTUW54pcghpXes+C2PqbYRMdU5mHrIhueb6z6nq1NueiIOeCUdrSjN/3wXfhCmnFjK7/d9aRGZNqSg==", "dev": true, "license": "MIT", "dependencies": { @@ -6369,6 +6864,8 @@ }, "node_modules/text-path-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-path-case/-/text-path-case-1.2.9.tgz", + "integrity": "sha512-s8cJ6r5TkJp5ticXMgtxd7f12odEN4d1CfX5u4aoz6jcUtBR2lDqzIhVimkqWFMJ4UKPSrmilUha8Xc2BPi+ow==", "dev": true, "license": "MIT", "dependencies": { @@ -6377,6 +6874,8 @@ }, "node_modules/text-sentence-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-sentence-case/-/text-sentence-case-1.2.9.tgz", + "integrity": "sha512-/G/Yi5kZfUa1edFRV4O3lGZAkbDZTFvlwW8CYfH7szkEGe2k2MYEYbOyAkGRVQEGV6V6JiuUAaP3VS9c1tB6nQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6386,6 +6885,8 @@ }, "node_modules/text-snake-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-snake-case/-/text-snake-case-1.2.9.tgz", + "integrity": "sha512-+ZrqK19ynF/TLQZ7ynqVrL2Dy04uu9syYZwsm8PhzUdsY3XrwPy6QiRqhIEFqhyWbShPcfyfmheer5UEQqFxlw==", "dev": true, "license": "MIT", "dependencies": { @@ -6394,11 +6895,15 @@ }, "node_modules/text-swap-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-swap-case/-/text-swap-case-1.2.9.tgz", + "integrity": "sha512-g5fp12ldktYKK9wdHRMvvtSCQrZYNv/D+ZGLumDsvAY4q9T5bCMO2IWMkIP1F5gVQrysdHH6Xv877P/pjUq1iw==", "dev": true, "license": "MIT" }, "node_modules/text-title-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-title-case/-/text-title-case-1.2.9.tgz", + "integrity": "sha512-RAtC9cdmPp41ns5/HXZBsaQg71BsHT7uZpj2ojTtuFa8o2dNuRYYOrSmy5YdLRIAJQ6WK5hQVpV3jHuq7a+4Tw==", "dev": true, "license": "MIT", "dependencies": { @@ -6408,39 +6913,49 @@ }, "node_modules/text-upper-case": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-upper-case/-/text-upper-case-1.2.9.tgz", + "integrity": "sha512-K/0DNT7a4z8eah2spARtoJllTZyrNTo6Uc0ujhN/96Ir9uJ/slpahfs13y46H9osL3daaLl3O7iXOkW4xtX6bg==", "dev": true, "license": "MIT" }, "node_modules/text-upper-case-first": { "version": "1.2.9", + "resolved": "https://registry.npmjs.org/text-upper-case-first/-/text-upper-case-first-1.2.9.tgz", + "integrity": "sha512-wEDD1B6XqJmEV+xEnBJd+2sBCHZ+7fvA/8Rv/o8+dAsp05YWjYP/kjB8sPH6zqzW0s6jtehIg4IlcKjcYxk2CQ==", "dev": true, "license": "MIT" }, "node_modules/three": { "version": "0.181.2", + "resolved": "https://registry.npmjs.org/three/-/three-0.181.2.tgz", + "integrity": "sha512-k/CjiZ80bYss6Qs7/ex1TBlPD11whT9oKfT8oTGiHa34W4JRd1NiH/Tr1DbHWQ2/vMUypxksLnF2CfmlmM5XFQ==", "license": "MIT" }, - "node_modules/threejs-server": { - "resolved": "examples/threejs-server", - "link": true - }, "node_modules/tinybench": { "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, "node_modules/tinycolor2": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", "dev": true, "license": "MIT" }, "node_modules/tinyexec": { "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", "dev": true, "license": "MIT" }, "node_modules/tinyglobby": { "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6456,6 +6971,8 @@ }, "node_modules/tinyglobby/node_modules/fdir": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { @@ -6472,9 +6989,10 @@ }, "node_modules/tinyglobby/node_modules/picomatch": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -6484,6 +7002,8 @@ }, "node_modules/tinypool": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", "dev": true, "license": "MIT", "engines": { @@ -6492,6 +7012,8 @@ }, "node_modules/tinyrainbow": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", "dev": true, "license": "MIT", "engines": { @@ -6500,6 +7022,8 @@ }, "node_modules/tinyspy": { "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", "dev": true, "license": "MIT", "engines": { @@ -6508,6 +7032,8 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6519,6 +7045,8 @@ }, "node_modules/toidentifier": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", "engines": { "node": ">=0.6" @@ -6526,6 +7054,8 @@ }, "node_modules/touch": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", "dev": true, "license": "ISC", "bin": { @@ -6534,6 +7064,8 @@ }, "node_modules/tree-kill": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true, "license": "MIT", "bin": { @@ -6542,6 +7074,8 @@ }, "node_modules/ts-to-zod": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ts-to-zod/-/ts-to-zod-5.1.0.tgz", + "integrity": "sha512-giqqlvRHunlJqG9tBL/KAO3wWIVZGF//mZiWLKm/fdQnKnz4EN2mtiK5cugN9slytBkdMEXQIaLvMzIScbhhFw==", "dev": true, "license": "MIT", "dependencies": { @@ -6563,6 +7097,8 @@ }, "node_modules/ts-to-zod/node_modules/chokidar": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", "dependencies": { @@ -6577,6 +7113,8 @@ }, "node_modules/ts-to-zod/node_modules/readdirp": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, "license": "MIT", "engines": { @@ -6589,11 +7127,15 @@ }, "node_modules/tslib": { "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "license": "MIT", "dependencies": { @@ -6608,11 +7150,15 @@ }, "node_modules/tsutils/node_modules/tslib": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true, "license": "0BSD" }, "node_modules/tsx": { "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, "license": "MIT", "dependencies": { @@ -6630,9 +7176,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz", - "integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", "cpu": [ "ppc64" ], @@ -6647,9 +7193,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-arm": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz", - "integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", "cpu": [ "arm" ], @@ -6664,9 +7210,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz", - "integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", "cpu": [ "arm64" ], @@ -6681,9 +7227,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz", - "integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", "cpu": [ "x64" ], @@ -6698,9 +7244,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz", - "integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", "cpu": [ "arm64" ], @@ -6715,9 +7261,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/darwin-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz", - "integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", "cpu": [ "x64" ], @@ -6732,9 +7278,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz", - "integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", "cpu": [ "arm64" ], @@ -6749,9 +7295,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz", - "integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", "cpu": [ "x64" ], @@ -6766,9 +7312,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-arm": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz", - "integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", "cpu": [ "arm" ], @@ -6783,9 +7329,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz", - "integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", "cpu": [ "arm64" ], @@ -6800,9 +7346,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-ia32": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz", - "integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", "cpu": [ "ia32" ], @@ -6817,9 +7363,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-loong64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz", - "integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", "cpu": [ "loong64" ], @@ -6834,9 +7380,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz", - "integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", "cpu": [ "mips64el" ], @@ -6851,9 +7397,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz", - "integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", "cpu": [ "ppc64" ], @@ -6868,9 +7414,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz", - "integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", "cpu": [ "riscv64" ], @@ -6885,9 +7431,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-s390x": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz", - "integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", "cpu": [ "s390x" ], @@ -6902,7 +7448,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-x64": { - "version": "0.27.1", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", "cpu": [ "x64" ], @@ -6917,9 +7465,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz", - "integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", "cpu": [ "arm64" ], @@ -6934,9 +7482,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz", - "integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", "cpu": [ "x64" ], @@ -6951,9 +7499,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz", - "integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", "cpu": [ "arm64" ], @@ -6968,9 +7516,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz", - "integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", "cpu": [ "x64" ], @@ -6985,9 +7533,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz", - "integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", "cpu": [ "arm64" ], @@ -7002,9 +7550,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/sunos-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz", - "integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", "cpu": [ "x64" ], @@ -7019,9 +7567,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-arm64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz", - "integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", "cpu": [ "arm64" ], @@ -7036,9 +7584,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-ia32": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz", - "integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", "cpu": [ "ia32" ], @@ -7053,9 +7601,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-x64": { - "version": "0.27.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz", - "integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", "cpu": [ "x64" ], @@ -7070,7 +7618,9 @@ } }, "node_modules/tsx/node_modules/esbuild": { - "version": "0.27.1", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -7081,36 +7631,38 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.1", - "@esbuild/android-arm": "0.27.1", - "@esbuild/android-arm64": "0.27.1", - "@esbuild/android-x64": "0.27.1", - "@esbuild/darwin-arm64": "0.27.1", - "@esbuild/darwin-x64": "0.27.1", - "@esbuild/freebsd-arm64": "0.27.1", - "@esbuild/freebsd-x64": "0.27.1", - "@esbuild/linux-arm": "0.27.1", - "@esbuild/linux-arm64": "0.27.1", - "@esbuild/linux-ia32": "0.27.1", - "@esbuild/linux-loong64": "0.27.1", - "@esbuild/linux-mips64el": "0.27.1", - "@esbuild/linux-ppc64": "0.27.1", - "@esbuild/linux-riscv64": "0.27.1", - "@esbuild/linux-s390x": "0.27.1", - "@esbuild/linux-x64": "0.27.1", - "@esbuild/netbsd-arm64": "0.27.1", - "@esbuild/netbsd-x64": "0.27.1", - "@esbuild/openbsd-arm64": "0.27.1", - "@esbuild/openbsd-x64": "0.27.1", - "@esbuild/openharmony-arm64": "0.27.1", - "@esbuild/sunos-x64": "0.27.1", - "@esbuild/win32-arm64": "0.27.1", - "@esbuild/win32-ia32": "0.27.1", - "@esbuild/win32-x64": "0.27.1" + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" } }, "node_modules/type-fest": { "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -7122,6 +7674,8 @@ }, "node_modules/type-is": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "license": "MIT", "dependencies": { "content-type": "^1.0.5", @@ -7134,6 +7688,8 @@ }, "node_modules/typedoc": { "version": "0.28.15", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.15.tgz", + "integrity": "sha512-mw2/2vTL7MlT+BVo43lOsufkkd2CJO4zeOSuWQQsiXoV2VuEn7f6IZp2jsUDPmBMABpgR0R5jlcJ2OGEFYmkyg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -7156,6 +7712,8 @@ }, "node_modules/typedoc/node_modules/brace-expansion": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7164,6 +7722,8 @@ }, "node_modules/typedoc/node_modules/minimatch": { "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -7178,9 +7738,10 @@ }, "node_modules/typescript": { "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7191,16 +7752,22 @@ }, "node_modules/uc.micro": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true, "license": "MIT" }, "node_modules/undefsafe": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true, "license": "MIT" }, "node_modules/undici": { - "version": "7.16.0", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.18.2.tgz", + "integrity": "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==", "license": "MIT", "engines": { "node": ">=20.18.1" @@ -7208,18 +7775,24 @@ }, "node_modules/undici-types": { "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/update-browserslist-db": { - "version": "1.2.2", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -7249,20 +7822,19 @@ }, "node_modules/vary": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/video-resource-server": { - "resolved": "examples/video-resource-server", - "link": true - }, "node_modules/vite": { "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -7334,6 +7906,8 @@ }, "node_modules/vite-node": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dev": true, "license": "MIT", "dependencies": { @@ -7355,6 +7929,8 @@ }, "node_modules/vite-plugin-singlefile": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vite-plugin-singlefile/-/vite-plugin-singlefile-2.3.0.tgz", + "integrity": "sha512-DAcHzYypM0CasNLSz/WG0VdKOCxGHErfrjOoyIPiNxTPTGmO6rRD/te93n1YL/s+miXq66ipF1brMBikf99c6A==", "dev": true, "license": "MIT", "dependencies": { @@ -7413,6 +7989,8 @@ }, "node_modules/vite/node_modules/fdir": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { @@ -7429,9 +8007,10 @@ }, "node_modules/vite/node_modules/picomatch": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -7461,6 +8040,8 @@ }, "node_modules/vitest": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", "dependencies": { @@ -7532,6 +8113,8 @@ }, "node_modules/vitest/node_modules/picomatch": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -7546,7 +8129,6 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz", "integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==", "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.26", "@vue/compiler-sfc": "3.5.26", @@ -7565,6 +8147,8 @@ }, "node_modules/whatwg-encoding": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" @@ -7575,6 +8159,8 @@ }, "node_modules/whatwg-encoding/node_modules/iconv-lite": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -7585,6 +8171,8 @@ }, "node_modules/whatwg-mimetype": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "license": "MIT", "engines": { "node": ">=18" @@ -7592,6 +8180,8 @@ }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -7605,6 +8195,8 @@ }, "node_modules/why-is-node-running": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { @@ -7620,6 +8212,8 @@ }, "node_modules/widest-line": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dev": true, "license": "MIT", "dependencies": { @@ -7629,17 +8223,17 @@ "node": ">=8" } }, - "node_modules/wiki-explorer-server": { - "resolved": "examples/wiki-explorer-server", - "link": true - }, "node_modules/wordwrap": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true, "license": "MIT" }, "node_modules/wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { @@ -7656,6 +8250,8 @@ }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -7664,6 +8260,8 @@ }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -7675,10 +8273,14 @@ }, "node_modules/wrappy": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, "node_modules/y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, "license": "ISC", "engines": { @@ -7687,14 +8289,17 @@ }, "node_modules/yallist": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" }, "node_modules/yaml": { "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "dev": true, "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -7707,6 +8312,8 @@ }, "node_modules/yargs": { "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", "dependencies": { @@ -7724,6 +8331,8 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "license": "ISC", "engines": { @@ -7737,15 +8346,18 @@ "license": "MIT" }, "node_modules/zod": { - "version": "4.2.1", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", + "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } }, "node_modules/zod-to-json-schema": { - "version": "3.25.0", + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", "license": "ISC", "peerDependencies": { "zod": "^3.25 || ^4" diff --git a/package.json b/package.json index 83b0b58..7ac95a7 100644 --- a/package.json +++ b/package.json @@ -111,6 +111,7 @@ "@rollup/rollup-darwin-x64": "^4.53.3", "@rollup/rollup-linux-arm64-gnu": "^4.53.3", "@rollup/rollup-linux-x64-gnu": "^4.53.3", + "@rollup/rollup-win32-arm64-msvc": "^4.53.3", "@rollup/rollup-win32-x64-msvc": "^4.53.3" } } diff --git a/src/generated/schema.json b/src/generated/schema.json index 2eedead..7a1fd2c 100644 --- a/src/generated/schema.json +++ b/src/generated/schema.json @@ -30,7 +30,6 @@ }, "McpUiDisplayMode": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "Display mode for UI presentation.", "anyOf": [ { "type": "string", @@ -44,7 +43,8 @@ "type": "string", "const": "pip" } - ] + ], + "description": "Display mode for UI presentation." }, "McpUiHostCapabilities": { "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -102,7 +102,6 @@ "const": "ui/notifications/host-context-changed" }, "params": { - "description": "Partial context update containing only changed fields.", "type": "object", "properties": { "toolInfo": { @@ -123,7 +122,6 @@ ] }, "tool": { - "description": "Tool definition including name, inputSchema, etc.", "type": "object", "properties": { "name": { @@ -148,6 +146,10 @@ "items": { "type": "string" } + }, + "theme": { + "type": "string", + "enum": ["light", "dark"] } }, "required": ["src"], @@ -245,7 +247,8 @@ } }, "required": ["name", "inputSchema"], - "additionalProperties": false + "additionalProperties": false, + "description": "Tool definition including name, inputSchema, etc." } }, "required": ["tool"], @@ -272,7 +275,6 @@ "description": "CSS variables for theming the app.", "type": "object", "propertyNames": { - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "anyOf": [ { "type": "string", @@ -582,17 +584,96 @@ "type": "string", "const": "--shadow-lg" } - ] + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." }, "additionalProperties": { - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "anyOf": [ { "type": "string" }, {} - ] - } + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." + }, + "required": [ + "--color-background-primary", + "--color-background-secondary", + "--color-background-tertiary", + "--color-background-inverse", + "--color-background-ghost", + "--color-background-info", + "--color-background-danger", + "--color-background-success", + "--color-background-warning", + "--color-background-disabled", + "--color-text-primary", + "--color-text-secondary", + "--color-text-tertiary", + "--color-text-inverse", + "--color-text-ghost", + "--color-text-info", + "--color-text-danger", + "--color-text-success", + "--color-text-warning", + "--color-text-disabled", + "--color-border-primary", + "--color-border-secondary", + "--color-border-tertiary", + "--color-border-inverse", + "--color-border-ghost", + "--color-border-info", + "--color-border-danger", + "--color-border-success", + "--color-border-warning", + "--color-border-disabled", + "--color-ring-primary", + "--color-ring-secondary", + "--color-ring-inverse", + "--color-ring-info", + "--color-ring-danger", + "--color-ring-success", + "--color-ring-warning", + "--font-sans", + "--font-mono", + "--font-weight-normal", + "--font-weight-medium", + "--font-weight-semibold", + "--font-weight-bold", + "--font-text-xs-size", + "--font-text-sm-size", + "--font-text-md-size", + "--font-text-lg-size", + "--font-heading-xs-size", + "--font-heading-sm-size", + "--font-heading-md-size", + "--font-heading-lg-size", + "--font-heading-xl-size", + "--font-heading-2xl-size", + "--font-heading-3xl-size", + "--font-text-xs-line-height", + "--font-text-sm-line-height", + "--font-text-md-line-height", + "--font-text-lg-line-height", + "--font-heading-xs-line-height", + "--font-heading-sm-line-height", + "--font-heading-md-line-height", + "--font-heading-lg-line-height", + "--font-heading-xl-line-height", + "--font-heading-2xl-line-height", + "--font-heading-3xl-line-height", + "--border-radius-xs", + "--border-radius-sm", + "--border-radius-md", + "--border-radius-lg", + "--border-radius-xl", + "--border-radius-full", + "--border-width-regular", + "--shadow-hairline", + "--shadow-sm", + "--shadow-md", + "--shadow-lg" + ] }, "css": { "description": "CSS blocks that apps can inject.", @@ -641,8 +722,8 @@ "type": "object", "properties": { "height": { - "description": "Fixed container height in pixels.", - "type": "number" + "type": "number", + "description": "Fixed container height in pixels." } }, "required": ["height"], @@ -671,8 +752,8 @@ "type": "object", "properties": { "width": { - "description": "Fixed container width in pixels.", - "type": "number" + "type": "number", + "description": "Fixed container width in pixels." } }, "required": ["width"], @@ -746,27 +827,28 @@ "type": "object", "properties": { "top": { - "description": "Top safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Top safe area inset in pixels." }, "right": { - "description": "Right safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Right safe area inset in pixels." }, "bottom": { - "description": "Bottom safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Bottom safe area inset in pixels." }, "left": { - "description": "Left safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Left safe area inset in pixels." } }, "required": ["top", "right", "bottom", "left"], "additionalProperties": false } }, - "additionalProperties": {} + "additionalProperties": {}, + "description": "Partial context update containing only changed fields." } }, "required": ["method", "params"], @@ -794,7 +876,6 @@ ] }, "tool": { - "description": "Tool definition including name, inputSchema, etc.", "type": "object", "properties": { "name": { @@ -819,6 +900,10 @@ "items": { "type": "string" } + }, + "theme": { + "type": "string", + "enum": ["light", "dark"] } }, "required": ["src"], @@ -916,7 +1001,8 @@ } }, "required": ["name", "inputSchema"], - "additionalProperties": false + "additionalProperties": false, + "description": "Tool definition including name, inputSchema, etc." } }, "required": ["tool"], @@ -943,7 +1029,6 @@ "description": "CSS variables for theming the app.", "type": "object", "propertyNames": { - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "anyOf": [ { "type": "string", @@ -1253,17 +1338,96 @@ "type": "string", "const": "--shadow-lg" } - ] + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." }, "additionalProperties": { - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "anyOf": [ { "type": "string" }, {} - ] - } + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." + }, + "required": [ + "--color-background-primary", + "--color-background-secondary", + "--color-background-tertiary", + "--color-background-inverse", + "--color-background-ghost", + "--color-background-info", + "--color-background-danger", + "--color-background-success", + "--color-background-warning", + "--color-background-disabled", + "--color-text-primary", + "--color-text-secondary", + "--color-text-tertiary", + "--color-text-inverse", + "--color-text-ghost", + "--color-text-info", + "--color-text-danger", + "--color-text-success", + "--color-text-warning", + "--color-text-disabled", + "--color-border-primary", + "--color-border-secondary", + "--color-border-tertiary", + "--color-border-inverse", + "--color-border-ghost", + "--color-border-info", + "--color-border-danger", + "--color-border-success", + "--color-border-warning", + "--color-border-disabled", + "--color-ring-primary", + "--color-ring-secondary", + "--color-ring-inverse", + "--color-ring-info", + "--color-ring-danger", + "--color-ring-success", + "--color-ring-warning", + "--font-sans", + "--font-mono", + "--font-weight-normal", + "--font-weight-medium", + "--font-weight-semibold", + "--font-weight-bold", + "--font-text-xs-size", + "--font-text-sm-size", + "--font-text-md-size", + "--font-text-lg-size", + "--font-heading-xs-size", + "--font-heading-sm-size", + "--font-heading-md-size", + "--font-heading-lg-size", + "--font-heading-xl-size", + "--font-heading-2xl-size", + "--font-heading-3xl-size", + "--font-text-xs-line-height", + "--font-text-sm-line-height", + "--font-text-md-line-height", + "--font-text-lg-line-height", + "--font-heading-xs-line-height", + "--font-heading-sm-line-height", + "--font-heading-md-line-height", + "--font-heading-lg-line-height", + "--font-heading-xl-line-height", + "--font-heading-2xl-line-height", + "--font-heading-3xl-line-height", + "--border-radius-xs", + "--border-radius-sm", + "--border-radius-md", + "--border-radius-lg", + "--border-radius-xl", + "--border-radius-full", + "--border-width-regular", + "--shadow-hairline", + "--shadow-sm", + "--shadow-md", + "--shadow-lg" + ] }, "css": { "description": "CSS blocks that apps can inject.", @@ -1312,8 +1476,8 @@ "type": "object", "properties": { "height": { - "description": "Fixed container height in pixels.", - "type": "number" + "type": "number", + "description": "Fixed container height in pixels." } }, "required": ["height"], @@ -1342,8 +1506,8 @@ "type": "object", "properties": { "width": { - "description": "Fixed container width in pixels.", - "type": "number" + "type": "number", + "description": "Fixed container width in pixels." } }, "required": ["width"], @@ -1417,20 +1581,20 @@ "type": "object", "properties": { "top": { - "description": "Top safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Top safe area inset in pixels." }, "right": { - "description": "Right safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Right safe area inset in pixels." }, "bottom": { - "description": "Bottom safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Bottom safe area inset in pixels." }, "left": { - "description": "Left safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Left safe area inset in pixels." } }, "required": ["top", "right", "bottom", "left"], @@ -1458,7 +1622,6 @@ "description": "CSS variables for theming the app.", "type": "object", "propertyNames": { - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "anyOf": [ { "type": "string", @@ -1768,17 +1931,96 @@ "type": "string", "const": "--shadow-lg" } - ] + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." }, "additionalProperties": { - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "anyOf": [ { "type": "string" }, {} - ] - } + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." + }, + "required": [ + "--color-background-primary", + "--color-background-secondary", + "--color-background-tertiary", + "--color-background-inverse", + "--color-background-ghost", + "--color-background-info", + "--color-background-danger", + "--color-background-success", + "--color-background-warning", + "--color-background-disabled", + "--color-text-primary", + "--color-text-secondary", + "--color-text-tertiary", + "--color-text-inverse", + "--color-text-ghost", + "--color-text-info", + "--color-text-danger", + "--color-text-success", + "--color-text-warning", + "--color-text-disabled", + "--color-border-primary", + "--color-border-secondary", + "--color-border-tertiary", + "--color-border-inverse", + "--color-border-ghost", + "--color-border-info", + "--color-border-danger", + "--color-border-success", + "--color-border-warning", + "--color-border-disabled", + "--color-ring-primary", + "--color-ring-secondary", + "--color-ring-inverse", + "--color-ring-info", + "--color-ring-danger", + "--color-ring-success", + "--color-ring-warning", + "--font-sans", + "--font-mono", + "--font-weight-normal", + "--font-weight-medium", + "--font-weight-semibold", + "--font-weight-bold", + "--font-text-xs-size", + "--font-text-sm-size", + "--font-text-md-size", + "--font-text-lg-size", + "--font-heading-xs-size", + "--font-heading-sm-size", + "--font-heading-md-size", + "--font-heading-lg-size", + "--font-heading-xl-size", + "--font-heading-2xl-size", + "--font-heading-3xl-size", + "--font-text-xs-line-height", + "--font-text-sm-line-height", + "--font-text-md-line-height", + "--font-text-lg-line-height", + "--font-heading-xs-line-height", + "--font-heading-sm-line-height", + "--font-heading-md-line-height", + "--font-heading-lg-line-height", + "--font-heading-xl-line-height", + "--font-heading-2xl-line-height", + "--font-heading-3xl-line-height", + "--border-radius-xs", + "--border-radius-sm", + "--border-radius-md", + "--border-radius-lg", + "--border-radius-xl", + "--border-radius-full", + "--border-width-regular", + "--shadow-hairline", + "--shadow-sm", + "--shadow-md", + "--shadow-lg" + ] }, "css": { "description": "CSS blocks that apps can inject.", @@ -1806,7 +2048,6 @@ "type": "object", "properties": { "appInfo": { - "description": "App identification (name and version).", "type": "object", "properties": { "name": { @@ -1831,6 +2072,10 @@ "items": { "type": "string" } + }, + "theme": { + "type": "string", + "enum": ["light", "dark"] } }, "required": ["src"], @@ -1842,13 +2087,16 @@ }, "websiteUrl": { "type": "string" + }, + "description": { + "type": "string" } }, "required": ["name", "version"], - "additionalProperties": false + "additionalProperties": false, + "description": "App identification (name and version)." }, "appCapabilities": { - "description": "Features and capabilities this app provides.", "type": "object", "properties": { "experimental": { @@ -1869,11 +2117,12 @@ "additionalProperties": false } }, - "additionalProperties": false + "additionalProperties": false, + "description": "Features and capabilities this app provides." }, "protocolVersion": { - "description": "Protocol version this app supports.", - "type": "string" + "type": "string", + "description": "Protocol version this app supports." } }, "required": ["appInfo", "appCapabilities", "protocolVersion"], @@ -1888,11 +2137,10 @@ "type": "object", "properties": { "protocolVersion": { - "description": "Negotiated protocol version string (e.g., \"2025-11-21\").", - "type": "string" + "type": "string", + "description": "Negotiated protocol version string (e.g., \"2025-11-21\")." }, "hostInfo": { - "description": "Host application identification and version.", "type": "object", "properties": { "name": { @@ -1917,6 +2165,10 @@ "items": { "type": "string" } + }, + "theme": { + "type": "string", + "enum": ["light", "dark"] } }, "required": ["src"], @@ -1928,13 +2180,16 @@ }, "websiteUrl": { "type": "string" + }, + "description": { + "type": "string" } }, "required": ["name", "version"], - "additionalProperties": false + "additionalProperties": false, + "description": "Host application identification and version." }, "hostCapabilities": { - "description": "Features and capabilities provided by the host.", "type": "object", "properties": { "experimental": { @@ -1978,10 +2233,10 @@ "additionalProperties": false } }, - "additionalProperties": false + "additionalProperties": false, + "description": "Features and capabilities provided by the host." }, "hostContext": { - "description": "Rich context about the host environment.", "type": "object", "properties": { "toolInfo": { @@ -2002,7 +2257,6 @@ ] }, "tool": { - "description": "Tool definition including name, inputSchema, etc.", "type": "object", "properties": { "name": { @@ -2027,6 +2281,10 @@ "items": { "type": "string" } + }, + "theme": { + "type": "string", + "enum": ["light", "dark"] } }, "required": ["src"], @@ -2124,7 +2382,8 @@ } }, "required": ["name", "inputSchema"], - "additionalProperties": false + "additionalProperties": false, + "description": "Tool definition including name, inputSchema, etc." } }, "required": ["tool"], @@ -2151,7 +2410,6 @@ "description": "CSS variables for theming the app.", "type": "object", "propertyNames": { - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "anyOf": [ { "type": "string", @@ -2461,17 +2719,96 @@ "type": "string", "const": "--shadow-lg" } - ] + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." }, "additionalProperties": { - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "anyOf": [ { "type": "string" }, {} - ] - } + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." + }, + "required": [ + "--color-background-primary", + "--color-background-secondary", + "--color-background-tertiary", + "--color-background-inverse", + "--color-background-ghost", + "--color-background-info", + "--color-background-danger", + "--color-background-success", + "--color-background-warning", + "--color-background-disabled", + "--color-text-primary", + "--color-text-secondary", + "--color-text-tertiary", + "--color-text-inverse", + "--color-text-ghost", + "--color-text-info", + "--color-text-danger", + "--color-text-success", + "--color-text-warning", + "--color-text-disabled", + "--color-border-primary", + "--color-border-secondary", + "--color-border-tertiary", + "--color-border-inverse", + "--color-border-ghost", + "--color-border-info", + "--color-border-danger", + "--color-border-success", + "--color-border-warning", + "--color-border-disabled", + "--color-ring-primary", + "--color-ring-secondary", + "--color-ring-inverse", + "--color-ring-info", + "--color-ring-danger", + "--color-ring-success", + "--color-ring-warning", + "--font-sans", + "--font-mono", + "--font-weight-normal", + "--font-weight-medium", + "--font-weight-semibold", + "--font-weight-bold", + "--font-text-xs-size", + "--font-text-sm-size", + "--font-text-md-size", + "--font-text-lg-size", + "--font-heading-xs-size", + "--font-heading-sm-size", + "--font-heading-md-size", + "--font-heading-lg-size", + "--font-heading-xl-size", + "--font-heading-2xl-size", + "--font-heading-3xl-size", + "--font-text-xs-line-height", + "--font-text-sm-line-height", + "--font-text-md-line-height", + "--font-text-lg-line-height", + "--font-heading-xs-line-height", + "--font-heading-sm-line-height", + "--font-heading-md-line-height", + "--font-heading-lg-line-height", + "--font-heading-xl-line-height", + "--font-heading-2xl-line-height", + "--font-heading-3xl-line-height", + "--border-radius-xs", + "--border-radius-sm", + "--border-radius-md", + "--border-radius-lg", + "--border-radius-xl", + "--border-radius-full", + "--border-width-regular", + "--shadow-hairline", + "--shadow-sm", + "--shadow-md", + "--shadow-lg" + ] }, "css": { "description": "CSS blocks that apps can inject.", @@ -2520,8 +2857,8 @@ "type": "object", "properties": { "height": { - "description": "Fixed container height in pixels.", - "type": "number" + "type": "number", + "description": "Fixed container height in pixels." } }, "required": ["height"], @@ -2550,8 +2887,8 @@ "type": "object", "properties": { "width": { - "description": "Fixed container width in pixels.", - "type": "number" + "type": "number", + "description": "Fixed container width in pixels." } }, "required": ["width"], @@ -2625,27 +2962,28 @@ "type": "object", "properties": { "top": { - "description": "Top safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Top safe area inset in pixels." }, "right": { - "description": "Right safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Right safe area inset in pixels." }, "bottom": { - "description": "Bottom safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Bottom safe area inset in pixels." }, "left": { - "description": "Left safe area inset in pixels.", - "type": "number" + "type": "number", + "description": "Left safe area inset in pixels." } }, "required": ["top", "right", "bottom", "left"], "additionalProperties": false } }, - "additionalProperties": {} + "additionalProperties": {}, + "description": "Rich context about the host environment." } }, "required": [ @@ -2685,12 +3023,11 @@ "type": "object", "properties": { "role": { - "description": "Message role, currently only \"user\" is supported.", "type": "string", - "const": "user" + "const": "user", + "description": "Message role, currently only \"user\" is supported." }, "content": { - "description": "Message content blocks (text, image, etc.).", "type": "array", "items": { "anyOf": [ @@ -2857,6 +3194,10 @@ "items": { "type": "string" } + }, + "theme": { + "type": "string", + "enum": ["light", "dark"] } }, "required": ["src"], @@ -3000,7 +3341,8 @@ "additionalProperties": false } ] - } + }, + "description": "Message content blocks (text, image, etc.)." } }, "required": ["role", "content"], @@ -3033,8 +3375,8 @@ "type": "object", "properties": { "url": { - "description": "URL to open in the host's browser", - "type": "string" + "type": "string", + "description": "URL to open in the host's browser" } }, "required": ["url"], @@ -3067,7 +3409,6 @@ "type": "object", "properties": { "mode": { - "description": "The display mode being requested.", "anyOf": [ { "type": "string", @@ -3081,7 +3422,8 @@ "type": "string", "const": "pip" } - ] + ], + "description": "The display mode being requested." } }, "required": ["mode"], @@ -3096,7 +3438,6 @@ "type": "object", "properties": { "mode": { - "description": "The display mode that was actually set. May differ from requested if not supported.", "anyOf": [ { "type": "string", @@ -3110,7 +3451,8 @@ "type": "string", "const": "pip" } - ] + ], + "description": "The display mode that was actually set. May differ from requested if not supported." } }, "required": ["mode"], @@ -3227,8 +3569,8 @@ "type": "object", "properties": { "html": { - "description": "HTML content to load into the inner iframe.", - "type": "string" + "type": "string", + "description": "HTML content to load into the inner iframe." }, "sandbox": { "description": "Optional override for the inner iframe's sandbox attribute.", @@ -3291,7 +3633,6 @@ }, "McpUiStyleVariableKey": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "CSS variable keys available to MCP apps for theming.", "anyOf": [ { "type": "string", @@ -3601,14 +3942,13 @@ "type": "string", "const": "--shadow-lg" } - ] + ], + "description": "CSS variable keys available to MCP apps for theming." }, "McpUiStyles": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "type": "object", "propertyNames": { - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "anyOf": [ { "type": "string", @@ -3918,21 +4258,100 @@ "type": "string", "const": "--shadow-lg" } - ] + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." }, "additionalProperties": { - "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation.", "anyOf": [ { "type": "string" }, {} - ] - } + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." + }, + "required": [ + "--color-background-primary", + "--color-background-secondary", + "--color-background-tertiary", + "--color-background-inverse", + "--color-background-ghost", + "--color-background-info", + "--color-background-danger", + "--color-background-success", + "--color-background-warning", + "--color-background-disabled", + "--color-text-primary", + "--color-text-secondary", + "--color-text-tertiary", + "--color-text-inverse", + "--color-text-ghost", + "--color-text-info", + "--color-text-danger", + "--color-text-success", + "--color-text-warning", + "--color-text-disabled", + "--color-border-primary", + "--color-border-secondary", + "--color-border-tertiary", + "--color-border-inverse", + "--color-border-ghost", + "--color-border-info", + "--color-border-danger", + "--color-border-success", + "--color-border-warning", + "--color-border-disabled", + "--color-ring-primary", + "--color-ring-secondary", + "--color-ring-inverse", + "--color-ring-info", + "--color-ring-danger", + "--color-ring-success", + "--color-ring-warning", + "--font-sans", + "--font-mono", + "--font-weight-normal", + "--font-weight-medium", + "--font-weight-semibold", + "--font-weight-bold", + "--font-text-xs-size", + "--font-text-sm-size", + "--font-text-md-size", + "--font-text-lg-size", + "--font-heading-xs-size", + "--font-heading-sm-size", + "--font-heading-md-size", + "--font-heading-lg-size", + "--font-heading-xl-size", + "--font-heading-2xl-size", + "--font-heading-3xl-size", + "--font-text-xs-line-height", + "--font-text-sm-line-height", + "--font-text-md-line-height", + "--font-text-lg-line-height", + "--font-heading-xs-line-height", + "--font-heading-sm-line-height", + "--font-heading-md-line-height", + "--font-heading-lg-line-height", + "--font-heading-xl-line-height", + "--font-heading-2xl-line-height", + "--font-heading-3xl-line-height", + "--border-radius-xs", + "--border-radius-sm", + "--border-radius-md", + "--border-radius-lg", + "--border-radius-xl", + "--border-radius-full", + "--border-width-regular", + "--shadow-hairline", + "--shadow-sm", + "--shadow-md", + "--shadow-lg" + ], + "description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record` rather than `Partial>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation." }, "McpUiTheme": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "Color theme preference for the host environment.", "anyOf": [ { "type": "string", @@ -3942,7 +4361,8 @@ "type": "string", "const": "dark" } - ] + ], + "description": "Color theme preference for the host environment." }, "McpUiToolCancelledNotification": { "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -4033,7 +4453,6 @@ "description": "Who can access this tool. Default: [\"model\", \"app\"]\n- \"model\": Tool visible to and callable by the agent\n- \"app\": Tool callable by the app from this server only", "type": "array", "items": { - "description": "Tool visibility scope - who can access the tool.", "anyOf": [ { "type": "string", @@ -4043,7 +4462,8 @@ "type": "string", "const": "app" } - ] + ], + "description": "Tool visibility scope - who can access the tool." } } }, @@ -4058,12 +4478,23 @@ "const": "ui/notifications/tool-result" }, "params": { - "description": "Standard MCP tool execution result.", "type": "object", "properties": { "_meta": { "type": "object", "properties": { + "progressToken": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + } + ] + }, "io.modelcontextprotocol/related-task": { "type": "object", "properties": { @@ -4072,7 +4503,7 @@ } }, "required": ["taskId"], - "additionalProperties": {} + "additionalProperties": false } }, "additionalProperties": {} @@ -4245,6 +4676,10 @@ "items": { "type": "string" } + }, + "theme": { + "type": "string", + "enum": ["light", "dark"] } }, "required": ["src"], @@ -4402,7 +4837,8 @@ } }, "required": ["content"], - "additionalProperties": {} + "additionalProperties": {}, + "description": "Standard MCP tool execution result." } }, "required": ["method", "params"], @@ -4410,7 +4846,6 @@ }, "McpUiToolVisibility": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "Tool visibility scope - who can access the tool.", "anyOf": [ { "type": "string", @@ -4420,7 +4855,8 @@ "type": "string", "const": "app" } - ] + ], + "description": "Tool visibility scope - who can access the tool." } } } diff --git a/tests/e2e/servers.spec.ts-snapshots/basic-react.png b/tests/e2e/servers.spec.ts-snapshots/basic-react.png index 40f57873a007029397be94bef0396470d39095d8..62f0410b77f500088664059d031358f5081e95b6 100644 GIT binary patch literal 46545 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 Rre4e`a#G5YCC^RX{x8i3g~k8? diff --git a/tests/e2e/servers.spec.ts-snapshots/basic-vanillajs.png b/tests/e2e/servers.spec.ts-snapshots/basic-vanillajs.png index bd0e88a4c2b34fc179f88cdda72274fff9fbd813..bd0d93c5b0aa6a8fccc5d64a4d8b49fffbfbab85 100644 GIT binary patch literal 47385 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 z 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

ahVW71B@6c(W-C&U8ZoxLPMsB@$x$G5m-?egA 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