From a6d984143265110cc0f4fba3d546e0b7a0d11758 Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Date: Wed, 6 May 2026 09:37:58 -0300 Subject: [PATCH] Add basic MCP support --- apps/cli/package.json | 4 +- apps/cli/src/README.md | 17 + apps/cli/src/commands/Mcp.ts | 126 ++++++ apps/cli/src/index.ts | 10 + apps/cli/src/mcp/README.md | 125 ++++++ apps/cli/src/mcp/auth.ts | 35 ++ apps/cli/src/mcp/dispatch.ts | 83 ++++ apps/cli/src/mcp/errors.ts | 29 ++ apps/cli/src/mcp/tools/checkTools.ts | 28 ++ apps/cli/src/mcp/tools/detectAppleAppType.ts | 25 ++ apps/cli/src/mcp/tools/index.ts | 13 + apps/cli/src/mcp/tools/listDevices.ts | 28 ++ apps/cli/src/mcp/tools/register.ts | 48 +++ apps/cli/src/mcp/tools/trustedSources.ts | 18 + apps/cli/src/storage.ts | 10 + yarn.lock | 398 ++++++++++++++++++- 16 files changed, 979 insertions(+), 18 deletions(-) create mode 100644 apps/cli/src/commands/Mcp.ts create mode 100644 apps/cli/src/mcp/README.md create mode 100644 apps/cli/src/mcp/auth.ts create mode 100644 apps/cli/src/mcp/dispatch.ts create mode 100644 apps/cli/src/mcp/errors.ts create mode 100644 apps/cli/src/mcp/tools/checkTools.ts create mode 100644 apps/cli/src/mcp/tools/detectAppleAppType.ts create mode 100644 apps/cli/src/mcp/tools/index.ts create mode 100644 apps/cli/src/mcp/tools/listDevices.ts create mode 100644 apps/cli/src/mcp/tools/register.ts create mode 100644 apps/cli/src/mcp/tools/trustedSources.ts diff --git a/apps/cli/package.json b/apps/cli/package.json index caa3aa5b..6f6b9388 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -21,6 +21,7 @@ "test": "jest" }, "dependencies": { + "@modelcontextprotocol/sdk": "^1.21.0", "@types/picomatch": "^4.0.0", "commander": "^10.0.1", "common-types": "1.0.0", @@ -29,7 +30,8 @@ "graphql-request": "^6.1.0", "picomatch": "^4.0.2", "snack-content": "2.0.0-preview.2", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.0", + "zod": "^3.25.0" }, "devDependencies": { "@graphql-codegen/cli": "^5.0.0", diff --git a/apps/cli/src/README.md b/apps/cli/src/README.md index e529b440..cfaa2fec 100644 --- a/apps/cli/src/README.md +++ b/apps/cli/src/README.md @@ -177,3 +177,20 @@ expo-orbit-cli detect-apple-app-type Inspects an iOS app bundle and reports whether it’s a simulator build, App Store build, etc. --- + +### mcp + +```bash +expo-orbit-cli mcp [--port ] [--token ] +``` + +- **Options** + `--port ` + : Port to listen on. _Default_: `8765`. + `--token ` + : Override the bearer token. _Default_: persisted in `~/.config/expo/user-settings.json`. + +- **Description** + Starts the Model Context Protocol server so AI coding agents (Cursor, Claude Code, Claude Desktop) can drive simulators, emulators, and devices through Orbit. See [mcp/README.md](./mcp/README.md) for the full setup, client config snippets, and tool reference. + +--- diff --git a/apps/cli/src/commands/Mcp.ts b/apps/cli/src/commands/Mcp.ts new file mode 100644 index 00000000..019c9fa6 --- /dev/null +++ b/apps/cli/src/commands/Mcp.ts @@ -0,0 +1,126 @@ +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; +import http, { IncomingMessage, ServerResponse } from 'http'; + +import { ensureMcpTokenAsync, isAuthorized, isLocalhost } from '../mcp/auth'; +import { registerPhase1Tools } from '../mcp/tools'; + +const SERVER_INFO = { name: 'expo-orbit', version: '0.1.0' }; +const MAX_BODY_BYTES = 4 * 1024 * 1024; + +type McpOptions = { + port?: string; + token?: string; +}; + +export async function mcpServerAsync(options: McpOptions = {}): Promise { + const port = parsePort(options.port); + const token = await ensureMcpTokenAsync(options.token); + + const httpServer = http.createServer((req, res) => { + handleRequest(req, res, token).catch((err) => { + logErr('unhandled request error', err); + writeError(res, 500, 'Internal Server Error'); + }); + }); + + httpServer.on('error', (err) => { + logErr('HTTP server error', err); + }); + + await new Promise((resolve) => { + httpServer.listen(port, '127.0.0.1', () => resolve()); + }); + + const address = httpServer.address(); + const boundPort = typeof address === 'object' && address ? address.port : port; + log(`Expo Orbit MCP listening on http://127.0.0.1:${boundPort}/mcp`); + log(`Token: ${token}`); + + const shutdown = () => { + httpServer.close(() => process.exit(0)); + }; + process.once('SIGINT', shutdown); + process.once('SIGTERM', shutdown); +} + +async function handleRequest(req: IncomingMessage, res: ServerResponse, token: string) { + if (!isLocalhost(req.socket.remoteAddress)) { + return writeError(res, 403, 'Forbidden'); + } + + if (!isAuthorized(req.headers.authorization, token)) { + res.setHeader('WWW-Authenticate', 'Bearer'); + return writeError(res, 401, 'Unauthorized'); + } + + const url = req.url ?? ''; + const pathOnly = url.split('?')[0]; + if (pathOnly !== '/mcp') { + return writeError(res, 404, 'Not Found'); + } + + let body: unknown; + if (req.method === 'POST') { + try { + body = await readJsonBody(req); + } catch (err) { + return writeError(res, 400, err instanceof Error ? err.message : 'Bad Request'); + } + } + + const server = new McpServer(SERVER_INFO); + registerPhase1Tools(server); + const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined }); + + res.on('close', () => { + transport.close().catch(() => undefined); + server.close().catch(() => undefined); + }); + + await server.connect(transport); + await transport.handleRequest(req, res, body); +} + +async function readJsonBody(req: IncomingMessage): Promise { + let total = 0; + const chunks: Buffer[] = []; + for await (const chunk of req) { + const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); + total += buf.length; + if (total > MAX_BODY_BYTES) { + throw new Error('Request body too large'); + } + chunks.push(buf); + } + if (chunks.length === 0) return undefined; + const text = Buffer.concat(chunks).toString('utf8'); + try { + return JSON.parse(text); + } catch { + throw new Error('Invalid JSON body'); + } +} + +function writeError(res: ServerResponse, status: number, message: string) { + if (!res.headersSent) { + res.statusCode = status; + res.setHeader('Content-Type', 'application/json'); + } + res.end(JSON.stringify({ error: message })); +} + +function parsePort(value: string | undefined): number { + const parsed = value ? Number(value) : NaN; + if (Number.isInteger(parsed) && parsed >= 0 && parsed <= 65535) return parsed; + return 8765; +} + +function log(message: string) { + process.stderr.write(`[mcp] ${message}\n`); +} + +function logErr(message: string, error: unknown) { + const detail = error instanceof Error ? error.stack ?? error.message : String(error); + process.stderr.write(`[mcp] ${message}: ${detail}\n`); +} diff --git a/apps/cli/src/index.ts b/apps/cli/src/index.ts index ba67f4e5..e8e8dc3c 100644 --- a/apps/cli/src/index.ts +++ b/apps/cli/src/index.ts @@ -92,6 +92,16 @@ program .argument('', 'Trusted sources') .action(returnLoggerMiddleware(setCustomTrustedSourcesAsync)); +program + .command('mcp') + .description('Start the Model Context Protocol server') + .option('--port ', 'Port to listen on (default: 8765)') + .option('--token ', 'Override the bearer token (default: persisted in user settings)') + .action(async (options) => { + const { mcpServerAsync } = await import('./commands/Mcp'); + await mcpServerAsync(options); + }); + if (process.argv.length < 3) { program.help(); } diff --git a/apps/cli/src/mcp/README.md b/apps/cli/src/mcp/README.md new file mode 100644 index 00000000..0cecd879 --- /dev/null +++ b/apps/cli/src/mcp/README.md @@ -0,0 +1,125 @@ +# Expo Orbit MCP server + +The Orbit CLI ships an MCP (Model Context Protocol) server that lets AI coding agents — Cursor, Claude Code, Claude Desktop — drive your local iOS simulators, Android emulators, and connected devices through Orbit. You ask the agent to "list my simulators" or "check my Android tooling" and it calls into the same code paths the Orbit menu-bar uses. + +The server is exposed as a CLI subcommand: + +```bash +expo-orbit-cli mcp [--port ] [--token ] +``` + +It listens on `127.0.0.1` over HTTP/SSE, gated by a bearer token. + +--- + +## Quick start + +### 1. Build the CLI + +```bash +yarn install +yarn --cwd apps/cli build +``` + +### 2. Start the server + +```bash +node apps/cli/build/index.js mcp +``` + +Defaults: port `8765`, token persisted in `~/.expo/orbit/auth.json` (auto-generated on first run). On startup the server prints both: + +``` +[mcp] Expo Orbit MCP listening on http://127.0.0.1:8765/mcp +[mcp] Token: +``` + +Override either flag for ad-hoc runs: + +```bash +node apps/cli/build/index.js mcp --port 9000 --token devtoken +``` + +### 3. Hook up a client + +Add a server entry in your AI client's MCP config. The shape is the same across clients — set the URL to `http://127.0.0.1:/mcp` and pass the token in the `Authorization` header: + +```json +{ + "mcpServers": { + "expo-orbit": { + "url": "http://127.0.0.1:8765/mcp", + "headers": { "Authorization": "Bearer " } + } + } +} +``` + +Config locations: + +| Client | Path | +|---|---| +| Claude Desktop (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` | +| Cursor (global) | `~/.cursor/mcp.json` | +| Cursor (per-project) | `/.cursor/mcp.json` | +| Claude Code | `claude mcp add` or `~/.config/claude-code/mcp.json` | + +After saving the config, restart the client. The tools below should appear in the agent's tool list. + +--- + +## Tools + +| Tool | Inputs | Output | Read-only | +|---|---|---|---| +| `list_devices` | `platform?: ios \| android \| tvos \| watchos \| all` (default `all`) | iOS / Android / tvOS / watchOS device arrays | yes | +| `check_tools` | `platform?: ios \| android \| all` (default `all`) | `{ ios?, android?: { success, reason? } }` | yes | +| `get_trusted_sources` | — | `string[]` of allowlisted URL globs | yes | +| `detect_apple_app_type` | `appPath: string` (path to `.app`, `.ipa`, or archive) | `{ deviceType: 'simulator' \| 'device', ... }` | yes | + +All current tools are read-only — they don't boot devices, install apps, or change state. Mutating tools (`boot_device`, `install_and_launch`, `launch_update`, etc.) ship in later phases. + +--- + +## Authentication + +The MCP server is bound to `127.0.0.1` and rejects any non-local request, but localhost is still reachable by every process on your machine — so the bearer token is required. + +- **First run:** a 64-character hex token is generated and stored in `~/.expo/orbit/auth.json` under `mcpToken`. Reuse it across restarts. +- **Override:** pass `--token ` for an ephemeral token (not persisted). +- **Rotate:** delete the `mcpToken` field in `user-settings.json` and restart. A fresh token will be generated. + +Bad credentials → `401 Unauthorized`. Non-localhost source → `403 Forbidden`. + +--- + +## Dev loop + +For iterating on tools without an LLM in the loop, the MCP Inspector is faster than connecting Claude Desktop: + +```bash +node apps/cli/build/index.js mcp --port 8765 --token devtoken & +npx @modelcontextprotocol/inspector +``` + +Then in the Inspector UI, point it at `http://127.0.0.1:8765/mcp` with `Authorization: Bearer devtoken`. You can browse the schema, call tools, and inspect raw JSON-RPC traffic. + +You can also exercise it directly with curl: + +```bash +curl -sS -X POST http://127.0.0.1:8765/mcp \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json, text/event-stream' \ + -H 'Authorization: Bearer devtoken' \ + -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' +``` + +--- + +## How it works + +The `mcp` subcommand starts a long-lived Node HTTP server using `@modelcontextprotocol/sdk`'s `StreamableHTTPServerTransport` in stateless mode. Every tool call re-forks the same CLI binary for the underlying subcommand — `list_devices` shells out to `expo-orbit-cli list-devices`, `check_tools` shells out to `expo-orbit-cli check-tools`, and so on. + +That means MCP tools inherit the CLI's existing behavior for free: trusted-source URL allowlist, error codes (`UNTRUSTED_SOURCE`, `UNAUTHORIZED_ACCOUNT`, …), session secret resolution, etc. There's no parallel implementation to keep in sync. + +When Orbit's menu-bar app starts the MCP server (a future phase), the same CLI binary it already bundles is reused — both the macOS native host and the Electron host on Windows/Linux launch `expo-orbit-cli mcp` the same way they launch any other CLI subcommand. diff --git a/apps/cli/src/mcp/auth.ts b/apps/cli/src/mcp/auth.ts new file mode 100644 index 00000000..fa0c4cc3 --- /dev/null +++ b/apps/cli/src/mcp/auth.ts @@ -0,0 +1,35 @@ +import { randomBytes } from 'crypto'; + +import { getMcpToken, setMcpToken } from '../storage'; + +export async function ensureMcpTokenAsync(provided?: string): Promise { + if (provided) return provided; + + const existing = getMcpToken(); + if (existing) return existing; + + const token = randomBytes(32).toString('hex'); + await setMcpToken(token); + return token; +} + +export function isAuthorized(headerValue: string | undefined, token: string): boolean { + if (!headerValue) return false; + const expected = `Bearer ${token}`; + if (headerValue.length !== expected.length) return false; + // Constant-time compare + let mismatch = 0; + for (let i = 0; i < expected.length; i++) { + mismatch |= headerValue.charCodeAt(i) ^ expected.charCodeAt(i); + } + return mismatch === 0; +} + +export function isLocalhost(remoteAddress: string | undefined): boolean { + if (!remoteAddress) return false; + return ( + remoteAddress === '127.0.0.1' || + remoteAddress === '::1' || + remoteAddress === '::ffff:127.0.0.1' + ); +} diff --git a/apps/cli/src/mcp/dispatch.ts b/apps/cli/src/mcp/dispatch.ts new file mode 100644 index 00000000..c2d00849 --- /dev/null +++ b/apps/cli/src/mcp/dispatch.ts @@ -0,0 +1,83 @@ +import { fork } from 'child_process'; + +export type CliErrorPayload = { + name?: string; + code?: string; + message: string; + details?: unknown; + stack?: string; +}; + +export type DispatchResult = + | { ok: true; value: T } + | { ok: false; error: CliErrorPayload }; + +export async function dispatchCliAsync( + command: string, + args: string[] = [] +): Promise> { + const cliPath = process.argv[1]; + + return new Promise>((resolve) => { + const child = fork(cliPath, [command, ...args], { + env: { ...process.env, EXPO_MENU_BAR: 'true' }, + stdio: 'pipe', + }); + + let mode: 'pre' | 'return' | 'error' = 'pre'; + let payload = ''; + let stderr = ''; + + const handleStream = (data: Buffer) => { + const lines = data.toString().split('\n'); + for (const line of lines) { + if (line === '') continue; + if (line === '---- return output ----') { + mode = 'return'; + } else if (line === '---- thrown error ----') { + mode = 'error'; + } else if (mode !== 'pre') { + payload += line; + } + } + }; + + child.stdout?.on('data', handleStream); + child.stderr?.on('data', (d: Buffer) => { + stderr += d.toString(); + handleStream(d); + }); + + child.once('close', () => { + if (mode === 'error') { + try { + resolve({ ok: false, error: JSON.parse(payload) }); + } catch { + resolve({ + ok: false, + error: { message: payload || stderr || 'CLI exited with an unparseable error' }, + }); + } + return; + } + + if (mode === 'return') { + try { + resolve({ ok: true, value: JSON.parse(payload) as T }); + } catch { + resolve({ ok: true, value: payload as unknown as T }); + } + return; + } + + resolve({ + ok: false, + error: { message: stderr.trim() || 'CLI exited without producing output' }, + }); + }); + + child.once('error', (err) => { + resolve({ ok: false, error: { message: err.message, name: err.name } }); + }); + }); +} diff --git a/apps/cli/src/mcp/errors.ts b/apps/cli/src/mcp/errors.ts new file mode 100644 index 00000000..d370e61c --- /dev/null +++ b/apps/cli/src/mcp/errors.ts @@ -0,0 +1,29 @@ +import { CliErrorPayload, DispatchResult } from './dispatch'; + +export type ToolResult = { + content: Array<{ type: 'text'; text: string }>; + isError?: boolean; +}; + +export function toToolResult( + result: DispatchResult, + formatValue: (value: T) => string = defaultFormat +): ToolResult { + if (result.ok) { + return { content: [{ type: 'text', text: formatValue(result.value) }] }; + } + return { + isError: true, + content: [{ type: 'text', text: formatErrorMessage(result.error) }], + }; +} + +function formatErrorMessage(error: CliErrorPayload): string { + const code = error.code ? `[${error.code}] ` : ''; + return `${code}${error.message}`; +} + +function defaultFormat(value: unknown): string { + if (typeof value === 'string') return value; + return JSON.stringify(value, null, 2); +} diff --git a/apps/cli/src/mcp/tools/checkTools.ts b/apps/cli/src/mcp/tools/checkTools.ts new file mode 100644 index 00000000..b34e7448 --- /dev/null +++ b/apps/cli/src/mcp/tools/checkTools.ts @@ -0,0 +1,28 @@ +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { z } from 'zod'; + +import { dispatchCliAsync } from '../dispatch'; +import { toToolResult } from '../errors'; +import { registerTool } from './register'; + +export function registerCheckToolsTool(server: McpServer) { + registerTool( + server, + 'check_tools', + 'Validate that the local iOS and/or Android development tools are installed (Xcode, Android SDK). Returns success or a structured failure reason per platform.', + { + platform: z + .enum(['ios', 'android', 'all']) + .optional() + .describe('Filter by platform. Defaults to "all".'), + }, + { readOnlyHint: true, openWorldHint: false, title: 'Check development tools' }, + async ({ platform }) => { + const result = await dispatchCliAsync('check-tools', [ + '--platform', + platform ?? 'all', + ]); + return toToolResult(result); + } + ); +} diff --git a/apps/cli/src/mcp/tools/detectAppleAppType.ts b/apps/cli/src/mcp/tools/detectAppleAppType.ts new file mode 100644 index 00000000..15634e15 --- /dev/null +++ b/apps/cli/src/mcp/tools/detectAppleAppType.ts @@ -0,0 +1,25 @@ +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { z } from 'zod'; + +import { dispatchCliAsync } from '../dispatch'; +import { toToolResult } from '../errors'; +import { registerTool } from './register'; + +export function registerDetectAppleAppTypeTool(server: McpServer) { + registerTool( + server, + 'detect_apple_app_type', + 'Inspect a local .app, .ipa, or build archive and report whether it targets a simulator or a physical device, plus its bundle identifier.', + { + appPath: z + .string() + .min(1) + .describe('Local path to the .app, .ipa, or archive containing the app.'), + }, + { readOnlyHint: true, openWorldHint: false, title: 'Detect Apple app type' }, + async ({ appPath }) => { + const result = await dispatchCliAsync('detect-apple-app-type', [appPath]); + return toToolResult(result); + } + ); +} diff --git a/apps/cli/src/mcp/tools/index.ts b/apps/cli/src/mcp/tools/index.ts new file mode 100644 index 00000000..01b1427a --- /dev/null +++ b/apps/cli/src/mcp/tools/index.ts @@ -0,0 +1,13 @@ +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; + +import { registerCheckToolsTool } from './checkTools'; +import { registerDetectAppleAppTypeTool } from './detectAppleAppType'; +import { registerListDevicesTool } from './listDevices'; +import { registerTrustedSourcesTools } from './trustedSources'; + +export function registerPhase1Tools(server: McpServer) { + registerListDevicesTool(server); + registerCheckToolsTool(server); + registerTrustedSourcesTools(server); + registerDetectAppleAppTypeTool(server); +} diff --git a/apps/cli/src/mcp/tools/listDevices.ts b/apps/cli/src/mcp/tools/listDevices.ts new file mode 100644 index 00000000..9b7f9ff8 --- /dev/null +++ b/apps/cli/src/mcp/tools/listDevices.ts @@ -0,0 +1,28 @@ +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { z } from 'zod'; + +import { dispatchCliAsync } from '../dispatch'; +import { toToolResult } from '../errors'; +import { registerTool } from './register'; + +export function registerListDevicesTool(server: McpServer) { + registerTool( + server, + 'list_devices', + 'List connected iOS devices, iOS/tvOS/watchOS simulators, Android devices, and Android emulators.', + { + platform: z + .enum(['ios', 'android', 'tvos', 'watchos', 'all']) + .optional() + .describe('Filter by platform. Defaults to "all".'), + }, + { readOnlyHint: true, openWorldHint: false, title: 'List devices' }, + async ({ platform }) => { + const result = await dispatchCliAsync('list-devices', [ + '--platform', + platform ?? 'all', + ]); + return toToolResult(result); + } + ); +} diff --git a/apps/cli/src/mcp/tools/register.ts b/apps/cli/src/mcp/tools/register.ts new file mode 100644 index 00000000..895710d9 --- /dev/null +++ b/apps/cli/src/mcp/tools/register.ts @@ -0,0 +1,48 @@ +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { ZodRawShape, z } from 'zod'; + +import { ToolResult } from '../errors'; + +export type ToolAnnotations = { + title?: string; + readOnlyHint?: boolean; + destructiveHint?: boolean; + idempotentHint?: boolean; + openWorldHint?: boolean; +}; + +export function registerTool( + server: McpServer, + name: string, + description: string, + schema: Schema, + annotations: ToolAnnotations, + handler: (args: z.objectOutputType) => Promise +): void; +export function registerTool( + server: McpServer, + name: string, + description: string, + annotations: ToolAnnotations, + handler: () => Promise +): void; +export function registerTool( + server: McpServer, + name: string, + description: string, + schemaOrAnnotations: ZodRawShape | ToolAnnotations, + annotationsOrHandler: ToolAnnotations | (() => Promise), + maybeHandler?: (args: any) => Promise +): void { + // The @modelcontextprotocol/sdk `tool()` overloads cause TS2589 ("type + // instantiation is excessively deep") when the inferred `Args` involves + // `.optional()` — the conditional `BaseToolCallback` tries to distribute + // over the v3/v4 zod union. Cast to `any` at the boundary; the public + // signature above still gives callers typed args. + const anyServer = server as any; + if (typeof annotationsOrHandler === 'function') { + anyServer.tool(name, description, schemaOrAnnotations, annotationsOrHandler); + } else { + anyServer.tool(name, description, schemaOrAnnotations, annotationsOrHandler, maybeHandler); + } +} diff --git a/apps/cli/src/mcp/tools/trustedSources.ts b/apps/cli/src/mcp/tools/trustedSources.ts new file mode 100644 index 00000000..26800b7b --- /dev/null +++ b/apps/cli/src/mcp/tools/trustedSources.ts @@ -0,0 +1,18 @@ +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; + +import { dispatchCliAsync } from '../dispatch'; +import { toToolResult } from '../errors'; +import { registerTool } from './register'; + +export function registerTrustedSourcesTools(server: McpServer) { + registerTool( + server, + 'get_trusted_sources', + 'Return the user-configured allowlist of URL glob patterns from which Orbit will download builds and updates.', + { readOnlyHint: true, openWorldHint: false, title: 'Get trusted sources' }, + async () => { + const result = await dispatchCliAsync('get-custom-trusted-sources'); + return toToolResult(result); + } + ); +} diff --git a/apps/cli/src/storage.ts b/apps/cli/src/storage.ts index c746e3ea..578ee69a 100644 --- a/apps/cli/src/storage.ts +++ b/apps/cli/src/storage.ts @@ -20,9 +20,19 @@ export async function setCustomTrustedSources(trustedSources: string[] | undefin await userSettingsJsonFile().setAsync('trustedSources', trustedSources); } +export function getMcpToken(): string | undefined { + const userSettings = userSettingsJsonFile().read(); + return userSettings.mcpToken; +} + +export async function setMcpToken(mcpToken: string): Promise { + await userSettingsJsonFile().setAsync('mcpToken', mcpToken); +} + type UserData = { sessionSecret?: string; trustedSources?: string[]; + mcpToken?: string; }; function userSettingsJsonFile(): JsonFile { diff --git a/yarn.lock b/yarn.lock index f03fe51e..02dec695 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2519,6 +2519,11 @@ dependencies: csstype "^3.1.3" +"@hono/node-server@^1.19.9": + version "1.19.14" + resolved "https://registry.yarnpkg.com/@hono/node-server/-/node-server-1.19.14.tgz#e30f844bc77e3ce7be442aac3b1f73ad8b58d181" + integrity sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw== + "@humanwhocodes/config-array@^0.13.0": version "0.13.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" @@ -2940,6 +2945,29 @@ yargs "16.2.0" yargs-parser "20.2.4" +"@modelcontextprotocol/sdk@^1.21.0": + version "1.29.0" + resolved "https://registry.yarnpkg.com/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz#79786d8b525e269de850ac82b1f1f757f3915f44" + integrity sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ== + dependencies: + "@hono/node-server" "^1.19.9" + ajv "^8.17.1" + ajv-formats "^3.0.1" + content-type "^1.0.5" + cors "^2.8.5" + cross-spawn "^7.0.5" + eventsource "^3.0.2" + eventsource-parser "^3.0.0" + express "^5.2.1" + express-rate-limit "^8.2.1" + hono "^4.11.4" + jose "^6.1.3" + json-schema-typed "^8.0.2" + pkce-challenge "^5.0.0" + raw-body "^3.0.0" + zod "^3.25 || ^4.0" + zod-to-json-schema "^3.25.1" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -4163,6 +4191,14 @@ accepts@^1.3.7, accepts@^1.3.8: mime-types "~2.1.34" negotiator "0.6.3" +accepts@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-2.0.0.tgz#bbcf4ba5075467f3f2131eab3cffc73c2f5d7895" + integrity sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng== + dependencies: + mime-types "^3.0.0" + negotiator "^1.0.0" + acorn-globals@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" @@ -4227,6 +4263,13 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" +ajv-formats@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578" + integrity sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ== + dependencies: + ajv "^8.0.0" + ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -4247,6 +4290,16 @@ ajv@^8.0.0, ajv@^8.6.3: json-schema-traverse "^1.0.0" require-from-string "^2.0.2" +ajv@^8.17.1: + version "8.20.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.20.0.tgz#304b3636add88ba7d936760dd50ece006dea95f9" + integrity sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + anser@^1.4.9: version "1.4.10" resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.10.tgz#befa3eddf282684bd03b63dcda3927aef8c2e35b" @@ -4760,6 +4813,21 @@ bl@^4.0.3, bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" +body-parser@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-2.2.2.tgz#1a32cdb966beaf68de50a9dfbe5b58f83cb8890c" + integrity sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA== + dependencies: + bytes "^3.1.2" + content-type "^1.0.5" + debug "^4.4.3" + http-errors "^2.0.0" + iconv-lite "^0.7.0" + on-finished "^2.4.1" + qs "^6.14.1" + raw-body "^3.0.1" + type-is "^2.0.1" + boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -4890,7 +4958,7 @@ byte-size@8.1.1: resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.1.tgz#3424608c62d59de5bfda05d31e0313c6174842ae" integrity sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg== -bytes@3.1.2: +bytes@3.1.2, bytes@^3.1.2, bytes@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== @@ -5449,6 +5517,16 @@ constant-case@^3.0.4: tslib "^2.0.3" upper-case "^2.0.2" +content-disposition@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-1.1.0.tgz#f3db789c752d45564cc7e9e1e0b31790d4a38e17" + integrity sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g== + +content-type@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + conventional-changelog-angular@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz#5eec8edbff15aa9b1680a8dcfbd53e2d7eb2ba7a" @@ -5527,6 +5605,16 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== +cookie-signature@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.2.2.tgz#57c7fc3cc293acab9fec54d73e15690ebe4a1793" + integrity sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg== + +cookie@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== + core-js-compat@^3.38.0, core-js-compat@^3.38.1: version "3.39.0" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.39.0.tgz#b12dccb495f2601dc860bdbe7b4e3ffa8ba63f61" @@ -5539,6 +5627,14 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cors@^2.8.5: + version "2.8.6" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.6.tgz#ff5dd69bd95e547503820d29aba4f8faf8dfec96" + integrity sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw== + dependencies: + object-assign "^4" + vary "^1" + cosmiconfig@^8.1.0, cosmiconfig@^8.1.3, cosmiconfig@^8.2.0: version "8.3.6" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" @@ -5585,6 +5681,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^7.0.5: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" @@ -5750,6 +5855,13 @@ debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + decamelize-keys@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" @@ -5859,7 +5971,7 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== -depd@2.0.0: +depd@2.0.0, depd@^2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -6101,16 +6213,16 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== +encodeurl@^2.0.0, encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -encodeurl@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" - integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== - encoding@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" @@ -6316,7 +6428,7 @@ escalade@^3.1.1, escalade@^3.2.0: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== -escape-html@~1.0.3: +escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== @@ -6620,7 +6732,7 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -etag@~1.8.1: +etag@^1.8.1, etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== @@ -6635,6 +6747,18 @@ eventemitter3@^4.0.4: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== +eventsource-parser@^3.0.0, eventsource-parser@^3.0.1: + version "3.0.8" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.8.tgz#1c792503e4080455d00701bb1f7a1d60734d0e58" + integrity sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ== + +eventsource@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-3.0.7.tgz#1157622e2f5377bb6aef2114372728ba0c156989" + integrity sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA== + dependencies: + eventsource-parser "^3.0.1" + exec-async@2.2.0, exec-async@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/exec-async/-/exec-async-2.2.0.tgz#c7c5ad2eef3478d38390c6dd3acfe8af0efc8301" @@ -6797,6 +6921,47 @@ exponential-backoff@^3.1.1: resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== +express-rate-limit@^8.2.1: + version "8.5.0" + resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-8.5.0.tgz#ef4709a569b8e763ae2a2420f3d74537bbbe9795" + integrity sha512-XKhFohWaSBdVJNTi5TaHziqnPkv04I9UQV6q1Wy7Ui6GGQZVW12ojDFwqer14EvCXxjvPG0CyWXx7cAXpALB4Q== + dependencies: + ip-address "10.1.0" + +express@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/express/-/express-5.2.1.tgz#8f21d15b6d327f92b4794ecf8cb08a72f956ac04" + integrity sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw== + dependencies: + accepts "^2.0.0" + body-parser "^2.2.1" + content-disposition "^1.0.0" + content-type "^1.0.5" + cookie "^0.7.1" + cookie-signature "^1.2.1" + debug "^4.4.0" + depd "^2.0.0" + encodeurl "^2.0.0" + escape-html "^1.0.3" + etag "^1.8.1" + finalhandler "^2.1.0" + fresh "^2.0.0" + http-errors "^2.0.0" + merge-descriptors "^2.0.0" + mime-types "^3.0.0" + on-finished "^2.4.1" + once "^1.4.0" + parseurl "^1.3.3" + proxy-addr "^2.0.7" + qs "^6.14.0" + range-parser "^1.2.1" + router "^2.2.0" + send "^1.1.0" + serve-static "^2.2.0" + statuses "^2.0.1" + type-is "^2.0.1" + vary "^1.1.2" + external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -6960,6 +7125,18 @@ finalhandler@1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +finalhandler@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-2.1.1.tgz#a2c517a6559852bcdb06d1f8bd7f51b68fad8099" + integrity sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA== + dependencies: + debug "^4.4.0" + encodeurl "^2.0.0" + escape-html "^1.0.3" + on-finished "^2.4.1" + parseurl "^1.3.3" + statuses "^2.0.1" + find-up@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -7055,6 +7232,11 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + freeport-async@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/freeport-async/-/freeport-async-2.0.0.tgz#6adf2ec0c629d11abff92836acd04b399135bab4" @@ -7065,6 +7247,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== +fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-2.0.0.tgz#8dd7df6a1b3a1b3a5cf186c05a5dd267622635a4" + integrity sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A== + from2@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -7668,6 +7855,11 @@ hoist-non-react-statics@^3.3.2: dependencies: react-is "^16.7.0" +hono@^4.11.4: + version "4.12.17" + resolved "https://registry.yarnpkg.com/hono/-/hono-4.12.17.tgz#1465ab13d72d3f6dd8aa515ba3ba0672bba223d7" + integrity sha512-FbJJNb/XgX7YW0hX/V8w5oYLztKEsRLykCMZWt1WdLtsfjzMvmoqWBA4H4t5norinq8/rh20oiZYr+WSl4UzAQ== + hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" @@ -7729,6 +7921,17 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-errors@^2.0.0, http-errors@^2.0.1, http-errors@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" + integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== + dependencies: + depd "~2.0.0" + inherits "~2.0.4" + setprototypeof "~1.2.0" + statuses "~2.0.2" + toidentifier "~1.0.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -7801,6 +8004,13 @@ iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@^0.7.0, iconv-lite@~0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e" + integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -7894,7 +8104,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -7969,6 +8179,11 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" +ip-address@10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.1.0.tgz#d8dcffb34d0e02eb241427444a6e23f5b0595aa4" + integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q== + ip-address@^9.0.5: version "9.0.5" resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" @@ -7977,6 +8192,11 @@ ip-address@^9.0.5: jsbn "1.1.0" sprintf-js "^1.1.3" +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + is-absolute@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" @@ -8177,6 +8397,11 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== +is-promise@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" + integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== + is-regex@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" @@ -8848,6 +9073,11 @@ jose@^5.0.0: resolved "https://registry.yarnpkg.com/jose/-/jose-5.9.6.tgz#77f1f901d88ebdc405e57cce08d2a91f47521883" integrity sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ== +jose@^6.1.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/jose/-/jose-6.2.3.tgz#0975197ad973251221c658a3cddc4b951a250c2d" + integrity sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -8955,6 +9185,11 @@ json-schema-typed@^7.0.3: resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-7.0.3.tgz#23ff481b8b4eebcd2ca123b4fa0409e66469a2d9" integrity sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A== +json-schema-typed@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-8.0.2.tgz#e98ee7b1899ff4a184534d1f167c288c66bbeff4" + integrity sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA== + json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" @@ -9582,6 +9817,11 @@ mdn-data@2.0.30: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== +media-typer@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" + integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== + memoize-one@^5.0.0: version "5.2.1" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" @@ -9609,6 +9849,11 @@ meow@^8.1.2: type-fest "^0.18.0" yargs-parser "^20.2.3" +merge-descriptors@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz#ea922f660635a2249ee565e0449f951e6b603808" + integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -9835,6 +10080,11 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.53.0.tgz#3cb63cd820fc29896d9d4e8c32ab4fcd74ccb447" integrity sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg== +mime-db@^1.54.0: + version "1.54.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" + integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== + mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" @@ -9842,6 +10092,13 @@ mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.34: dependencies: mime-db "1.52.0" +mime-types@^3.0.0, mime-types@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-3.0.2.tgz#39002d4182575d5af036ffa118100f2524b2e2ab" + integrity sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A== + dependencies: + mime-db "^1.54.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -10116,6 +10373,11 @@ negotiator@^0.6.3, negotiator@~0.6.4: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== +negotiator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" + integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== + neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" @@ -10460,7 +10722,7 @@ ob1@0.83.3: dependencies: flow-enums-runtime "^0.0.6" -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -10526,7 +10788,7 @@ object.values@^1.1.6, object.values@^1.2.0, object.values@^1.2.1: define-properties "^1.2.1" es-object-atoms "^1.0.0" -on-finished@2.4.1: +on-finished@2.4.1, on-finished@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== @@ -10863,7 +11125,7 @@ parse5@^7.0.0, parse5@^7.1.1: dependencies: entities "^4.5.0" -parseurl@~1.3.3: +parseurl@^1.3.3, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -10963,6 +11225,11 @@ path-scurry@^2.0.0: lru-cache "^11.0.0" minipass "^7.1.2" +path-to-regexp@^8.0.0: + version "8.4.2" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-8.4.2.tgz#795c420c4f7ca45c5b887366f622ee0c9852cccd" + integrity sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA== + path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -11030,6 +11297,11 @@ pirates@^4.0.1, pirates@^4.0.4: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== +pkce-challenge@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/pkce-challenge/-/pkce-challenge-5.0.1.tgz#3b4446865b17b1745e9ace2016a31f48ddf6230d" + integrity sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ== + pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" @@ -11241,6 +11513,14 @@ protocols@^2.0.0, protocols@^2.0.1: resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== +proxy-addr@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" @@ -11274,6 +11554,13 @@ qrcode-terminal@0.11.0: resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz#ffc6c28a2fc0bfb47052b47e23f4f446a5fbdb9e" integrity sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ== +qs@^6.14.0, qs@^6.14.1: + version "6.15.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.1.tgz#bdb55aed06bfac257a90c44a446a73fba5575c8f" + integrity sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg== + dependencies: + side-channel "^1.1.0" + querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" @@ -11306,11 +11593,21 @@ quick-lru@^5.1.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== -range-parser@~1.2.1: +range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== +raw-body@^3.0.0, raw-body@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-3.0.2.tgz#3e3ada5ae5568f9095d84376fd3a49b8fb000a51" + integrity sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA== + dependencies: + bytes "~3.1.2" + http-errors "~2.0.1" + iconv-lite "~0.7.0" + unpipe "~1.0.0" + rc@^1.2.7, rc@~1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -11906,6 +12203,17 @@ roarr@^2.15.3: semver-compare "^1.0.0" sprintf-js "^1.1.2" +router@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/router/-/router-2.2.0.tgz#019be620b711c87641167cc79b99090f00b146ef" + integrity sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ== + dependencies: + debug "^4.4.0" + depd "^2.0.0" + is-promise "^4.0.0" + parseurl "^1.3.3" + path-to-regexp "^8.0.0" + rtl-css-js@^1.16.1: version "1.16.1" resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.16.1.tgz#4b48b4354b0ff917a30488d95100fbf7219a3e80" @@ -12081,6 +12389,23 @@ send@^0.19.0: range-parser "~1.2.1" statuses "2.0.1" +send@^1.1.0, send@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/send/-/send-1.2.1.tgz#9eab743b874f3550f40a26867bf286ad60d3f3ed" + integrity sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ== + dependencies: + debug "^4.4.3" + encodeurl "^2.0.0" + escape-html "^1.0.3" + etag "^1.8.1" + fresh "^2.0.0" + http-errors "^2.0.1" + mime-types "^3.0.2" + ms "^2.1.3" + on-finished "^2.4.1" + range-parser "^1.2.1" + statuses "^2.0.2" + sentence-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-3.0.4.tgz#3645a7b8c117c787fde8702056225bb62a45131f" @@ -12112,6 +12437,16 @@ serve-static@^1.16.2: parseurl "~1.3.3" send "0.19.0" +serve-static@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-2.2.1.tgz#7f186a4a4e5f5b663ad7a4294ff1bf37cf0e98a9" + integrity sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw== + dependencies: + encodeurl "^2.0.0" + escape-html "^1.0.3" + parseurl "^1.3.3" + send "^1.2.0" + server-only@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/server-only/-/server-only-0.0.1.tgz#0f366bb6afb618c37c9255a314535dc412cd1c9e" @@ -12158,7 +12493,7 @@ setimmediate@^1.0.5: resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== -setprototypeof@1.2.0: +setprototypeof@1.2.0, setprototypeof@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== @@ -12518,6 +12853,11 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +statuses@^2.0.1, statuses@^2.0.2, statuses@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== + statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" @@ -13077,7 +13417,7 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.1: +toidentifier@1.0.1, toidentifier@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== @@ -13264,6 +13604,15 @@ type-fest@^4.41.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== +type-is@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-2.0.1.tgz#64f6cf03f92fce4015c2b224793f6bdd4b068c97" + integrity sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw== + dependencies: + content-type "^1.0.5" + media-typer "^1.1.0" + mime-types "^3.0.0" + typed-array-buffer@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536" @@ -13580,7 +13929,7 @@ value-or-promise@^1.0.11, value-or-promise@^1.0.12: resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.12.tgz#0e5abfeec70148c78460a849f6b003ea7986f15c" integrity sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q== -vary@~1.1.2: +vary@^1, vary@^1.1.2, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== @@ -14056,6 +14405,11 @@ zen-observable@0.8.15: resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== +zod-to-json-schema@^3.25.1: + version "3.25.2" + resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz#3fa799a7badd554541472fb65843fdc460b2e5aa" + integrity sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA== + zod-validation-error@^3.0.3: version "3.4.1" resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-3.4.1.tgz#fb0a64f15d90f4aafe9ccc804331853609aad408" @@ -14065,3 +14419,13 @@ zod@^3.22.4: version "3.25.7" resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.7.tgz#74184ecfe03ef8c67a62393008117b3b8d9cc48c" integrity sha512-YGdT1cVRmKkOg6Sq7vY7IkxdphySKnXhaUmFI4r4FcuFVNgpCb9tZfNwXbT6BPjD5oz0nubFsoo9pIqKrDcCvg== + +"zod@^3.25 || ^4.0": + version "4.4.3" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.4.3.tgz#b680f172885d18bbebf21a834ea25e55a1bbf356" + integrity sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ== + +zod@^3.25.0: + version "3.25.76" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.76.tgz#26841c3f6fd22a6a2760e7ccb719179768471e34" + integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==