diff --git a/apps/api/package.json b/apps/api/package.json index 6f5572e..e216573 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -34,9 +34,11 @@ "@coderscreen/email": "workspace:^", "@daytonaio/sdk": "0.21.1", "@hono/zod-validator": "^0.7.0", + "@modelcontextprotocol/sdk": "^1.29.0", "@sentry/cloudflare": "10.65.0", "@tldraw/sync-core": "^3.14.0", "@tldraw/tlschema": "^3.14.0", + "agents": "^0.19.0", "better-auth": "^1.2.10", "drizzle-orm": "^0.44.2", "hono": "^4.7.11", diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index c970a31..464bc16 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -12,10 +12,15 @@ import { openAPISpecs } from 'hono-openapi'; import { useAuth } from '@/lib/auth'; import { getSentryOptions } from '@/lib/sentry'; import { getBilling } from '@/lib/session'; +import { CoderScreenMcp } from '@/mcp/agent'; +import { handleMcpSSE, handleMcpStreamable } from '@/mcp/handler'; +import { apiKeyMiddleware } from '@/middleware/apiKey.middleware'; import { authMiddleware } from '@/middleware/auth.middleware'; import { RoomServer as PartyServer } from '@/partykit/room.do'; +import { apiKeyRouter } from '@/routes/apiKey.routes'; import { billingRouter } from '@/routes/billing.routes'; import { templateRouter } from '@/routes/template.routes'; +import { publicApiRouter } from '@/routes/v1'; import { webhookRouter } from '@/routes/webhook.routes'; import { PublicRoomSchema } from '@/schema/room.zod'; import { AppFactory, appFactoryMiddleware } from '@/services/AppFactory'; @@ -83,6 +88,11 @@ const app = new Hono() except( [ '/webhook/*', + '/v1/*', + '/mcp', + '/mcp/*', + '/sse', + '/sse/*', '/rooms/:roomId/public/*', '/assessments/:subId/take', '/assessments/:subId/take/*', @@ -91,6 +101,17 @@ const app = new Hono() authMiddleware ) ) + // Public API: separate surface authenticated with an org API key (never a + // session cookie), so keys can't reach the internal routes below. + .use('/v1/*', apiKeyMiddleware) + .route('/v1', publicApiRouter) + // Hosted MCP server wrapping /v1 (same API-key auth). Handlers verify the key + // then hand off to the CoderScreenMcp Durable Object. + .all('/mcp', handleMcpStreamable) + .all('/mcp/*', handleMcpStreamable) + .all('/sse', handleMcpSSE) + .all('/sse/*', handleMcpSSE) + .route('/api-keys', apiKeyRouter) .route('/webhook', webhookRouter) .route('/rooms/:roomId/public', publicRoomRouter) .route('/assets', assetRouter) @@ -245,6 +266,7 @@ const InstrumentedWhiteboardDurableObject = Sentry.instrumentDurableObjectWithSe export { Sandbox, + CoderScreenMcp, InstrumentedPartyServer as PartyServer, InstrumentedPrivateRoomServer as PrivateRoomServer, InstrumentedWhiteboardDurableObject as WhiteboardDurableObject, diff --git a/apps/api/src/lib/apiKeyAuth.ts b/apps/api/src/lib/apiKeyAuth.ts new file mode 100644 index 0000000..7dc5a1a --- /dev/null +++ b/apps/api/src/lib/apiKeyAuth.ts @@ -0,0 +1,105 @@ +import { apikey } from '@coderscreen/db/apikey.db'; +import { eq, sql } from 'drizzle-orm'; +import { Context } from 'hono'; +import { useDb } from '@/db/client'; +import { AppContext } from '@/index'; + +export interface ApiKeyIdentity { + keyId: string; + organizationId: string; + // The user who created the key. Used only to attribute API-created resources + // (e.g. rooms). The key itself acts for the organization. + createdBy: string; +} + +const KEY_PREFIX = 'cs'; +// Random part length. 32 chars of the id alphabet is ~190 bits of entropy. +const KEY_RANDOM_LENGTH = 32; +const ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + +/** SHA-256 hex digest, used to store/look up keys without persisting plaintext. */ +export const hashApiKey = async (key: string): Promise => { + const data = new TextEncoder().encode(key); + const digest = await crypto.subtle.digest('SHA-256', data); + return Array.from(new Uint8Array(digest)) + .map((b) => b.toString(16).padStart(2, '0')) + .join(''); +}; + +/** Cryptographically-random `cs_` key plus the bits we persist. */ +export const generateApiKey = async (): Promise<{ + key: string; + keyHash: string; + prefix: string; + start: string; +}> => { + const bytes = crypto.getRandomValues(new Uint8Array(KEY_RANDOM_LENGTH)); + const random = Array.from(bytes, (b) => ALPHABET[b % ALPHABET.length]).join(''); + const key = `${KEY_PREFIX}_${random}`; + return { + key, + keyHash: await hashApiKey(key), + prefix: KEY_PREFIX, + // Enough to disambiguate in the UI without revealing the secret. + start: key.slice(0, KEY_PREFIX.length + 1 + 6), + }; +}; + +/** Pull an API key from an `Authorization: Bearer ` or `x-api-key` header. */ +export const extractApiKey = (ctx: Context): string | undefined => { + const authHeader = ctx.req.header('authorization'); + const bearer = authHeader?.toLowerCase().startsWith('bearer ') + ? authHeader.slice(7).trim() + : undefined; + return bearer ?? ctx.req.header('x-api-key'); +}; + +/** + * Verify an API key against the apikey table and resolve the org it acts for. + * Returns null when the key is unknown, disabled, or expired. + * + * Single source of truth for API-key auth, shared by the REST middleware + * (apiKey.middleware.ts) and the MCP handler (mcp/handler.ts). + */ +export const verifyApiKey = async ( + ctx: Context, + key: string +): Promise => { + const db = useDb(ctx); + const keyHash = await hashApiKey(key); + + const row = await db + .select({ + id: apikey.id, + createdBy: apikey.createdBy, + organizationId: apikey.organizationId, + enabled: apikey.enabled, + expiresAt: apikey.expiresAt, + }) + .from(apikey) + .where(eq(apikey.keyHash, keyHash)) + .then((rows) => rows[0] ?? null); + + if (!row || !row.enabled) return null; + if (row.expiresAt && new Date(row.expiresAt).getTime() < Date.now()) return null; + + // Best-effort usage tracking; never block the request (or fail auth) on it. + const trackUsage = db + .update(apikey) + .set({ lastRequest: sql`now()`, requestCount: sql`${apikey.requestCount} + 1` }) + .where(eq(apikey.id, row.id)) + .then(() => undefined) + .catch(() => undefined); + try { + ctx.executionCtx.waitUntil(trackUsage); + } catch { + // No execution context (e.g. certain test/runtime paths) - fire and forget. + void trackUsage; + } + + return { + keyId: row.id, + organizationId: row.organizationId, + createdBy: row.createdBy, + }; +}; diff --git a/apps/api/src/mcp/agent.ts b/apps/api/src/mcp/agent.ts new file mode 100644 index 0000000..79447e0 --- /dev/null +++ b/apps/api/src/mcp/agent.ts @@ -0,0 +1,28 @@ +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { McpAgent } from 'agents/mcp'; +import { registerTools } from './executor'; + +/** + * Per-connection context, populated by the MCP handler after it verifies the + * caller's API key. Tools call `/v1` with `apiKey` against `baseUrl`; the org + * and acting user are re-derived server-side from the key on each `/v1` call, + * so nothing else needs to be stashed here. Declared as a type alias (not an + * interface) so it satisfies McpAgent's `Record` props + * constraint without an explicit index signature. + */ +export type McpProps = { + apiKey: string; + baseUrl: string; +}; + +/** + * Hosted MCP server (Durable Object) that wraps the public `/v1` API. Tool + * definitions live in tools.ts; this class only wires them onto the server. + */ +export class CoderScreenMcp extends McpAgent { + server = new McpServer({ name: 'coderscreen', version: '1.0.0' }); + + async init(): Promise { + registerTools(this.server, () => this.props); + } +} diff --git a/apps/api/src/mcp/executor.ts b/apps/api/src/mcp/executor.ts new file mode 100644 index 0000000..4bcd4d6 --- /dev/null +++ b/apps/api/src/mcp/executor.ts @@ -0,0 +1,49 @@ +import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import type { McpProps } from './agent'; +import { TOOLS } from './tools'; + +/** + * Registers every tool in the registry on the MCP server. Each tool is a thin + * bridge: it validates args (via the SDK, against the tool's `input` shape), + * calls the corresponding `/v1` endpoint with the caller's API key, and returns + * the raw JSON. `getProps` is read at call time so the caller's key/base URL are + * always current regardless of when the agent hydrated its props. + */ +export const registerTools = (server: McpServer, getProps: () => McpProps | undefined): void => { + for (const tool of TOOLS) { + server.registerTool( + tool.name, + { description: tool.description, inputSchema: tool.input }, + // args are validated by the SDK against inputSchema before this runs + (async (args: Record) => { + const props = getProps(); + if (!props) { + return { + content: [{ type: 'text' as const, text: 'Not authenticated' }], + isError: true, + }; + } + + const { method, path, body } = tool.request(args ?? {}); + const res = await fetch(`${props.baseUrl}/v1${path}`, { + method, + headers: { + authorization: `Bearer ${props.apiKey}`, + 'content-type': 'application/json', + }, + body: body === undefined ? undefined : JSON.stringify(body), + }); + + const text = await res.text(); + if (!res.ok) { + return { + content: [{ type: 'text' as const, text: `Error ${res.status}: ${text}` }], + isError: true, + }; + } + return { content: [{ type: 'text' as const, text }] }; + // biome-ignore lint/suspicious/noExplicitAny: registerTool's generic callback type + }) as any + ); + } +}; diff --git a/apps/api/src/mcp/handler.ts b/apps/api/src/mcp/handler.ts new file mode 100644 index 0000000..314dcc3 --- /dev/null +++ b/apps/api/src/mcp/handler.ts @@ -0,0 +1,53 @@ +import { Context } from 'hono'; +import { HTTPException } from 'hono/http-exception'; +import { AppContext } from '@/index'; +import { extractApiKey, verifyApiKey } from '@/lib/apiKeyAuth'; +import { CoderScreenMcp, McpProps } from './agent'; + +const MCP_BINDING = 'CODERSCREEN_MCP'; + +/** + * Verify the caller's API key and stash it (plus this request's origin) on the + * execution context's `props`. This is how the agents SDK passes per-connection + * context to an McpAgent: `McpAgent.serve()` reads `ctx.props` when it spins up + * the Durable Object (the same channel `@cloudflare/workers-oauth-provider` + * uses after an OAuth flow). Throws 401 if the key is missing or invalid. + */ +const authenticate = async (c: Context): Promise => { + const key = extractApiKey(c); + if (!key) { + throw new HTTPException(401, { + message: 'Missing API key. Provide it as "Authorization: Bearer ".', + }); + } + + const identity = await verifyApiKey(c, key); + if (!identity) { + throw new HTTPException(401, { message: 'Invalid API key' }); + } + + // Only the key and origin are needed; tools re-derive org/user from the key + // on each /v1 call. + const props: McpProps = { apiKey: key, baseUrl: new URL(c.req.url).origin }; + c.executionCtx.props = props; +}; + +/** Streamable HTTP transport (recommended). Single endpoint at /mcp. */ +export const handleMcpStreamable = async (c: Context): Promise => { + await authenticate(c); + return CoderScreenMcp.serve('/mcp', { binding: MCP_BINDING }).fetch( + c.req.raw, + c.env, + c.executionCtx + ); +}; + +/** Legacy SSE transport, for clients that don't support streamable HTTP yet. */ +export const handleMcpSSE = async (c: Context): Promise => { + await authenticate(c); + return CoderScreenMcp.serveSSE('/sse', { binding: MCP_BINDING }).fetch( + c.req.raw, + c.env, + c.executionCtx + ); +}; diff --git a/apps/api/src/mcp/tools.ts b/apps/api/src/mcp/tools.ts new file mode 100644 index 0000000..585de75 --- /dev/null +++ b/apps/api/src/mcp/tools.ts @@ -0,0 +1,105 @@ +import { z } from 'zod'; + +/** + * Declarative registry of MCP tools. Each entry maps 1:1 to a public `/v1` + * endpoint: `input` is the tool's parameters (a zod raw shape) and `request` + * turns validated args into the `/v1` call to make. Adding a public endpoint to + * the MCP is a single entry here; there is no per-tool boilerplate. Business + * logic stays in the services behind `/v1`. + */ +export interface McpToolDef { + name: string; + description: string; + input: z.ZodRawShape; + request: (args: Record) => { method: string; path: string; body?: unknown }; +} + +const withQuery = (base: string, params: Record): string => { + const qs = new URLSearchParams(); + for (const [k, v] of Object.entries(params)) { + if (v !== undefined && v !== null) qs.set(k, String(v)); + } + const s = qs.toString(); + return s ? `${base}?${s}` : base; +}; + +export const TOOLS: McpToolDef[] = [ + { + name: 'list_interviews', + description: 'List live coding interviews for your organization.', + input: {}, + request: () => ({ method: 'GET', path: '/rooms' }), + }, + { + name: 'create_interview', + description: + 'Create a live coding interview. Returns the interview and its shareable join URL.', + input: { + title: z.string().describe('Title of the interview'), + language: z.string().describe('Primary language, e.g. "python", "typescript", "go"'), + notes: z.string().optional().describe('Optional private notes'), + }, + request: (a) => ({ + method: 'POST', + path: '/rooms', + body: { title: a.title, language: a.language, notes: a.notes }, + }), + }, + { + name: 'get_interview', + description: 'Get a single interview by its ID.', + input: { id: z.string().describe('Interview ID (starts with r_)') }, + request: (a) => ({ method: 'GET', path: `/rooms/${a.id}` }), + }, + { + name: 'list_assessments', + description: 'List assessments (auto-graded coding tests) for your organization, paginated.', + input: { + page: z.number().int().min(1).optional().describe('Page number, default 1'), + limit: z.number().int().min(1).max(100).optional().describe('Page size, default 20'), + }, + request: (a) => ({ + method: 'GET', + path: withQuery('/assessments', { page: a.page, limit: a.limit }), + }), + }, + { + name: 'get_assessment', + description: 'Get a single assessment by its ID.', + input: { id: z.string().describe('Assessment ID (starts with as_)') }, + request: (a) => ({ method: 'GET', path: `/assessments/${a.id}` }), + }, + { + name: 'list_submissions', + description: 'List candidate submissions for an assessment, including scores and status.', + input: { assessmentId: z.string().describe('Assessment ID (starts with as_)') }, + request: (a) => ({ method: 'GET', path: `/assessments/${a.assessmentId}/submissions` }), + }, + { + name: 'invite_candidate', + description: + 'Invite a candidate to an assessment by email. Returns the submission with a take link to send them.', + input: { + assessmentId: z.string().describe('Assessment ID (starts with as_)'), + candidateName: z.string().describe('Candidate full name'), + candidateEmail: z.string().email().describe('Candidate email address'), + }, + request: (a) => ({ + method: 'POST', + path: `/assessments/${a.assessmentId}/invites`, + body: { candidateName: a.candidateName, candidateEmail: a.candidateEmail }, + }), + }, + { + name: 'get_submission', + description: 'Get a single submission (with results) by its ID.', + input: { id: z.string().describe('Submission ID (starts with asub_)') }, + request: (a) => ({ method: 'GET', path: `/submissions/${a.id}` }), + }, + { + name: 'list_candidates', + description: 'List candidates in your organization.', + input: {}, + request: () => ({ method: 'GET', path: '/candidates' }), + }, +]; diff --git a/apps/api/src/middleware/apiKey.middleware.ts b/apps/api/src/middleware/apiKey.middleware.ts new file mode 100644 index 0000000..58c644f --- /dev/null +++ b/apps/api/src/middleware/apiKey.middleware.ts @@ -0,0 +1,51 @@ +import * as Sentry from '@sentry/cloudflare'; +import { createMiddleware } from 'hono/factory'; +import { HTTPException } from 'hono/http-exception'; +import { AppContext } from '@/index'; +import { extractApiKey, verifyApiKey } from '@/lib/apiKeyAuth'; + +/** + * Auth for the public `/v1` API. Reads an API key from the `Authorization: + * Bearer ` header (or `x-api-key`), verifies it, and rebuilds the tenant + * context (`user` + `session`) from the key so downstream services keep working + * through `getSession(ctx)` unchanged. Keys only work on the public surface, + * never against the cookie-authed internal API. + */ +export const apiKeyMiddleware = createMiddleware(async (ctx, next) => { + const key = extractApiKey(ctx); + + if (!key) { + throw new HTTPException(401, { + message: 'Missing API key. Provide it as "Authorization: Bearer ".', + }); + } + + const identity = await verifyApiKey(ctx, key); + + if (!identity) { + throw new HTTPException(401, { message: 'Invalid API key' }); + } + + // Per-key rate limit via the Cloudflare Rate Limiting binding. Limit is per + // Cloudflare location and eventually consistent (see wrangler.jsonc). + const { success } = await ctx.env.API_RATE_LIMITER.limit({ key: identity.keyId }); + if (!success) { + throw new HTTPException(429, { + message: 'Rate limit exceeded. Slow down and retry shortly.', + }); + } + + // Minimal shapes: downstream services only read `user.id` and + // `session.activeOrganizationId` via getSession(). The key acts for the org; + // the acting user is the key's creator, used only for row attribution. + // @ts-expect-error partial user is sufficient for the code paths /v1 exposes + ctx.set('user', { id: identity.createdBy }); + // @ts-expect-error partial session is sufficient for getSession() + ctx.set('session', { activeOrganizationId: identity.organizationId }); + + Sentry.setUser({ id: identity.createdBy }); + Sentry.setTag('apiKeyId', identity.keyId); + Sentry.setTag('organizationId', identity.organizationId); + + return next(); +}); diff --git a/apps/api/src/middleware/auth.middleware.ts b/apps/api/src/middleware/auth.middleware.ts index a135e88..c0b14c4 100644 --- a/apps/api/src/middleware/auth.middleware.ts +++ b/apps/api/src/middleware/auth.middleware.ts @@ -4,6 +4,11 @@ import { HTTPException } from 'hono/http-exception'; import { AppContext } from '@/index'; import { useAuth } from '@/lib/auth'; +/** + * Session-cookie auth for the internal (web app) API. Programmatic access uses + * an API key against the separate public `/v1` surface (see + * apiKey.middleware.ts) so a key can never reach internal-only routes. + */ export const authMiddleware = createMiddleware(async (ctx, next) => { const auth = useAuth(ctx); const session = await auth.api.getSession({ headers: ctx.req.raw.headers }); diff --git a/apps/api/src/routes/apiKey.routes.ts b/apps/api/src/routes/apiKey.routes.ts new file mode 100644 index 0000000..d2252d0 --- /dev/null +++ b/apps/api/src/routes/apiKey.routes.ts @@ -0,0 +1,165 @@ +import { generateId, idString } from '@coderscreen/common/id'; +import { apikey } from '@coderscreen/db/apikey.db'; +import { and, desc, eq } from 'drizzle-orm'; +import { Hono } from 'hono'; +import { HTTPException } from 'hono/http-exception'; +import { describeRoute } from 'hono-openapi'; +import { resolver, validator as zValidator } from 'hono-openapi/zod'; +import { z } from 'zod'; +import { useDb } from '@/db/client'; +import { AppContext } from '@/index'; +import { generateApiKey } from '@/lib/apiKeyAuth'; +import { getSession } from '@/lib/session'; + +// Public-safe view of an API key. The secret is only ever returned once, at +// creation time. +const ApiKeySchema = z.object({ + id: z.string(), + name: z.string().nullable(), + start: z.string().nullable(), + prefix: z.string().nullable(), + enabled: z.boolean(), + requestCount: z.number(), + lastRequest: z.string().nullable(), + expiresAt: z.string().nullable(), + createdAt: z.string(), +}); + +const CreatedApiKeySchema = ApiKeySchema.extend({ + // Full plaintext key. Shown once and never retrievable again. + key: z.string(), +}); + +const toSafe = (row: typeof apikey.$inferSelect) => ({ + id: row.id, + name: row.name, + start: row.start, + prefix: row.prefix, + enabled: row.enabled, + requestCount: row.requestCount, + lastRequest: row.lastRequest ? new Date(row.lastRequest).toISOString() : null, + expiresAt: row.expiresAt ? new Date(row.expiresAt).toISOString() : null, + createdAt: new Date(row.createdAt).toISOString(), +}); + +export const apiKeyRouter = new Hono() + // GET /api-keys - List API keys for the active organization + .get( + '/', + describeRoute({ + description: 'List API keys for the active organization', + responses: { + 200: { + description: 'List of API keys', + content: { + 'application/json': { + schema: resolver(z.array(ApiKeySchema)), + }, + }, + }, + }, + }), + async (ctx) => { + const { orgId } = getSession(ctx); + const db = useDb(ctx); + + const rows = await db + .select() + .from(apikey) + .where(eq(apikey.organizationId, orgId)) + .orderBy(desc(apikey.createdAt)); + + return ctx.json(rows.map(toSafe)); + } + ) + // POST /api-keys - Create a new API key for the active organization + .post( + '/', + describeRoute({ + description: 'Create a new API key. The secret is only returned once.', + responses: { + 201: { + description: 'API key created', + content: { + 'application/json': { + schema: resolver(CreatedApiKeySchema), + }, + }, + }, + }, + }), + zValidator( + 'json', + z.object({ + name: z.string().min(1).max(100), + expiresInDays: z.number().int().positive().max(3650).optional(), + }) + ), + async (ctx) => { + const { user, orgId } = getSession(ctx); + const { name, expiresInDays } = ctx.req.valid('json'); + const db = useDb(ctx); + + const { key, keyHash, prefix, start } = await generateApiKey(); + const expiresAt = expiresInDays + ? new Date(Date.now() + expiresInDays * 24 * 60 * 60 * 1000).toISOString() + : null; + + const created = await db + .insert(apikey) + .values({ + id: generateId('apiKey'), + organizationId: orgId, + createdBy: user.id, + name, + prefix, + start, + keyHash, + expiresAt, + }) + .returning() + .then((rows) => rows[0]); + + return ctx.json( + { + ...toSafe(created), + key, + }, + 201 + ); + } + ) + // DELETE /api-keys/:id - Revoke an API key + .delete( + '/:id', + describeRoute({ + description: 'Revoke an API key', + responses: { + 200: { + description: 'API key revoked', + }, + 404: { + description: 'API key not found', + }, + }, + }), + zValidator('param', z.object({ id: idString('apiKey') })), + async (ctx) => { + const { orgId } = getSession(ctx); + const { id } = ctx.req.valid('param'); + const db = useDb(ctx); + + // Scope the delete to the active org so members can only revoke their own + // organization's keys, regardless of which member created them. + const deleted = await db + .delete(apikey) + .where(and(eq(apikey.id, id), eq(apikey.organizationId, orgId))) + .returning({ id: apikey.id }); + + if (deleted.length === 0) { + throw new HTTPException(404, { message: 'API key not found' }); + } + + return ctx.json(null, 200); + } + ); diff --git a/apps/api/src/routes/v1/index.ts b/apps/api/src/routes/v1/index.ts new file mode 100644 index 0000000..0a544fd --- /dev/null +++ b/apps/api/src/routes/v1/index.ts @@ -0,0 +1,225 @@ +import { idString } from '@coderscreen/common/id'; +import { Hono } from 'hono'; +import { describeRoute } from 'hono-openapi'; +import { resolver, validator as zValidator } from 'hono-openapi/zod'; +import { z } from 'zod'; +import { AppContext } from '@/index'; +import { PaginationQuerySchema } from '@/lib/pagination'; +import { CreateSubmissionSchema } from '@/schema/assessment.zod'; +import { + PublicAssessmentSchema, + PublicCandidateSchema, + PublicPaginationSchema, + PublicRoomSchema, + PublicSubmissionSchema, + toPublicAssessment, + toPublicCandidate, + toPublicRoom, + toPublicSubmission, +} from '@/schema/public.zod'; +import { AssessmentService } from '@/services/Assessment.service'; +import { AssessmentSubmissionService } from '@/services/AssessmentSubmission.service'; +import { RoomService } from '@/services/Room.service'; + +// Public request bodies. Kept separate from internal schemas so the external +// contract is explicit and stable. +const CreateRoomBody = z.object({ + title: z.string().min(1), + language: z.string().min(1), + notes: z.string().optional(), +}); + +/** + * Public REST API (v1). Authenticated with an organization API key via + * `apiKeyMiddleware` (mounted in index.ts). Handlers are thin: they call the + * same services the internal API uses, then map to the stable public DTOs in + * schema/public.zod.ts. Business logic lives in the services, not here. + */ +export const publicApiRouter = new Hono() + // --- Interviews (rooms) --------------------------------------------------- + .get( + '/rooms', + describeRoute({ + description: 'List interviews', + responses: { + 200: { + description: 'List of interviews', + content: { 'application/json': { schema: resolver(z.array(PublicRoomSchema)) } }, + }, + }, + }), + async (ctx) => { + const rooms = await new RoomService(ctx).listRooms(); + return ctx.json(rooms.map((r) => toPublicRoom(r, ctx.env.FE_APP_URL))); + } + ) + .post( + '/rooms', + describeRoute({ + description: 'Create an interview', + responses: { + 201: { + description: 'Interview created', + content: { 'application/json': { schema: resolver(PublicRoomSchema) } }, + }, + }, + }), + zValidator('json', CreateRoomBody), + async (ctx) => { + const body = ctx.req.valid('json'); + const room = await new RoomService(ctx).createRoom({ + title: body.title, + language: body.language as Parameters[0]['language'], + notes: body.notes ?? '', + status: 'active', + }); + return ctx.json(toPublicRoom(room, ctx.env.FE_APP_URL), 201); + } + ) + .get( + '/rooms/:id', + describeRoute({ + description: 'Get an interview by ID', + responses: { + 200: { + description: 'Interview', + content: { 'application/json': { schema: resolver(PublicRoomSchema) } }, + }, + 404: { description: 'Interview not found' }, + }, + }), + zValidator('param', z.object({ id: idString('room') })), + async (ctx) => { + const { id } = ctx.req.valid('param'); + const room = await new RoomService(ctx).getRoom(id); + if (!room) return ctx.json({ error: 'Interview not found' }, 404); + return ctx.json(toPublicRoom(room, ctx.env.FE_APP_URL)); + } + ) + // --- Assessments ---------------------------------------------------------- + .get( + '/assessments', + describeRoute({ + description: 'List assessments', + responses: { + 200: { + description: 'Paginated list of assessments', + content: { + 'application/json': { + schema: resolver( + z.object({ + data: z.array(PublicAssessmentSchema), + pagination: PublicPaginationSchema, + }) + ), + }, + }, + }, + }, + }), + zValidator('query', PaginationQuerySchema), + async (ctx) => { + const pagination = ctx.req.valid('query'); + const result = await new AssessmentService(ctx).listAssessments(pagination); + return ctx.json({ + data: result.data.map(toPublicAssessment), + pagination: result.pagination, + }); + } + ) + .get( + '/assessments/:id', + describeRoute({ + description: 'Get an assessment by ID', + responses: { + 200: { + description: 'Assessment', + content: { 'application/json': { schema: resolver(PublicAssessmentSchema) } }, + }, + 404: { description: 'Assessment not found' }, + }, + }), + zValidator('param', z.object({ id: idString('assessment') })), + async (ctx) => { + const { id } = ctx.req.valid('param'); + const assessment = await new AssessmentService(ctx).getAssessment(id); + if (!assessment) return ctx.json({ error: 'Assessment not found' }, 404); + return ctx.json(toPublicAssessment(assessment)); + } + ) + .get( + '/assessments/:id/submissions', + describeRoute({ + description: 'List submissions for an assessment', + responses: { + 200: { + description: 'List of submissions', + content: { 'application/json': { schema: resolver(z.array(PublicSubmissionSchema)) } }, + }, + }, + }), + zValidator('param', z.object({ id: idString('assessment') })), + async (ctx) => { + const { id } = ctx.req.valid('param'); + const submissions = await new AssessmentSubmissionService(ctx).listSubmissions(id); + return ctx.json(submissions.map((s) => toPublicSubmission(s, ctx.env.FE_APP_URL))); + } + ) + .post( + '/assessments/:id/invites', + describeRoute({ + description: 'Invite a candidate to an assessment. Returns the submission (with take link).', + responses: { + 201: { + description: 'Candidate invited', + content: { 'application/json': { schema: resolver(PublicSubmissionSchema) } }, + }, + }, + }), + zValidator('param', z.object({ id: idString('assessment') })), + zValidator('json', CreateSubmissionSchema), + async (ctx) => { + const { id } = ctx.req.valid('param'); + const body = ctx.req.valid('json'); + const submission = await new AssessmentSubmissionService(ctx).inviteCandidate(id, body); + return ctx.json(toPublicSubmission(submission, ctx.env.FE_APP_URL), 201); + } + ) + // --- Submissions ---------------------------------------------------------- + .get( + '/submissions/:id', + describeRoute({ + description: 'Get a submission (with results) by ID', + responses: { + 200: { + description: 'Submission details', + content: { 'application/json': { schema: resolver(PublicSubmissionSchema) } }, + }, + 404: { description: 'Submission not found' }, + }, + }), + zValidator('param', z.object({ id: idString('assessmentSubmission') })), + async (ctx) => { + const { id } = ctx.req.valid('param'); + const submission = await new AssessmentSubmissionService(ctx).getSubmissionDetails(id); + if (!submission) return ctx.json({ error: 'Submission not found' }, 404); + return ctx.json(toPublicSubmission(submission, ctx.env.FE_APP_URL)); + } + ) + // --- Candidates ----------------------------------------------------------- + .get( + '/candidates', + describeRoute({ + description: 'List candidates', + responses: { + 200: { + description: 'List of candidates', + content: { 'application/json': { schema: resolver(z.array(PublicCandidateSchema)) } }, + }, + }, + }), + async (ctx) => { + const candidates = await new AssessmentSubmissionService(ctx).listCandidates(); + return ctx.json(candidates.map(toPublicCandidate)); + } + ); diff --git a/apps/api/src/schema/public.zod.ts b/apps/api/src/schema/public.zod.ts new file mode 100644 index 0000000..4e60c7d --- /dev/null +++ b/apps/api/src/schema/public.zod.ts @@ -0,0 +1,128 @@ +import type { AssessmentEntity } from '@coderscreen/db/assessment.db'; +import type { AssessmentSubmissionEntity } from '@coderscreen/db/assessmentSubmission.db'; +import type { CandidateEntity } from '@coderscreen/db/candidate.db'; +import type { RoomEntity } from '@coderscreen/db/room.db'; +import { z } from 'zod'; + +/** + * Public API (v1) response contract. These schemas are deliberately decoupled + * from the internal DB entities: they expose only stable, documented fields + * (no org/user foreign keys, no secrets like access tokens) and map internal + * URLs into absolute links. Change internal shapes freely; only breaking + * changes here need a new API version. + */ + +// --- Interviews (rooms) ----------------------------------------------------- +export const PublicRoomSchema = z.object({ + id: z.string(), + title: z.string(), + status: z.string(), + language: z.string(), + notes: z.string(), + url: z.string(), + createdAt: z.string(), + updatedAt: z.string(), +}); +export type PublicRoom = z.infer; + +export const toPublicRoom = (room: RoomEntity, feUrl: string): PublicRoom => ({ + id: room.id, + title: room.title, + status: room.status, + language: room.language, + notes: room.notes, + url: `${feUrl}/room/${room.id}`, + createdAt: room.createdAt, + updatedAt: room.updatedAt, +}); + +// --- Assessments ------------------------------------------------------------ +export const PublicAssessmentSchema = z.object({ + id: z.string(), + title: z.string(), + description: z.string(), + mode: z.string(), + status: z.string(), + allowedLanguages: z.array(z.string()), + timeLimitSeconds: z.number().nullable(), + createdAt: z.string(), + updatedAt: z.string(), +}); +export type PublicAssessment = z.infer; + +export const toPublicAssessment = (assessment: AssessmentEntity): PublicAssessment => ({ + id: assessment.id, + title: assessment.title, + description: assessment.description, + mode: assessment.mode, + status: assessment.status, + allowedLanguages: assessment.allowedLanguages, + timeLimitSeconds: assessment.timeLimitSeconds, + createdAt: assessment.createdAt, + updatedAt: assessment.updatedAt, +}); + +// --- Candidates ------------------------------------------------------------- +export const PublicCandidateSchema = z.object({ + id: z.string(), + name: z.string(), + email: z.string(), + createdAt: z.string(), +}); +export type PublicCandidate = z.infer; + +export const toPublicCandidate = (candidate: CandidateEntity): PublicCandidate => ({ + id: candidate.id, + name: candidate.name, + email: candidate.email, + createdAt: candidate.createdAt, +}); + +// --- Submissions ------------------------------------------------------------ +export const PublicSubmissionSchema = z.object({ + id: z.string(), + assessmentId: z.string(), + status: z.string(), + candidate: PublicCandidateSchema.nullable(), + selectedLanguage: z.string().nullable(), + startedAt: z.string().nullable(), + submittedAt: z.string().nullable(), + expiresAt: z.string().nullable(), + totalScore: z.number().nullable(), + maxScore: z.number().nullable(), + // Candidate-facing link to take the assessment (embeds the access token). + takeUrl: z.string(), + // Recruiter-facing link to review results in the app. + resultsUrl: z.string(), + createdAt: z.string(), + updatedAt: z.string(), +}); +export type PublicSubmission = z.infer; + +export const toPublicSubmission = ( + submission: AssessmentSubmissionEntity & { candidate?: CandidateEntity | null }, + feUrl: string +): PublicSubmission => ({ + id: submission.id, + assessmentId: submission.assessmentId, + status: submission.status, + candidate: submission.candidate ? toPublicCandidate(submission.candidate) : null, + selectedLanguage: submission.selectedLanguage, + startedAt: submission.startedAt ?? null, + submittedAt: submission.submittedAt ?? null, + expiresAt: submission.expiresAt ?? null, + totalScore: submission.totalScore, + maxScore: submission.maxScore, + takeUrl: `${feUrl}/take/${submission.id}?token=${submission.accessToken}`, + resultsUrl: `${feUrl}/assessments/${submission.assessmentId}/submissions/${submission.id}`, + createdAt: submission.createdAt, + updatedAt: submission.updatedAt, +}); + +// Pagination envelope mirrored from lib/pagination for the public contract. +export const PublicPaginationSchema = z.object({ + page: z.number(), + limit: z.number(), + totalCount: z.number(), + totalPages: z.number(), +}); diff --git a/apps/api/worker-configuration.d.ts b/apps/api/worker-configuration.d.ts index 744b702..60cc3db 100644 --- a/apps/api/worker-configuration.d.ts +++ b/apps/api/worker-configuration.d.ts @@ -28,6 +28,7 @@ declare namespace Cloudflare { WHITEBOARD_DO: DurableObjectNamespace; ASSETS_BUCKET: R2Bucket; WHITEBOARD_ASSETS_BUCKET: R2Bucket; + API_RATE_LIMITER: RateLimit; } } interface Env extends Cloudflare.Env {} diff --git a/apps/api/wrangler.jsonc b/apps/api/wrangler.jsonc index a90f23e..066f1c2 100644 --- a/apps/api/wrangler.jsonc +++ b/apps/api/wrangler.jsonc @@ -56,8 +56,24 @@ "name": "WHITEBOARD_DO", "class_name": "WhiteboardDurableObject", }, + { + "name": "CODERSCREEN_MCP", + "class_name": "CoderScreenMcp", + }, ], }, + "ratelimits": [ + { + // Per-API-key rate limit for the public /v1 API (and the MCP server, + // which calls /v1). Limit is per Cloudflare location. Period must be 10 or 60. + "name": "API_RATE_LIMITER", + "namespace_id": "1001", + "simple": { + "limit": 120, + "period": 60, + }, + }, + ], "migrations": [ { "tag": "v1", @@ -68,6 +84,10 @@ "WhiteboardDurableObject", ], }, + { + "tag": "v2", + "new_sqlite_classes": ["CoderScreenMcp"], + }, ], "r2_buckets": [ { diff --git a/apps/web/src/components/common/Sidebar.tsx b/apps/web/src/components/common/Sidebar.tsx index b184dea..86a054a 100644 --- a/apps/web/src/components/common/Sidebar.tsx +++ b/apps/web/src/components/common/Sidebar.tsx @@ -12,6 +12,7 @@ import { RiCodeBoxLine, RiExternalLinkLine, RiFileTextLine, + RiKey2Line, RiListCheck3, RiMenuLine, RiMoneyDollarBoxLine, @@ -96,11 +97,11 @@ const MAIN_NAVIGATION: { href: siteConfig.routes.billing, icon: RiMoneyDollarBoxLine, }, - // { - // titleKey: 'API Keys', - // href: siteConfig.routes.apiKeys, - // icon: RiKey2Line, - // }, + { + titleKey: 'API', + href: siteConfig.routes.apiKeys, + icon: RiKey2Line, + }, { titleKey: 'Team', href: siteConfig.routes.team, diff --git a/apps/web/src/components/settings/ApiKeysView.tsx b/apps/web/src/components/settings/ApiKeysView.tsx new file mode 100644 index 0000000..52a5678 --- /dev/null +++ b/apps/web/src/components/settings/ApiKeysView.tsx @@ -0,0 +1,333 @@ +import { Button } from '@coderscreen/ui/button'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@coderscreen/ui/dialog'; +import { Divider } from '@coderscreen/ui/divider'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuIconWrapper, + DropdownMenuItem, + DropdownMenuTrigger, +} from '@coderscreen/ui/dropdown'; +import { SmallHeader } from '@coderscreen/ui/heading'; +import { Input } from '@coderscreen/ui/input'; +import { Label } from '@coderscreen/ui/label'; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeaderCell, + TableRoot, + TableRow, + TableSkeleton, +} from '@coderscreen/ui/table'; +import { MutedText } from '@coderscreen/ui/typography'; +import { + RiAddLine, + RiCloseLine, + RiDeleteBinLine, + RiFileCopyLine, + RiKey2Line, + RiMore2Line, +} from '@remixicon/react'; +import { useState } from 'react'; +import { toast } from 'sonner'; +import { formatDatetime } from '@/lib/dateUtils'; +import { useApiKeys, useCreateApiKey, useRevokeApiKey } from '@/query/apiKey.query'; + +type ApiKey = NonNullable['apiKeys']>[number]; + +const API_URL = (import.meta.env.VITE_API_URL as string | undefined) ?? ''; +const MCP_URL = `${API_URL}/mcp`; +const KEY_PLACEHOLDER = '{YOUR_API_KEY}'; + +// Ready-to-paste MCP client config (Cursor / VS Code / Claude style). +const buildMcpConfig = (key: string) => + JSON.stringify( + { + mcpServers: { + coderscreen: { + url: MCP_URL, + headers: { Authorization: `Bearer ${key}` }, + }, + }, + }, + null, + 2 + ); + +const copyToClipboard = async (value: string) => { + await navigator.clipboard.writeText(value); + toast.success('Copied to clipboard'); +}; + +const CodeBlock = ({ code }: { code: string }) => ( +
+
+      {code}
+    
+
+); + +export const ApiKeysView = () => { + const { apiKeys, isLoading } = useApiKeys(); + const [createOpen, setCreateOpen] = useState(false); + const [revokeKey, setRevokeKey] = useState(null); + + return ( +
+
+
+ API Keys + + Use API keys to access the CoderScreen public API on behalf of your organization. Treat + them like passwords. + +
+ +
+ + + + + + + + Name + Key + Created + Last used + Actions + + + + {isLoading ? ( + + ) : (apiKeys ?? []).length === 0 ? ( + + +
+ +
No API keys yet
+ Create your first key to start using the API. +
+
+
+ ) : ( + (apiKeys ?? []).map((key) => ( + + + {key.name ?? 'Unnamed'} + + + + {key.prefix ? `${key.prefix}_` : ''} + {key.start ?? '••••'}… + + + + {formatDatetime(key.createdAt)} + + + {key.lastRequest ? formatDatetime(key.lastRequest) : 'Never'} + + + + +
+
+ +
+ Connect via MCP + + Use CoderScreen from AI tools like Claude, Cursor, and VS Code over the Model Context + Protocol. Add the config below to your MCP client and replace the token with an API key + from above. + +
+ +
+
+ + +
+
+ + +
+
+ + + setRevokeKey(null)} /> +
+ ); +}; + +const CreateApiKeyDialog = ({ + open, + onOpenChange, +}: { + open: boolean; + onOpenChange: (open: boolean) => void; +}) => { + const { createApiKey, isLoading } = useCreateApiKey(); + const [name, setName] = useState(''); + const [createdKey, setCreatedKey] = useState(null); + + const handleClose = (nextOpen: boolean) => { + if (!nextOpen) { + setName(''); + setCreatedKey(null); + } + onOpenChange(nextOpen); + }; + + const handleCreate = async () => { + const result = await createApiKey({ name: name.trim() }); + setCreatedKey(result.key); + }; + + return ( + + + + {createdKey ? 'API key created' : 'Create API key'} + + + {createdKey ? ( +
+ + Copy your key now. For security, you will not be able to see it again. + +
+ + {createdKey} + + +
+ +
+ + Paste into your MCP client to connect AI tools right away. + +
+
+ ) : ( +
+ + setName(e.target.value)} + /> + Give the key a name so you can recognize it later. +
+ )} + + + {createdKey ? ( + + ) : ( + <> + + + + )} + +
+
+ ); +}; + +const RevokeApiKeyDialog = ({ + apiKey, + onClose, +}: { + apiKey: ApiKey | null; + onClose: () => void; +}) => { + const { revokeApiKey, isLoading } = useRevokeApiKey(); + + const handleRevoke = async () => { + if (!apiKey) return; + await revokeApiKey(apiKey.id); + onClose(); + }; + + return ( + !open && onClose()}> + + + Revoke API key + + + Are you sure you want to revoke {apiKey?.name}? Any + integration using this key will immediately stop working. This cannot be undone. + + + + + + + + ); +}; diff --git a/apps/web/src/query/apiKey.query.ts b/apps/web/src/query/apiKey.query.ts new file mode 100644 index 0000000..631a698 --- /dev/null +++ b/apps/web/src/query/apiKey.query.ts @@ -0,0 +1,82 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { throwApiError } from '@/query/error.query'; +import { apiClient } from './client'; + +const API_KEYS_QUERY_KEY = ['api-keys']; + +// List API keys for the active organization +export const useApiKeys = () => { + const query = useQuery({ + queryKey: API_KEYS_QUERY_KEY, + queryFn: async () => { + const response = await apiClient['api-keys'].$get(); + if (!response.ok) { + throw new Error('Failed to fetch API keys'); + } + return response.json(); + }, + meta: { + ERROR_MESSAGE: 'Failed to fetch API keys', + }, + }); + + return { + apiKeys: query.data, + ...query, + }; +}; + +// Create a new API key. The plaintext key is only returned here, once. +export const useCreateApiKey = () => { + const queryClient = useQueryClient(); + + const mutation = useMutation({ + mutationFn: async (data: { name: string; expiresInDays?: number }) => { + const response = await apiClient['api-keys'].$post({ json: data }); + if (!response.ok) { + await throwApiError(response); + } + return response.json(); + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: API_KEYS_QUERY_KEY }); + }, + meta: { + ERROR_MESSAGE: 'Failed to create API key', + }, + }); + + return { + createApiKey: mutation.mutateAsync, + isLoading: mutation.isPending, + ...mutation, + }; +}; + +// Revoke an API key +export const useRevokeApiKey = () => { + const queryClient = useQueryClient(); + + const mutation = useMutation({ + mutationFn: async (id: string) => { + const response = await apiClient['api-keys'][':id'].$delete({ param: { id } }); + if (!response.ok) { + await throwApiError(response); + } + return response.json(); + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: API_KEYS_QUERY_KEY }); + }, + meta: { + SUCCESS_MESSAGE: 'API key revoked', + ERROR_MESSAGE: 'Failed to revoke API key', + }, + }); + + return { + revokeApiKey: mutation.mutateAsync, + isLoading: mutation.isPending, + ...mutation, + }; +}; diff --git a/apps/web/src/routeTree.gen.ts b/apps/web/src/routeTree.gen.ts index 49d6193..1bb3840 100644 --- a/apps/web/src/routeTree.gen.ts +++ b/apps/web/src/routeTree.gen.ts @@ -29,6 +29,7 @@ import { Route as AppAssessmentsIndexRouteImport } from './routes/_app/assessmen import { Route as RoomRoomIdSummaryRouteImport } from './routes/room/$roomId/summary' import { Route as AppSettingsTeamRouteImport } from './routes/_app/settings/team' import { Route as AppSettingsBillingRouteImport } from './routes/_app/settings/billing' +import { Route as AppSettingsApiKeysRouteImport } from './routes/_app/settings/api-keys' import { Route as AppQuestionsNewRouteImport } from './routes/_app/questions/new' import { Route as AppAssessmentsAssessmentIdRouteImport } from './routes/_app/assessments/$assessmentId' import { Route as AppAssessmentsAssessmentIdIndexRouteImport } from './routes/_app/assessments/$assessmentId/index' @@ -140,6 +141,11 @@ const AppSettingsBillingRoute = AppSettingsBillingRouteImport.update({ path: '/settings/billing', getParentRoute: () => AppRoute, } as any) +const AppSettingsApiKeysRoute = AppSettingsApiKeysRouteImport.update({ + id: '/settings/api-keys', + path: '/settings/api-keys', + getParentRoute: () => AppRoute, +} as any) const AppQuestionsNewRoute = AppQuestionsNewRouteImport.update({ id: '/questions/new', path: '/questions/new', @@ -220,6 +226,7 @@ export interface FileRoutesByFullPath { '/': typeof AppIndexRoute '/assessments/$assessmentId': typeof AppAssessmentsAssessmentIdRouteWithChildren '/questions/new': typeof AppQuestionsNewRoute + '/settings/api-keys': typeof AppSettingsApiKeysRoute '/settings/billing': typeof AppSettingsBillingRoute '/settings/team': typeof AppSettingsTeamRoute '/room/$roomId/summary': typeof RoomRoomIdSummaryRoute @@ -250,6 +257,7 @@ export interface FileRoutesByTo { '/accept-invitation/$invId': typeof AcceptInvitationInvIdRoute '/': typeof AppIndexRoute '/questions/new': typeof AppQuestionsNewRoute + '/settings/api-keys': typeof AppSettingsApiKeysRoute '/settings/billing': typeof AppSettingsBillingRoute '/settings/team': typeof AppSettingsTeamRoute '/room/$roomId/summary': typeof RoomRoomIdSummaryRoute @@ -284,6 +292,7 @@ export interface FileRoutesById { '/_app/': typeof AppIndexRoute '/_app/assessments/$assessmentId': typeof AppAssessmentsAssessmentIdRouteWithChildren '/_app/questions/new': typeof AppQuestionsNewRoute + '/_app/settings/api-keys': typeof AppSettingsApiKeysRoute '/_app/settings/billing': typeof AppSettingsBillingRoute '/_app/settings/team': typeof AppSettingsTeamRoute '/room/$roomId/summary': typeof RoomRoomIdSummaryRoute @@ -318,6 +327,7 @@ export interface FileRouteTypes { | '/' | '/assessments/$assessmentId' | '/questions/new' + | '/settings/api-keys' | '/settings/billing' | '/settings/team' | '/room/$roomId/summary' @@ -348,6 +358,7 @@ export interface FileRouteTypes { | '/accept-invitation/$invId' | '/' | '/questions/new' + | '/settings/api-keys' | '/settings/billing' | '/settings/team' | '/room/$roomId/summary' @@ -381,6 +392,7 @@ export interface FileRouteTypes { | '/_app/' | '/_app/assessments/$assessmentId' | '/_app/questions/new' + | '/_app/settings/api-keys' | '/_app/settings/billing' | '/_app/settings/team' | '/room/$roomId/summary' @@ -554,6 +566,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof AppSettingsBillingRouteImport parentRoute: typeof AppRoute } + '/_app/settings/api-keys': { + id: '/_app/settings/api-keys' + path: '/settings/api-keys' + fullPath: '/settings/api-keys' + preLoaderRoute: typeof AppSettingsApiKeysRouteImport + parentRoute: typeof AppRoute + } '/_app/questions/new': { id: '/_app/questions/new' path: '/questions/new' @@ -674,6 +693,7 @@ interface AppRouteChildren { AppIndexRoute: typeof AppIndexRoute AppAssessmentsAssessmentIdRoute: typeof AppAssessmentsAssessmentIdRouteWithChildren AppQuestionsNewRoute: typeof AppQuestionsNewRoute + AppSettingsApiKeysRoute: typeof AppSettingsApiKeysRoute AppSettingsBillingRoute: typeof AppSettingsBillingRoute AppSettingsTeamRoute: typeof AppSettingsTeamRoute AppAssessmentsIndexRoute: typeof AppAssessmentsIndexRoute @@ -690,6 +710,7 @@ const AppRouteChildren: AppRouteChildren = { AppIndexRoute: AppIndexRoute, AppAssessmentsAssessmentIdRoute: AppAssessmentsAssessmentIdRouteWithChildren, AppQuestionsNewRoute: AppQuestionsNewRoute, + AppSettingsApiKeysRoute: AppSettingsApiKeysRoute, AppSettingsBillingRoute: AppSettingsBillingRoute, AppSettingsTeamRoute: AppSettingsTeamRoute, AppAssessmentsIndexRoute: AppAssessmentsIndexRoute, diff --git a/apps/web/src/routes/_app/settings/api-keys.tsx b/apps/web/src/routes/_app/settings/api-keys.tsx new file mode 100644 index 0000000..a424470 --- /dev/null +++ b/apps/web/src/routes/_app/settings/api-keys.tsx @@ -0,0 +1,10 @@ +import { createFileRoute } from '@tanstack/react-router'; +import { ApiKeysView } from '@/components/settings/ApiKeysView'; + +export const Route = createFileRoute('/_app/settings/api-keys')({ + component: RouteComponent, +}); + +function RouteComponent() { + return ; +} diff --git a/packages/common/src/id.ts b/packages/common/src/id.ts index e7ab6c9..3c5436b 100644 --- a/packages/common/src/id.ts +++ b/packages/common/src/id.ts @@ -22,6 +22,7 @@ export const Entities = { testCaseResult: 'tcr', questionLibrary: 'ql', questionLibraryTestCase: 'qltc', + apiKey: 'apik', } as const; type Entities = typeof Entities; diff --git a/packages/db/src/apikey.db.ts b/packages/db/src/apikey.db.ts new file mode 100644 index 0000000..f2a5a41 --- /dev/null +++ b/packages/db/src/apikey.db.ts @@ -0,0 +1,45 @@ +import type { Id } from '@coderscreen/common/id'; +import { sql } from 'drizzle-orm'; +import { boolean, index, integer, pgTable, text, timestamp } from 'drizzle-orm/pg-core'; +import { organization, user } from './user.db'; + +// API keys for the public `/v1` API, owned by us (not the better-auth apiKey +// plugin). The org a key acts on behalf of is a real, indexed column so it can +// be filtered directly. Only the SHA-256 hash of the key is stored; the plaintext +// is shown once at creation time and never persisted. +export const apikey = pgTable( + 'apikey', + { + id: text('id').primaryKey().$type>(), + createdAt: timestamp('created_at', { mode: 'string', withTimezone: true }) + .default(sql`now()`) + .notNull(), + updatedAt: timestamp('updated_at', { mode: 'string', withTimezone: true }) + .default(sql`now()`) + .notNull(), + organizationId: text('organization_id') + .notNull() + .references(() => organization.id, { onDelete: 'cascade' }), + // The member who created the key. Attribution only - the key acts for the + // organization, not this user. Requests made with the key are attributed to + // this user (e.g. as the creator of rooms opened via the API). + createdBy: text('created_by') + .notNull() + .references(() => user.id, { onDelete: 'cascade' }), + name: text('name'), + // e.g. "cs" - the human-readable prefix on the plaintext key. + prefix: text('prefix'), + // First few chars of the plaintext key, for display in the UI (e.g. "cs_ab12"). + start: text('start'), + // SHA-256 hex digest of the full plaintext key. Lookups hash the incoming + // key and match against this. + keyHash: text('key_hash').notNull().unique(), + enabled: boolean('enabled').default(true).notNull(), + requestCount: integer('request_count').default(0).notNull(), + lastRequest: timestamp('last_request', { mode: 'string', withTimezone: true }), + expiresAt: timestamp('expires_at', { mode: 'string', withTimezone: true }), + }, + (t) => [index('idx_apikey_org').on(t.organizationId)] +); + +export type ApiKeyEntity = typeof apikey.$inferSelect; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b3bacd9..d64e512 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,10 +34,13 @@ importers: version: link:../../packages/email '@daytonaio/sdk': specifier: 0.21.1 - version: 0.21.1(@babel/core@7.28.0)(typescript@5.8.3) + version: 0.21.1(typescript@5.8.3) '@hono/zod-validator': specifier: ^0.7.0 version: 0.7.2(hono@4.8.9)(zod@3.25.76) + '@modelcontextprotocol/sdk': + specifier: ^1.29.0 + version: 1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) '@sentry/cloudflare': specifier: 10.65.0 version: 10.65.0(@cloudflare/workers-types@4.20250726.0)(@opentelemetry/core@2.9.0(@opentelemetry/api@1.9.1)) @@ -47,6 +50,9 @@ importers: '@tldraw/tlschema': specifier: ^3.14.0 version: 3.14.2(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + agents: + specifier: ^0.19.0 + version: 0.19.0(@babel/runtime@7.28.2)(@cloudflare/workers-types@4.20250726.0)(react@19.2.1)(rolldown@1.2.0)(vite@6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0))(zod@3.25.76) better-auth: specifier: ^1.2.10 version: 1.3.4(react-dom@19.2.1(react@19.2.1))(react@19.2.1) @@ -104,7 +110,7 @@ importers: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.8.36 - version: 0.8.57(@cloudflare/workers-types@4.20250726.0)(@vitest/runner@3.0.9)(@vitest/snapshot@3.0.9)(vitest@3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 0.8.57(@cloudflare/workers-types@4.20250726.0)(@vitest/runner@3.0.9)(@vitest/snapshot@3.0.9)(vitest@3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0)) '@types/lodash.throttle': specifier: ^4.1.9 version: 4.1.9 @@ -119,7 +125,7 @@ importers: version: 5.8.3 vitest: specifier: ~3.0.9 - version: 3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) wrangler: specifier: ^4.67.0 version: 4.67.0(@cloudflare/workers-types@4.20250726.0) @@ -219,7 +225,7 @@ importers: version: 0.7.5(@xterm/xterm@6.0.0) '@cloudflare/vite-plugin': specifier: ^1.7.5 - version: 1.10.1(rollup@4.46.0)(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0))(workerd@1.20250712.0)(wrangler@4.26.0(@cloudflare/workers-types@4.20250726.0)) + version: 1.10.1(rollup@4.46.0)(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0))(workerd@1.20250712.0)(wrangler@4.26.0(@cloudflare/workers-types@4.20250726.0)) '@codemirror/commands': specifier: ^6.8.1 version: 6.8.1 @@ -354,7 +360,7 @@ importers: version: 4.1.11 '@tailwindcss/vite': specifier: ^4.1.17 - version: 4.1.17(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 4.1.17(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0)) '@tanstack/react-form': specifier: ^1.12.4 version: 1.15.0(react-dom@19.2.1(react@19.2.1))(react@19.2.1) @@ -369,7 +375,7 @@ importers: version: 1.130.1(@tanstack/react-router@1.130.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(@tanstack/router-core@1.130.1)(csstype@3.1.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(solid-js@1.9.7)(tiny-invariant@1.3.3) '@tanstack/router-plugin': specifier: ^1.121.2 - version: 1.130.1(@tanstack/react-router@1.130.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 1.130.1(@tanstack/react-router@1.130.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0)) '@tanstack/zod-adapter': specifier: ^1.127.3 version: 1.130.1(@tanstack/react-router@1.130.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(zod@3.25.76) @@ -550,7 +556,7 @@ importers: version: 15.5.13 '@vitejs/plugin-react': specifier: ^4.3.4 - version: 4.7.0(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 4.7.0(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0)) jsdom: specifier: ^26.0.0 version: 26.1.0 @@ -559,10 +565,10 @@ importers: version: 5.8.3 vite: specifier: ^7.2.6 - version: 7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + version: 7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) vitest: specifier: ^3.0.5 - version: 3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) web-vitals: specifier: ^4.2.4 version: 4.2.4 @@ -920,6 +926,10 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} + '@babel/code-frame@8.0.0': + resolution: {integrity: sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/compat-data@7.28.0': resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} engines: {node: '>=6.9.0'} @@ -932,10 +942,18 @@ packages: resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} engines: {node: '>=6.9.0'} + '@babel/generator@8.0.0': + resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@8.0.0': + resolution: {integrity: sha512-NSpMkMsvvZqzThJ0p1B02cbtA2ObEyfBvq950bmNkyxsxvcxwhvvCB036rKhlEnuBBo30bOrk13u3FzlKSoRrw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-compilation-targets@7.27.2': resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} @@ -946,6 +964,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-create-class-features-plugin@8.0.1': + resolution: {integrity: sha512-++t3ZktzlLmASAxIlxeXQK9Z2YwUafYGYcvGBFevqOqt16HozVHStUoQvWD09fzAZOb/uJGpUTBuGK41AJAuOA==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/helper-create-regexp-features-plugin@7.27.1': resolution: {integrity: sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==} engines: {node: '>=6.9.0'} @@ -961,10 +985,18 @@ packages: resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} + '@babel/helper-globals@8.0.0': + resolution: {integrity: sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-member-expression-to-functions@7.27.1': resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@8.0.0': + resolution: {integrity: sha512-xkXrMbtk87Gk7+oKBVmBc6EORg/Qwx++AHESldmHkpvG8wgccdhJJFwrzqlF382Fk8wfXhJHWE/g/43QvEGNPQ==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-module-imports@7.27.1': resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} @@ -979,10 +1011,20 @@ packages: resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} + '@babel/helper-optimise-call-expression@8.0.0': + resolution: {integrity: sha512-3W6satvtPuCUkUx63S2jMoW9EQNYkADgs1HTfufmL7gCmAulHMKupA/12WNz4A0GMMFn/YnWWwqOT9IZrJHQjg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-plugin-utils@7.27.1': resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@8.0.1': + resolution: {integrity: sha512-3PKFgjTyPlhFhorfP+SjKQxLViIL++zWjFOO4hGriYU+Bsm983DxEM1JmDRJVWXV0O9npu+xXRqz7Pbd3mh70g==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/helper-remap-async-to-generator@7.27.1': resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} engines: {node: '>=6.9.0'} @@ -995,18 +1037,36 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-replace-supers@8.0.1': + resolution: {integrity: sha512-B1SZADIcy3tmH8CmWvj4SHi/oAPom4UL3uknTc2QRNsPVLFk/sPnZvQL/8kj7Y5omvjMqie0vklvs6XM4OLW5Q==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} engines: {node: '>=6.9.0'} + '@babel/helper-skip-transparent-expression-wrappers@8.0.0': + resolution: {integrity: sha512-xmCA9kP3IhySsqhzwIdWGlDN/1A4cCKNBO/uwZx/3YzmDoMePwno2Q5/Bq0q+tYaKbeF940YiKV/kaW8Mzvpjw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@8.0.0': + resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-validator-identifier@7.27.1': resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@8.0.4': + resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} @@ -1024,6 +1084,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@8.0.4': + resolution: {integrity: sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==} + engines: {node: ^22.18.0 || >=24.11.0} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1': resolution: {integrity: sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==} engines: {node: '>=6.9.0'} @@ -1054,12 +1119,24 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/plugin-proposal-decorators@8.0.2': + resolution: {integrity: sha512-+C6O6KKXU7BBq1GNaIkFJxrALUVGRcr+WeWm4OcuRl3h+l/CmNfcTLMrT2Lm3uvGBimBH/8pEBRrXJFLoO67Gg==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-decorators@8.0.1': + resolution: {integrity: sha512-NI+0S/6MvR6GlcQFwjDZ+WIc2qvG6TXN534lYs9llNldwW4b7Dh6KTtk030FA0xWdYGs4t1lWo+OEWN8wGB+Nw==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/plugin-syntax-import-assertions@7.27.1': resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} engines: {node: '>=6.9.0'} @@ -1425,6 +1502,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/runtime-corejs3@7.29.7': + resolution: {integrity: sha512-ppj9ouYku+RX0ljtgZd+KMO5mkM2bCqg8H2PYAFWnLsHEIKIdRojqbJ2i3eVHrisuxy7nOFCmngTDdWtUCdXUQ==} + engines: {node: '>=6.9.0'} + '@babel/runtime@7.28.2': resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==} engines: {node: '>=6.9.0'} @@ -1433,14 +1514,26 @@ packages: resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} + '@babel/template@8.0.0': + resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/traverse@7.28.0': resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} engines: {node: '>=6.9.0'} + '@babel/traverse@8.0.4': + resolution: {integrity: sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/types@7.28.2': resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} engines: {node: '>=6.9.0'} + '@babel/types@8.0.4': + resolution: {integrity: sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==} + engines: {node: ^22.18.0 || >=24.11.0} + '@better-auth/utils@0.2.5': resolution: {integrity: sha512-uI2+/8h/zVsH8RrYdG8eUErbuGBk16rZKQfz8CjxQOyCE6v7BqFYEbFwvOkvl1KbUdxhqOnXp78+uE5h8qVEgQ==} @@ -1500,6 +1593,26 @@ packages: cpu: [x64] os: [win32] + '@cfworker/json-schema@4.1.1': + resolution: {integrity: sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==} + + '@cloudflare/codemode@0.5.0': + resolution: {integrity: sha512-DS3S/azE4XOCZRJz/slpBo4kFAkdoz303FYDgDSRCJXpnLyDEq+qj9WDceZPBWI7HK0olgOEyLeo/jQy6IKkvQ==} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.25.0 + '@tanstack/ai': '>=0.8.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + '@tanstack/ai': + optional: true + ai: + optional: true + zod: + optional: true + '@cloudflare/containers@0.0.30': resolution: {integrity: sha512-i148xBgmyn/pje82ZIyuTr/Ae0BT/YWwa1/GTJcw6DxEjUHAzZLaBCiX446U9OeuJ2rBh/L/9FIzxX5iYNt1AQ==} @@ -1763,9 +1876,15 @@ packages: peerDependencies: '@noble/ciphers': ^1.0.0 + '@emnapi/core@1.11.2': + resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} + '@emnapi/core@1.4.5': resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} + '@emnapi/runtime@1.11.2': + resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} + '@emnapi/runtime@1.4.5': resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} @@ -1775,6 +1894,9 @@ packages: '@emnapi/wasi-threads@1.0.4': resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@esbuild-kit/core-utils@3.3.2': resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} deprecated: 'Merged into tsx: https://tsx.is' @@ -1807,6 +1929,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.18.20': resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -1837,6 +1965,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.18.20': resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -1867,6 +2001,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -1897,6 +2037,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -1927,6 +2073,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -1957,6 +2109,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -1987,6 +2145,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -2017,6 +2181,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -2047,6 +2217,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -2077,6 +2253,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -2107,6 +2289,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -2137,6 +2325,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -2167,6 +2361,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -2197,6 +2397,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -2227,6 +2433,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -2257,6 +2469,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -2287,6 +2505,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.4': resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} engines: {node: '>=18'} @@ -2305,6 +2529,12 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -2335,6 +2565,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.4': resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} engines: {node: '>=18'} @@ -2353,6 +2589,12 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -2383,6 +2625,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.8': resolution: {integrity: sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==} engines: {node: '>=18'} @@ -2395,6 +2643,12 @@ packages: cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -2425,6 +2679,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.18.20': resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -2455,6 +2715,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -2485,6 +2751,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -2515,6 +2787,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.7.0': resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2597,6 +2875,12 @@ packages: '@hexagon/base64@1.1.28': resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} + '@hono/node-server@1.19.15': + resolution: {integrity: sha512-Za2ai6TLdKjUvnur+eenO6nuYYipVAEhyCAdaV8IRvmU9kK8crOZUSYvIXn72E4f8fJqyAbpcJuTsYYmZp9Deg==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + '@hono/zod-validator@0.7.2': resolution: {integrity: sha512-ub5eL/NeZ4eLZawu78JpW/J+dugDAYhwqUIdp9KYScI6PZECij4Hx4UsrthlEUutqDDhPwRI0MscUfNkvn/mqQ==} peerDependencies: @@ -3114,6 +3398,16 @@ packages: '@mjackson/node-fetch-server@0.6.1': resolution: {integrity: sha512-9ZJnk/DJjt805uv5PPv11haJIW+HHf3YEEyVXv+8iLQxLD/iXA68FH220XoiTPBC4gCg5q+IMadDw8qPqlA5wg==} + '@modelcontextprotocol/sdk@1.29.0': + resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + '@msgpack/msgpack@3.1.3': resolution: {integrity: sha512-47XIizs9XZXvuJgoaJUIE2lFoID8ugvc0jzSHP+Ptfk8nTbnR8g788wv48N03Kx0UkAv559HWRQ3yzOgzlRNUA==} engines: {node: '>= 18'} @@ -3124,6 +3418,12 @@ packages: '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@next/env@15.4.8': resolution: {integrity: sha512-LydLa2MDI1NMrOFSkO54mTc8iIHSttj6R6dthITky9ylXV2gCGi0bHQjVCtLGRshdRPjyh2kXbxJukDtBWQZtQ==} @@ -3312,6 +3612,9 @@ packages: resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} engines: {node: '>=14'} + '@oxc-project/types@0.140.0': + resolution: {integrity: sha512-h5LUOzGArYemnW1NMz/DuuQhBi96J6JL2Bk8zE4kvqxB5Sg3jxmCiH4uyOWHDkiKSt5vWlG4FIwCR/DbstcNRQ==} + '@peculiar/asn1-android@2.4.0': resolution: {integrity: sha512-YFueREq97CLslZZBI8dKzis7jMfEHSLxM+nr0Zdx1POiXFLjqqwoY5s0F1UimdBiEw/iKlHey2m56MRDv7Jtyg==} @@ -4184,9 +4487,118 @@ packages: peerDependencies: react: '>=18.2.0' + '@rolldown/binding-android-arm64@1.2.0': + resolution: {integrity: sha512-9yB1l95IrJuNGDFdOYe79vdApdz6WWBCObE+rQ2LUliYUlcyFwSYIb2xb5/Ifw7dAtMy2ZqNyd8QTSOc7duAKw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.0': + resolution: {integrity: sha512-pexNaW9ACLUOaBITOpU6qVu4VrsOFIjTv6bzgu0YUATo4eUJx0V605PxwZfndpPOn0ilqGqvGQ0M8UW0IE24jg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.0': + resolution: {integrity: sha512-NqKYaq0355ZmNMG4QGpxtEDxsc7tGDhjhCm4PpE0cwnBW+5Il95LJyq414niEiaKLVjnVHBEjSo1wngKxJNiFw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.0': + resolution: {integrity: sha512-3vPoHzh6eBTz9IbB0/qZdSr0Qeks2echn+I4cHu2joV74VriPDdldswksEDzrl1mBB+oPRi+67+3Ib59paxIPQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.0': + resolution: {integrity: sha512-E6NNefZ1bUVmKJq2tJkf45J4Zyczj7qm9rUT7NY+Xo2474Y13qWAwc2tvBt0BAVbmtXR1llkxXg0Ou1jbDf2SQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.0': + resolution: {integrity: sha512-D+TgkdgM1vu+7/Fpf8+v0ARW+RXEP9Ccazgm8zQ4JFFd9Q7SrYQ2TakU5S5ihazQDgpKyAgZDOcIFsvoHmTZ8w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-musl@1.2.0': + resolution: {integrity: sha512-wUqdwJBbAv0APN87GecstdMUtLjjNTs0hBALpxETD73mccFxdmt/XeizXDtN5RAlBwNKmI+Tg+blect2G+8IeQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-ppc64-gnu@1.2.0': + resolution: {integrity: sha512-9DtF35qR9/NrfhM4oxLplCzVVjE+KKm8Pjemi0i/sdhAWkUasjmSo8WTTubNJClhSHCfyk2yeyoXDQEDPtDAAw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + + '@rolldown/binding-linux-s390x-gnu@1.2.0': + resolution: {integrity: sha512-RzuHrBh8X8Hntd2N4VR02QGEciq/9JhcZoTpR/Cee6otRrlILGCf3cg2ygHuih+ZebUnWmMrDX6ITI85btO6rQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@1.2.0': + resolution: {integrity: sha512-MK7L0018jjh1jR3mh21G2j1zAVcpscJBlPo2z19pRjv2XOYGRhaV4LyiD8HO6nCDdZln9IFgCMIV5yt4E3klGQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@1.2.0': + resolution: {integrity: sha512-gyrxLQ9NfGb/9LoVnC4kb9miUghw1mghnkfYvNHSnVIXriabnfgGPUP4RLcJm87q3KgYz4FYUG8IDiWUT+CpSw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-openharmony-arm64@1.2.0': + resolution: {integrity: sha512-/6VFMQGRmrhP77KXDC+StIxGzcNp5JOIyYtw0CQ8gPlzhpiIRucYfoM5FaFamHd5BJYIdH86yfP46l1p3WdrFA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.2.0': + resolution: {integrity: sha512-rwdbUL465kisF24WEJLvP3JrEG6E5GRuIHt5wpMwHGERtHe4Wm2CIvtf5gTBgr2tGOHKh5NdKEAFS2VkOPE91g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.2.0': + resolution: {integrity: sha512-+5suHwRiKGmhwyUaNT8a5QbrBvLFh2DbO910TEmGRH1aSxwrCezodvGQnulv4uiWEIv1Kq4ypRsJ5+O+ry1DiA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.0': + resolution: {integrity: sha512-WfFv6/qGufotqBSBzBYwgpCkJBk8Nj7697LL9vTz/XWc67e0r3oewu8iMRwQj3AUL45GVD7wVsPjCsAAtW66Wg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/plugin-babel@0.2.3': + resolution: {integrity: sha512-+zEk16yGlz1F9STiRr6uG9hmIXb6nprjLczV/htGptYuLoCuxb+itZ03RKCEeOhBpDDd1NU7qF6x1VLMUp62bw==} + engines: {node: '>=22.12.0 || ^24.0.0'} + peerDependencies: + '@babel/core': ^7.29.0 || ^8.0.0-rc.1 + '@babel/plugin-transform-runtime': ^7.29.0 || ^8.0.0-rc.1 + '@babel/runtime': ^7.27.0 || ^8.0.0-rc.1 + rolldown: ^1.0.0-rc.5 + vite: ^8.0.0 + peerDependenciesMeta: + '@babel/plugin-transform-runtime': + optional: true + '@babel/runtime': + optional: true + vite: + optional: true + '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + '@rollup/plugin-replace@6.0.2': resolution: {integrity: sha512-7QaYCf8bqF04dOy7w/eHmJeNExxTYwvKAmlSAH/EaWWUzbT0h5sbF6bktFoX/0F/0qwng5/dWFMyf3gzaM8DsQ==} engines: {node: '>=14.0.0'} @@ -5155,6 +5567,9 @@ packages: '@tybys/wasm-util@0.10.0': resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} @@ -5223,6 +5638,9 @@ packages: peerDependencies: '@types/react': '*' + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -5515,6 +5933,10 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -5538,6 +5960,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -5553,9 +5980,52 @@ packages: react-dom: optional: true + agents@0.19.0: + resolution: {integrity: sha512-0/4p1eDRRI9PfOzZgpAH3OUQASkKGStqie9HN7KXji91dHnH+81UerYcPsMqFXqwB8qRi8onrvkoV8FL3RJ5tQ==} + hasBin: true + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@tanstack/ai': '>=0.10.2 <1.0.0' + '@x402/core': ^2.0.0 + '@x402/evm': ^2.0.0 + ai: ^6.0.0 || ^7.0.0 + chat: ^4.29.0 + just-bash: ^3.0.0 + react: ^19.0.0 + vite: '>=6.0.0 <9.0.0' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@tanstack/ai': + optional: true + '@x402/core': + optional: true + '@x402/evm': + optional: true + ai: + optional: true + chat: + optional: true + just-bash: + optional: true + vite: + optional: true + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -5564,6 +6034,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -5572,6 +6046,10 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + ansis@4.1.0: resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} engines: {node: '>=14'} @@ -5741,6 +6219,10 @@ packages: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + body-parser@2.3.0: + resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} + engines: {node: '>=18'} + bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} @@ -5879,6 +6361,10 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} @@ -5949,10 +6435,18 @@ packages: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} + content-disposition@1.1.0: + resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + engines: {node: '>=18'} + content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + content-type@2.0.0: + resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} + engines: {node: '>=18'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -5962,6 +6456,10 @@ packages: cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + cookie@0.7.1: resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} @@ -5977,15 +6475,26 @@ packages: core-js-compat@3.44.0: resolution: {integrity: sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==} + core-js-pure@3.49.0: + resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==} + core-js@3.44.0: resolution: {integrity: sha512-aFCtd4l6GvAXwVEh3XbbVqJGHDJt0OZRa+5ePGx3LLwi12WfexqQxcsohb2wgsa/92xtl19Hd66G/L+TaAxDMw==} core-js@3.49.0: resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==} + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + crelt@1.0.6: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + cron-schedule@6.0.0: + resolution: {integrity: sha512-BoZaseYGXOo5j5HUwTaegIog3JJbuH4BbrY9A1ArLjXpy+RWb3mV28F/9Gv1dDA7E2L8kngWva4NWisnLTyfgQ==} + engines: {node: '>=20'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -6102,6 +6611,15 @@ packages: supports-color: optional: true + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decimal.js-light@2.5.1: resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} @@ -6331,6 +6849,9 @@ packages: electron-to-chromium@1.5.191: resolution: {integrity: sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==} + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -6445,6 +6966,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -6631,6 +7157,14 @@ packages: resolution: {integrity: sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==} engines: {node: '>=14.18'} + eventsource-parser@3.1.0: + resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -6647,10 +7181,20 @@ packages: resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} engines: {node: '>=12.0.0'} + express-rate-limit@8.6.0: + resolution: {integrity: sha512-XKJXDsASUOo0LLtFwW5hCcQGH0N4WQc/Rn8/Pvoia+TJFOkkFPvrtW9lZOeeNcxQJspvOIERMwiRLsVFlhHEkA==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + express@4.21.2: resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} engines: {node: '>= 0.10.0'} + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + exsolve@1.0.7: resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} @@ -6685,6 +7229,9 @@ packages: fast-sha256@1.3.0: resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} + fast-uri@3.1.4: + resolution: {integrity: sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==} + fast-xml-parser@5.2.5: resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} hasBin: true @@ -6731,6 +7278,10 @@ packages: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -6792,6 +7343,10 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + front-matter@4.0.2: resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} @@ -6825,6 +7380,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + engines: {node: '>=18'} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -7014,6 +7573,10 @@ packages: hono: ^4.6.17 partyserver: ^0.0.72 + hono@4.12.32: + resolution: {integrity: sha512-XcuyW9qE2kJn07PkecMOBd5Vq/hMy7mmGw+idz1yblbg9N17ijJODrvPkn7/dwL3Kulj8LcRJ69DLOWf91dRUg==} + engines: {node: '>=16.9.0'} + hono@4.8.9: resolution: {integrity: sha512-ERIxkXMRhUxGV7nS/Af52+j2KL60B1eg+k6cPtgzrGughS+espS9KQ7QO0SMnevtmRlBfAcN0mf1jKtO6j/doA==} engines: {node: '>=16.9.0'} @@ -7032,6 +7595,10 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -7056,6 +7623,10 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} + engines: {node: '>=0.10.0'} + idb@7.1.1: resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} @@ -7099,6 +7670,10 @@ packages: intl-messageformat@10.7.16: resolution: {integrity: sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==} + ip-address@10.3.1: + resolution: {integrity: sha512-1e9d3kb97NHJTIJDZW9rKqW2h6+dFa50Dy0fpPSMQp2ADje5gvKsXmdiK6dwY5t76TaTt5+P5N1Y/LoToIxP6g==} + engines: {node: '>= 12'} + ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -7239,6 +7814,9 @@ packages: is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -7335,6 +7913,15 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + jose@6.2.4: + resolution: {integrity: sha512-N8acGzVsQy6M/fjFcxtysNc4Q379TcM5dM/qKkNtsHFji88yANnXTr7BLeP75iPnFwBfQzM/jg2BZ9+HZrHCZA==} + + js-base64@3.9.1: + resolution: {integrity: sha512-U73qptcvf/HIOauFOmqT3a0mDUp0MYlfd15oqoe9kqZt5XhiXVb+HG09sLvI9PQ9tZIBFS4nlErai8zbWazP0g==} + + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -7371,6 +7958,12 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + json-schema-walker@2.0.0: resolution: {integrity: sha512-nXN2cMky0Iw7Af28w061hmxaPDaML5/bQD9nwm1lOoIKEGjHcRGxqWe4MfrkYThYAPjSUhmsp4bJNoLAyVn9Xw==} engines: {node: '>=10'} @@ -7704,9 +8297,17 @@ packages: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} + media-typer@1.1.1: + resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} + engines: {node: '>= 0.8'} + merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -7843,6 +8444,10 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -7853,6 +8458,9 @@ packages: engines: {node: '>=10.0.0'} hasBin: true + mimetext@3.0.28: + resolution: {integrity: sha512-eQXpbNrtxLCjUtiVbR/qR09dbPgZ2o+KR1uA7QKqGhbn8QV7HIL16mXXsobBL4/8TqoYh1us31kfz+dNfCev9g==} + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -7973,6 +8581,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@5.1.16: + resolution: {integrity: sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==} + engines: {node: ^18 || >=20} + hasBin: true + nanoid@5.1.5: resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} engines: {node: ^18 || >=20} @@ -7998,6 +8611,10 @@ packages: resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} engines: {node: '>= 0.6'} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + next-mdx-remote@6.0.0: resolution: {integrity: sha512-cJEpEZlgD6xGjB4jL8BnI8FaYdN9BzZM4NwadPe1YQr7pqoWjg9EBCMv3nXBkuHqMRfv2y33SzUsuyNh9LFAQQ==} engines: {node: '>=14', npm: '>=7'} @@ -8095,6 +8712,10 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + obug@2.1.4: + resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} + engines: {node: '>=12.20.0'} + ohash@1.1.6: resolution: {integrity: sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg==} @@ -8192,9 +8813,22 @@ packages: peerDependencies: '@cloudflare/workers-types': ^4.20240729.0 + partyserver@0.5.8: + resolution: {integrity: sha512-htgSwiBcBu9zIYLrsxBAOvdkjukHvncbTk0nDrJgfruvZ08rxtEN1Ab4T7j9osykP80Bq3zA2oWFd3ngc4Z9uw==} + peerDependencies: + '@cloudflare/workers-types': ^4.20260424.1 + partysocket@1.1.4: resolution: {integrity: sha512-jXP7PFj2h5/v4UjDS8P7MZy6NJUQ7sspiFyxL4uc/+oKOL+KdtXzHnTV8INPGxBrLTXgalyG3kd12Qm7WrYc3A==} + partysocket@1.3.0: + resolution: {integrity: sha512-1zToNyolZFK/7nuAw/K2bZrNzFqaZyRoCEkS+9vG6WSC5ikrN6qWRe96q6ImU51uptz2r+dAwSkwhJVdQi4LiA==} + peerDependencies: + react: '>=17' + peerDependenciesMeta: + react: + optional: true + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -8216,6 +8850,9 @@ packages: path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -8237,6 +8874,14 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} @@ -8399,6 +9044,10 @@ packages: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} + qs@6.15.3: + resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} + engines: {node: '>=0.6'} + query-selector-shadow-dom@1.0.1: resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} @@ -8426,6 +9075,10 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + react-cookie@8.0.1: resolution: {integrity: sha512-QNdAd0MLuAiDiLcDU/2s/eyKmmfMHtjPUKJ2dZ/5CcQ9QKUium4B3o61/haq6PQl/YWFqC5PO8GvxeHKhy3GFA==} peerDependencies: @@ -8628,6 +9281,10 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + require-in-the-middle@8.0.1: resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==} engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'} @@ -8672,6 +9329,11 @@ packages: robot3@0.4.1: resolution: {integrity: sha512-hzjy826lrxzx8eRgv80idkf8ua1JAepRc9Efdtj03N3KNJuznQCPlyCJ7gnUmDFwZCLQjxy567mQVKmdv2BsXQ==} + rolldown@1.2.0: + resolution: {integrity: sha512-u7tgm5l4Yw1iTqUL4EcYOAt7fFvCgQMLeidrnD4GALlC6aOznCjezYajgxeyKw27u0Q5N7fwgCzjVyPIWzwuBA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup@4.46.0: resolution: {integrity: sha512-ONmkT3Ud3IfW15nl7l4qAZko5/2iZ5ALVBDh02ZSZ5IGVLJSYkRcRa3iB58VyEIyoofs9m2xdVrm+lTi97+3pw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -8683,6 +9345,10 @@ packages: rou3@0.5.1: resolution: {integrity: sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==} + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} @@ -8745,6 +9411,10 @@ packages: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + seroval-plugins@1.3.2: resolution: {integrity: sha512-0QvCV2lM3aj/U3YozDiVwx9zpH0q8A60CTWIv4Jszj/givcudPb48B+rkU5D51NJ0pTpweGMttHjboPa9/zoIQ==} engines: {node: '>=10'} @@ -8759,6 +9429,10 @@ packages: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + set-cookie-parser@2.7.1: resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} @@ -8805,6 +9479,10 @@ packages: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + side-channel-map@1.0.1: resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} engines: {node: '>= 0.4'} @@ -8817,6 +9495,10 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -8879,6 +9561,10 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} @@ -8897,6 +9583,10 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + string.prototype.includes@2.0.1: resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} engines: {node: '>= 0.4'} @@ -8930,6 +9620,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + strip-bom-string@1.0.0: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} @@ -9158,6 +9852,10 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -9595,6 +10293,10 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -9698,14 +10400,27 @@ packages: engines: {node: '>= 14.6'} hasBin: true + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yargs@18.0.0: + resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yjs@13.6.27: resolution: {integrity: sha512-OIDwaflOaq4wC6YlPBy2L6ceKeKuF7DeTxx+jPzv1FHn9tCZ0ZwSRnUBxD05E3yed46fv/FWJbvR+Ud7x0L7zw==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} @@ -9732,6 +10447,11 @@ packages: peerDependencies: zod: ^3.21.4 + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + zod@3.22.3: resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} @@ -10274,6 +10994,11 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@8.0.0': + dependencies: + '@babel/helper-validator-identifier': 8.0.4 + js-tokens: 10.0.0 + '@babel/compat-data@7.28.0': {} '@babel/core@7.28.0': @@ -10304,10 +11029,23 @@ snapshots: '@jridgewell/trace-mapping': 0.3.29 jsesc: 3.1.0 + '@babel/generator@8.0.0': + dependencies: + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': dependencies: '@babel/types': 7.28.2 + '@babel/helper-annotate-as-pure@8.0.0': + dependencies: + '@babel/types': 8.0.4 + '@babel/helper-compilation-targets@7.27.2': dependencies: '@babel/compat-data': 7.28.0 @@ -10329,16 +11067,24 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.0)': + '@babel/helper-create-class-features-plugin@8.0.1': + dependencies: + '@babel/helper-annotate-as-pure': 8.0.0 + '@babel/helper-member-expression-to-functions': 8.0.0 + '@babel/helper-optimise-call-expression': 8.0.0 + '@babel/helper-replace-supers': 8.0.1 + '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 + '@babel/traverse': 8.0.4 + semver: 7.7.4 + + '@babel/helper-create-regexp-features-plugin@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-annotate-as-pure': 7.27.3 regexpu-core: 6.2.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.0)': + '@babel/helper-define-polyfill-provider@0.6.5': dependencies: - '@babel/core': 7.28.0 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 debug: 4.4.1 @@ -10349,6 +11095,8 @@ snapshots: '@babel/helper-globals@7.28.0': {} + '@babel/helper-globals@8.0.0': {} + '@babel/helper-member-expression-to-functions@7.27.1': dependencies: '@babel/traverse': 7.28.0 @@ -10356,6 +11104,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-member-expression-to-functions@8.0.0': + dependencies: + '@babel/traverse': 8.0.4 + '@babel/types': 8.0.4 + '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.28.0 @@ -10376,11 +11129,16 @@ snapshots: dependencies: '@babel/types': 7.28.2 + '@babel/helper-optimise-call-expression@8.0.0': + dependencies: + '@babel/types': 8.0.4 + '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.0)': + '@babel/helper-plugin-utils@8.0.1': {} + + '@babel/helper-remap-async-to-generator@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-wrap-function': 7.27.1 '@babel/traverse': 7.28.0 @@ -10396,6 +11154,12 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-replace-supers@8.0.1': + dependencies: + '@babel/helper-member-expression-to-functions': 8.0.0 + '@babel/helper-optimise-call-expression': 8.0.0 + '@babel/traverse': 8.0.4 + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: '@babel/traverse': 7.28.0 @@ -10403,10 +11167,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-skip-transparent-expression-wrappers@8.0.0': + dependencies: + '@babel/traverse': 8.0.4 + '@babel/types': 8.0.4 + '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-string-parser@8.0.0': {} + '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-identifier@8.0.4': {} + '@babel/helper-validator-option@7.27.1': {} '@babel/helper-wrap-function@7.27.1': @@ -10426,53 +11199,58 @@ snapshots: dependencies: '@babel/types': 7.28.2 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.0)': + '@babel/parser@8.0.4': + dependencies: + '@babel/types': 8.0.4 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.0) + '@babel/plugin-transform-optional-chaining': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.0)': + '@babel/plugin-proposal-decorators@8.0.2': dependencies: - '@babel/core': 7.28.0 + '@babel/helper-create-class-features-plugin': 8.0.1 + '@babel/helper-plugin-utils': 8.0.1 + '@babel/plugin-syntax-decorators': 8.0.1 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': {} - '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-syntax-decorators@8.0.1': + dependencies: + '@babel/helper-plugin-utils': 8.0.1 + + '@babel/plugin-syntax-import-assertions@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-syntax-import-attributes@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': @@ -10485,64 +11263,55 @@ snapshots: '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.0)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@babel/helper-create-regexp-features-plugin': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-arrow-functions@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.0)': + '@babel/plugin-transform-async-generator-functions@7.28.0': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.0) + '@babel/helper-remap-async-to-generator': 7.27.1 '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-async-to-generator@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.0) + '@babel/helper-remap-async-to-generator': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-block-scoped-functions@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-block-scoping@7.28.0(@babel/core@7.28.0)': + '@babel/plugin-transform-block-scoping@7.28.0': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-class-properties@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-class-static-block@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.0(@babel/core@7.28.0)': + '@babel/plugin-transform-classes@7.28.0': dependencies: - '@babel/core': 7.28.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-globals': 7.28.0 @@ -10552,92 +11321,77 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-computed-properties@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/template': 7.27.2 - '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.0)': + '@babel/plugin-transform-destructuring@7.28.0': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-dotall-regex@7.27.1': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@babel/helper-create-regexp-features-plugin': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-duplicate-keys@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@babel/helper-create-regexp-features-plugin': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-dynamic-import@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-exponentiation-operator@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-export-namespace-from@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-for-of@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-function-name@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-json-strings@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-literals@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-logical-assignment-operators@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-member-expression-literals@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-modules-amd@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: @@ -10651,9 +11405,8 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-modules-systemjs@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 @@ -10661,92 +11414,79 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-modules-umd@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@babel/helper-create-regexp-features-plugin': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-new-target@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-numeric-separator@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-object-rest-spread@7.28.0(@babel/core@7.28.0)': + '@babel/plugin-transform-object-rest-spread@7.28.0': dependencies: - '@babel/core': 7.28.0 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.0) + '@babel/plugin-transform-destructuring': 7.28.0 + '@babel/plugin-transform-parameters': 7.27.7 '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-object-super@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-optional-catch-binding@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-optional-chaining@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.0)': + '@babel/plugin-transform-parameters@7.27.7': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-private-methods@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-private-property-in-object@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-property-literals@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.0)': @@ -10759,48 +11499,40 @@ snapshots: '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regenerator@7.28.1(@babel/core@7.28.0)': + '@babel/plugin-transform-regenerator@7.28.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-regexp-modifiers@7.27.1': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@babel/helper-create-regexp-features-plugin': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-reserved-words@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-shorthand-properties@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-spread@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-sticky-regex@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-template-literals@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-typeof-symbol@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.0)': @@ -10814,107 +11546,101 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-unicode-escapes@7.27.1': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-unicode-property-regex@7.27.1': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@babel/helper-create-regexp-features-plugin': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-unicode-regex@7.27.1': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@babel/helper-create-regexp-features-plugin': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.0)': + '@babel/plugin-transform-unicode-sets-regex@7.27.1': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.0) + '@babel/helper-create-regexp-features-plugin': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/preset-env@7.27.2(@babel/core@7.28.0)': + '@babel/preset-env@7.27.2': dependencies: '@babel/compat-data': 7.28.0 - '@babel/core': 7.28.0 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.0) - '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.0) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-block-scoping': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-class-static-block': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-classes': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.0) + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1 + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1 + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.27.1 + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2 + '@babel/plugin-syntax-import-assertions': 7.27.1 + '@babel/plugin-syntax-import-attributes': 7.27.1 + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6 + '@babel/plugin-transform-arrow-functions': 7.27.1 + '@babel/plugin-transform-async-generator-functions': 7.28.0 + '@babel/plugin-transform-async-to-generator': 7.27.1 + '@babel/plugin-transform-block-scoped-functions': 7.27.1 + '@babel/plugin-transform-block-scoping': 7.28.0 + '@babel/plugin-transform-class-properties': 7.27.1 + '@babel/plugin-transform-class-static-block': 7.27.1 + '@babel/plugin-transform-classes': 7.28.0 + '@babel/plugin-transform-computed-properties': 7.27.1 + '@babel/plugin-transform-destructuring': 7.28.0 + '@babel/plugin-transform-dotall-regex': 7.27.1 + '@babel/plugin-transform-duplicate-keys': 7.27.1 + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1 + '@babel/plugin-transform-dynamic-import': 7.27.1 + '@babel/plugin-transform-exponentiation-operator': 7.27.1 + '@babel/plugin-transform-export-namespace-from': 7.27.1 + '@babel/plugin-transform-for-of': 7.27.1 + '@babel/plugin-transform-function-name': 7.27.1 + '@babel/plugin-transform-json-strings': 7.27.1 + '@babel/plugin-transform-literals': 7.27.1 + '@babel/plugin-transform-logical-assignment-operators': 7.27.1 + '@babel/plugin-transform-member-expression-literals': 7.27.1 + '@babel/plugin-transform-modules-amd': 7.27.1 '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-object-rest-spread': 7.28.0(@babel/core@7.28.0) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.0) - '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-regenerator': 7.28.1(@babel/core@7.28.0) - '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.0) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.0) - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.0) - babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.28.0) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.0) + '@babel/plugin-transform-modules-systemjs': 7.27.1 + '@babel/plugin-transform-modules-umd': 7.27.1 + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1 + '@babel/plugin-transform-new-target': 7.27.1 + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1 + '@babel/plugin-transform-numeric-separator': 7.27.1 + '@babel/plugin-transform-object-rest-spread': 7.28.0 + '@babel/plugin-transform-object-super': 7.27.1 + '@babel/plugin-transform-optional-catch-binding': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.27.1 + '@babel/plugin-transform-parameters': 7.27.7 + '@babel/plugin-transform-private-methods': 7.27.1 + '@babel/plugin-transform-private-property-in-object': 7.27.1 + '@babel/plugin-transform-property-literals': 7.27.1 + '@babel/plugin-transform-regenerator': 7.28.1 + '@babel/plugin-transform-regexp-modifiers': 7.27.1 + '@babel/plugin-transform-reserved-words': 7.27.1 + '@babel/plugin-transform-shorthand-properties': 7.27.1 + '@babel/plugin-transform-spread': 7.27.1 + '@babel/plugin-transform-sticky-regex': 7.27.1 + '@babel/plugin-transform-template-literals': 7.27.1 + '@babel/plugin-transform-typeof-symbol': 7.27.1 + '@babel/plugin-transform-unicode-escapes': 7.27.1 + '@babel/plugin-transform-unicode-property-regex': 7.27.1 + '@babel/plugin-transform-unicode-regex': 7.27.1 + '@babel/plugin-transform-unicode-sets-regex': 7.27.1 + '@babel/preset-modules': 0.1.6-no-external-plugins + babel-plugin-polyfill-corejs2: 0.4.14 + babel-plugin-polyfill-corejs3: 0.11.1 + babel-plugin-polyfill-regenerator: 0.6.5 core-js-compat: 3.44.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.0)': + '@babel/preset-modules@0.1.6-no-external-plugins': dependencies: - '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/types': 7.28.2 esutils: 2.0.3 @@ -10930,6 +11656,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/runtime-corejs3@7.29.7': + dependencies: + core-js-pure: 3.49.0 + '@babel/runtime@7.28.2': {} '@babel/template@7.27.2': @@ -10938,6 +11668,12 @@ snapshots: '@babel/parser': 7.28.0 '@babel/types': 7.28.2 + '@babel/template@8.0.0': + dependencies: + '@babel/code-frame': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 + '@babel/traverse@7.28.0': dependencies: '@babel/code-frame': 7.27.1 @@ -10950,11 +11686,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@8.0.4': + dependencies: + '@babel/code-frame': 8.0.0 + '@babel/generator': 8.0.0 + '@babel/helper-globals': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/template': 8.0.0 + '@babel/types': 8.0.4 + obug: 2.1.4 + '@babel/types@7.28.2': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@8.0.4': + dependencies: + '@babel/helper-string-parser': 8.0.0 + '@babel/helper-validator-identifier': 8.0.4 + '@better-auth/utils@0.2.5': dependencies: typescript: 5.8.3 @@ -10997,6 +11748,16 @@ snapshots: '@biomejs/cli-win32-x64@2.0.6': optional: true + '@cfworker/json-schema@4.1.1': {} + + '@cloudflare/codemode@0.5.0(@modelcontextprotocol/sdk@1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76))(zod@3.25.76)': + dependencies: + '@types/json-schema': 7.0.15 + acorn: 8.17.0 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + zod: 3.25.76 + '@cloudflare/containers@0.0.30': {} '@cloudflare/kv-asset-handler@0.4.0': @@ -11024,7 +11785,7 @@ snapshots: optionalDependencies: workerd: 1.20250712.0 - '@cloudflare/vite-plugin@1.10.1(rollup@4.46.0)(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0))(workerd@1.20250712.0)(wrangler@4.26.0(@cloudflare/workers-types@4.20250726.0))': + '@cloudflare/vite-plugin@1.10.1(rollup@4.46.0)(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0))(workerd@1.20250712.0)(wrangler@4.26.0(@cloudflare/workers-types@4.20250726.0))': dependencies: '@cloudflare/unenv-preset': 2.4.1(unenv@2.0.0-rc.17)(workerd@1.20250712.0) '@mjackson/node-fetch-server': 0.6.1 @@ -11034,7 +11795,7 @@ snapshots: picocolors: 1.1.1 tinyglobby: 0.2.14 unenv: 2.0.0-rc.17 - vite: 7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) wrangler: 4.26.0(@cloudflare/workers-types@4.20250726.0) ws: 8.18.0 transitivePeerDependencies: @@ -11043,7 +11804,7 @@ snapshots: - utf-8-validate - workerd - '@cloudflare/vitest-pool-workers@0.8.57(@cloudflare/workers-types@4.20250726.0)(@vitest/runner@3.0.9)(@vitest/snapshot@3.0.9)(vitest@3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0))': + '@cloudflare/vitest-pool-workers@0.8.57(@cloudflare/workers-types@4.20250726.0)(@vitest/runner@3.0.9)(@vitest/snapshot@3.0.9)(vitest@3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0))': dependencies: '@vitest/runner': 3.0.9 '@vitest/snapshot': 3.0.9 @@ -11052,7 +11813,7 @@ snapshots: devalue: 4.3.3 miniflare: 4.20250712.2 semver: 7.7.2 - vitest: 3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + vitest: 3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) wrangler: 4.26.0(@cloudflare/workers-types@4.20250726.0) zod: 3.25.76 transitivePeerDependencies: @@ -11278,11 +12039,11 @@ snapshots: transitivePeerDependencies: - debug - '@daytonaio/sdk@0.21.1(@babel/core@7.28.0)(typescript@5.8.3)': + '@daytonaio/sdk@0.21.1(typescript@5.8.3)': dependencies: '@aws-sdk/client-s3': 3.850.0 '@aws-sdk/lib-storage': 3.850.0(@aws-sdk/client-s3@3.850.0) - '@babel/preset-env': 7.27.2(@babel/core@7.28.0) + '@babel/preset-env': 7.27.2 '@babel/preset-typescript': 7.27.1(@babel/core@7.28.0) '@daytonaio/api-client': 0.21.8 '@dotenvx/dotenvx': 1.48.3 @@ -11325,11 +12086,22 @@ snapshots: dependencies: '@noble/ciphers': 1.3.0 + '@emnapi/core@1.11.2': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + '@emnapi/core@1.4.5': dependencies: '@emnapi/wasi-threads': 1.0.4 tslib: 2.8.1 + '@emnapi/runtime@1.11.2': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.4.5': dependencies: tslib: 2.8.1 @@ -11343,6 +12115,11 @@ snapshots: dependencies: tslib: 2.8.1 + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild-kit/core-utils@3.3.2': dependencies: esbuild: 0.18.20 @@ -11365,6 +12142,9 @@ snapshots: '@esbuild/aix-ppc64@0.27.3': optional: true + '@esbuild/aix-ppc64@0.28.1': + optional: true + '@esbuild/android-arm64@0.18.20': optional: true @@ -11380,6 +12160,9 @@ snapshots: '@esbuild/android-arm64@0.27.3': optional: true + '@esbuild/android-arm64@0.28.1': + optional: true + '@esbuild/android-arm@0.18.20': optional: true @@ -11395,6 +12178,9 @@ snapshots: '@esbuild/android-arm@0.27.3': optional: true + '@esbuild/android-arm@0.28.1': + optional: true + '@esbuild/android-x64@0.18.20': optional: true @@ -11410,6 +12196,9 @@ snapshots: '@esbuild/android-x64@0.27.3': optional: true + '@esbuild/android-x64@0.28.1': + optional: true + '@esbuild/darwin-arm64@0.18.20': optional: true @@ -11425,6 +12214,9 @@ snapshots: '@esbuild/darwin-arm64@0.27.3': optional: true + '@esbuild/darwin-arm64@0.28.1': + optional: true + '@esbuild/darwin-x64@0.18.20': optional: true @@ -11440,6 +12232,9 @@ snapshots: '@esbuild/darwin-x64@0.27.3': optional: true + '@esbuild/darwin-x64@0.28.1': + optional: true + '@esbuild/freebsd-arm64@0.18.20': optional: true @@ -11455,6 +12250,9 @@ snapshots: '@esbuild/freebsd-arm64@0.27.3': optional: true + '@esbuild/freebsd-arm64@0.28.1': + optional: true + '@esbuild/freebsd-x64@0.18.20': optional: true @@ -11470,6 +12268,9 @@ snapshots: '@esbuild/freebsd-x64@0.27.3': optional: true + '@esbuild/freebsd-x64@0.28.1': + optional: true + '@esbuild/linux-arm64@0.18.20': optional: true @@ -11485,6 +12286,9 @@ snapshots: '@esbuild/linux-arm64@0.27.3': optional: true + '@esbuild/linux-arm64@0.28.1': + optional: true + '@esbuild/linux-arm@0.18.20': optional: true @@ -11500,6 +12304,9 @@ snapshots: '@esbuild/linux-arm@0.27.3': optional: true + '@esbuild/linux-arm@0.28.1': + optional: true + '@esbuild/linux-ia32@0.18.20': optional: true @@ -11515,6 +12322,9 @@ snapshots: '@esbuild/linux-ia32@0.27.3': optional: true + '@esbuild/linux-ia32@0.28.1': + optional: true + '@esbuild/linux-loong64@0.18.20': optional: true @@ -11530,6 +12340,9 @@ snapshots: '@esbuild/linux-loong64@0.27.3': optional: true + '@esbuild/linux-loong64@0.28.1': + optional: true + '@esbuild/linux-mips64el@0.18.20': optional: true @@ -11545,6 +12358,9 @@ snapshots: '@esbuild/linux-mips64el@0.27.3': optional: true + '@esbuild/linux-mips64el@0.28.1': + optional: true + '@esbuild/linux-ppc64@0.18.20': optional: true @@ -11560,6 +12376,9 @@ snapshots: '@esbuild/linux-ppc64@0.27.3': optional: true + '@esbuild/linux-ppc64@0.28.1': + optional: true + '@esbuild/linux-riscv64@0.18.20': optional: true @@ -11575,6 +12394,9 @@ snapshots: '@esbuild/linux-riscv64@0.27.3': optional: true + '@esbuild/linux-riscv64@0.28.1': + optional: true + '@esbuild/linux-s390x@0.18.20': optional: true @@ -11590,6 +12412,9 @@ snapshots: '@esbuild/linux-s390x@0.27.3': optional: true + '@esbuild/linux-s390x@0.28.1': + optional: true + '@esbuild/linux-x64@0.18.20': optional: true @@ -11605,6 +12430,9 @@ snapshots: '@esbuild/linux-x64@0.27.3': optional: true + '@esbuild/linux-x64@0.28.1': + optional: true + '@esbuild/netbsd-arm64@0.25.4': optional: true @@ -11614,6 +12442,9 @@ snapshots: '@esbuild/netbsd-arm64@0.27.3': optional: true + '@esbuild/netbsd-arm64@0.28.1': + optional: true + '@esbuild/netbsd-x64@0.18.20': optional: true @@ -11629,6 +12460,9 @@ snapshots: '@esbuild/netbsd-x64@0.27.3': optional: true + '@esbuild/netbsd-x64@0.28.1': + optional: true + '@esbuild/openbsd-arm64@0.25.4': optional: true @@ -11638,6 +12472,9 @@ snapshots: '@esbuild/openbsd-arm64@0.27.3': optional: true + '@esbuild/openbsd-arm64@0.28.1': + optional: true + '@esbuild/openbsd-x64@0.18.20': optional: true @@ -11653,12 +12490,18 @@ snapshots: '@esbuild/openbsd-x64@0.27.3': optional: true + '@esbuild/openbsd-x64@0.28.1': + optional: true + '@esbuild/openharmony-arm64@0.25.8': optional: true '@esbuild/openharmony-arm64@0.27.3': optional: true + '@esbuild/openharmony-arm64@0.28.1': + optional: true + '@esbuild/sunos-x64@0.18.20': optional: true @@ -11674,6 +12517,9 @@ snapshots: '@esbuild/sunos-x64@0.27.3': optional: true + '@esbuild/sunos-x64@0.28.1': + optional: true + '@esbuild/win32-arm64@0.18.20': optional: true @@ -11689,6 +12535,9 @@ snapshots: '@esbuild/win32-arm64@0.27.3': optional: true + '@esbuild/win32-arm64@0.28.1': + optional: true + '@esbuild/win32-ia32@0.18.20': optional: true @@ -11704,6 +12553,9 @@ snapshots: '@esbuild/win32-ia32@0.27.3': optional: true + '@esbuild/win32-ia32@0.28.1': + optional: true + '@esbuild/win32-x64@0.18.20': optional: true @@ -11719,6 +12571,9 @@ snapshots: '@esbuild/win32-x64@0.27.3': optional: true + '@esbuild/win32-x64@0.28.1': + optional: true + '@eslint-community/eslint-utils@4.7.0(eslint@9.32.0(jiti@2.6.1))': dependencies: eslint: 9.32.0(jiti@2.6.1) @@ -11828,6 +12683,10 @@ snapshots: '@hexagon/base64@1.1.28': {} + '@hono/node-server@1.19.15(hono@4.12.32)': + dependencies: + hono: 4.12.32 + '@hono/zod-validator@0.7.2(hono@4.8.9)(zod@3.25.76)': dependencies: hono: 4.8.9 @@ -12288,6 +13147,30 @@ snapshots: '@mjackson/node-fetch-server@0.6.1': {} + '@modelcontextprotocol/sdk@1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76)': + dependencies: + '@hono/node-server': 1.19.15(hono@4.12.32) + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.1.0 + express: 5.2.1 + express-rate-limit: 8.6.0(express@5.2.1) + hono: 4.12.32 + jose: 6.2.4 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 3.25.76 + zod-to-json-schema: 3.25.2(zod@3.25.76) + optionalDependencies: + '@cfworker/json-schema': 4.1.1 + transitivePeerDependencies: + - supports-color + '@msgpack/msgpack@3.1.3': {} '@napi-rs/wasm-runtime@0.2.12': @@ -12303,6 +13186,13 @@ snapshots: '@emnapi/runtime': 1.4.5 '@tybys/wasm-util': 0.9.0 + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@tybys/wasm-util': 0.10.3 + optional: true + '@next/env@15.4.8': {} '@next/eslint-plugin-next@15.4.2': @@ -12437,6 +13327,8 @@ snapshots: '@opentelemetry/semantic-conventions@1.43.0': {} + '@oxc-project/types@0.140.0': {} + '@peculiar/asn1-android@2.4.0': dependencies: '@peculiar/asn1-schema': 2.4.0 @@ -14024,8 +14916,67 @@ snapshots: dependencies: react: 19.2.1 + '@rolldown/binding-android-arm64@1.2.0': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.0': + optional: true + + '@rolldown/binding-darwin-x64@1.2.0': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.0': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.0': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.0': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.0': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.0': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.0': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.0': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.0': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.0': + optional: true + + '@rolldown/binding-wasm32-wasi@1.2.0': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.0': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.0': + optional: true + + '@rolldown/plugin-babel@0.2.3(@babel/runtime@7.28.2)(rolldown@1.2.0)(vite@6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0))': + dependencies: + picomatch: 4.0.5 + rolldown: 1.2.0 + optionalDependencies: + '@babel/runtime': 7.28.2 + vite: 6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) + '@rolldown/pluginutils@1.0.0-beta.27': {} + '@rolldown/pluginutils@1.0.1': {} + '@rollup/plugin-replace@6.0.2(rollup@4.46.0)': dependencies: '@rollup/pluginutils': 5.2.0(rollup@4.46.0) @@ -14717,12 +15668,12 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 4.1.11 - '@tailwindcss/vite@4.1.17(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0))': + '@tailwindcss/vite@4.1.17(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0))': dependencies: '@tailwindcss/node': 4.1.17 '@tailwindcss/oxide': 4.1.17 tailwindcss: 4.1.17 - vite: 7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) '@tanstack/form-core@1.15.0': dependencies: @@ -14810,7 +15761,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.130.1(@tanstack/react-router@1.130.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0))': + '@tanstack/router-plugin@1.130.1(@tanstack/react-router@1.130.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0))': dependencies: '@babel/core': 7.28.0 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) @@ -14828,7 +15779,7 @@ snapshots: zod: 3.25.76 optionalDependencies: '@tanstack/react-router': 1.130.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1) - vite: 7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) transitivePeerDependencies: - supports-color @@ -15148,6 +16099,11 @@ snapshots: tslib: 2.8.1 optional: true + '@tybys/wasm-util@0.10.3': + dependencies: + tslib: 2.8.1 + optional: true + '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.8.1 @@ -15224,6 +16180,8 @@ snapshots: '@types/react': 19.1.8 hoist-non-react-statics: 3.3.2 + '@types/jsesc@2.5.1': {} + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} @@ -15450,7 +16408,7 @@ snapshots: '@use-gesture/core': 10.3.1 react: 19.2.1 - '@vitejs/plugin-react@4.7.0(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0))': + '@vitejs/plugin-react@4.7.0(vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0))': dependencies: '@babel/core': 7.28.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.0) @@ -15458,7 +16416,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) transitivePeerDependencies: - supports-color @@ -15469,13 +16427,13 @@ snapshots: chai: 5.2.1 tinyrainbow: 2.0.0 - '@vitest/mocker@3.0.9(vite@6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0))': + '@vitest/mocker@3.0.9(vite@6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0))': dependencies: '@vitest/spy': 3.0.9 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) '@vitest/pretty-format@3.0.9': dependencies: @@ -15526,6 +16484,11 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -15540,6 +16503,8 @@ snapshots: acorn@8.15.0: {} + acorn@8.17.0: {} + agent-base@7.1.4: {} agentation@2.3.3(react-dom@19.2.1(react@19.2.1))(react@19.2.1): @@ -15547,6 +16512,37 @@ snapshots: react: 19.2.1 react-dom: 19.2.1(react@19.2.1) + agents@0.19.0(@babel/runtime@7.28.2)(@cloudflare/workers-types@4.20250726.0)(react@19.2.1)(rolldown@1.2.0)(vite@6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0))(zod@3.25.76): + dependencies: + '@babel/plugin-proposal-decorators': 8.0.2 + '@cfworker/json-schema': 4.1.1 + '@cloudflare/codemode': 0.5.0(@modelcontextprotocol/sdk@1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76))(zod@3.25.76) + '@modelcontextprotocol/sdk': 1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + '@rolldown/plugin-babel': 0.2.3(@babel/runtime@7.28.2)(rolldown@1.2.0)(vite@6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0)) + cron-schedule: 6.0.0 + esbuild: 0.28.1 + mimetext: 3.0.28 + nanoid: 5.1.16 + partyserver: 0.5.8(@cloudflare/workers-types@4.20250726.0) + partysocket: 1.3.0(react@19.2.1) + react: 19.2.1 + yaml: 2.9.0 + yargs: 18.0.0 + zod: 3.25.76 + optionalDependencies: + vite: 6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) + transitivePeerDependencies: + - '@babel/core' + - '@babel/plugin-transform-runtime' + - '@babel/runtime' + - '@cloudflare/workers-types' + - rolldown + - supports-color + + ajv-formats@3.0.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -15554,16 +16550,27 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.4 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-colors@4.1.3: {} ansi-regex@5.0.1: {} + ansi-regex@6.2.2: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 ansi-styles@5.2.0: {} + ansi-styles@6.2.3: {} + ansis@4.1.0: {} anymatch@3.1.3: @@ -15707,27 +16714,24 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.0): + babel-plugin-polyfill-corejs2@0.4.14: dependencies: '@babel/compat-data': 7.28.0 - '@babel/core': 7.28.0 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.0) + '@babel/helper-define-polyfill-provider': 0.6.5 semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.11.1(@babel/core@7.28.0): + babel-plugin-polyfill-corejs3@0.11.1: dependencies: - '@babel/core': 7.28.0 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.0) + '@babel/helper-define-polyfill-provider': 0.6.5 core-js-compat: 3.44.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.0): + babel-plugin-polyfill-regenerator@0.6.5: dependencies: - '@babel/core': 7.28.0 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.0) + '@babel/helper-define-polyfill-provider': 0.6.5 transitivePeerDependencies: - supports-color @@ -15795,6 +16799,20 @@ snapshots: transitivePeerDependencies: - supports-color + body-parser@2.3.0: + dependencies: + bytes: 3.1.2 + content-type: 2.0.0 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + on-finished: 2.4.1 + qs: 6.15.3 + raw-body: 3.0.2 + type-is: 2.1.0 + transitivePeerDependencies: + - supports-color + bowser@2.11.0: {} brace-expansion@1.1.12: @@ -15940,6 +16958,12 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + clone@1.0.4: {} clone@2.1.2: {} @@ -16032,14 +17056,20 @@ snapshots: dependencies: safe-buffer: 5.2.1 + content-disposition@1.1.0: {} + content-type@1.0.5: {} + content-type@2.0.0: {} + convert-source-map@2.0.0: {} cookie-es@1.2.2: {} cookie-signature@1.0.6: {} + cookie-signature@1.2.2: {} + cookie@0.7.1: {} cookie@0.7.2: {} @@ -16050,12 +17080,21 @@ snapshots: dependencies: browserslist: 4.25.1 + core-js-pure@3.49.0: {} + core-js@3.44.0: {} core-js@3.49.0: {} + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + crelt@1.0.6: {} + cron-schedule@6.0.0: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -16154,6 +17193,10 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.4.3: + dependencies: + ms: 2.1.3 + decimal.js-light@2.5.1: {} decimal.js@10.6.0: {} @@ -16282,6 +17325,8 @@ snapshots: electron-to-chromium@1.5.191: {} + emoji-regex@10.6.0: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -16577,6 +17622,35 @@ snapshots: '@esbuild/win32-ia32': 0.27.3 '@esbuild/win32-x64': 0.27.3 + esbuild@0.28.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -16835,6 +17909,12 @@ snapshots: eventsource-parser@1.1.2: {} + eventsource-parser@3.1.0: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.1.0 + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -16863,6 +17943,14 @@ snapshots: expect-type@1.2.2: {} + express-rate-limit@8.6.0(express@5.2.1): + dependencies: + debug: 4.4.3 + express: 5.2.1 + ip-address: 10.3.1 + transitivePeerDependencies: + - supports-color + express@4.21.2: dependencies: accepts: 1.3.8 @@ -16899,6 +17987,39 @@ snapshots: transitivePeerDependencies: - supports-color + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.3.0 + content-disposition: 1.1.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.1 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.0 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.1 + type-is: 2.1.0 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + exsolve@1.0.7: {} extend-shallow@2.0.1: @@ -16933,6 +18054,8 @@ snapshots: fast-sha256@1.3.0: {} + fast-uri@3.1.4: {} + fast-xml-parser@5.2.5: dependencies: strnum: 2.1.1 @@ -16979,6 +18102,17 @@ snapshots: transitivePeerDependencies: - supports-color + finalhandler@2.1.1: + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -17033,6 +18167,8 @@ snapshots: fresh@0.5.2: {} + fresh@2.0.0: {} + front-matter@4.0.2: dependencies: js-yaml: 3.14.1 @@ -17063,6 +18199,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.6.0: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -17255,6 +18393,8 @@ snapshots: hono: 4.8.9 partyserver: 0.0.72(@cloudflare/workers-types@4.20250726.0) + hono@4.12.32: {} + hono@4.8.9: {} hotkeys-js@3.13.15: {} @@ -17273,6 +18413,14 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 @@ -17299,6 +18447,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 + idb@7.1.1: {} ieee754@1.2.1: {} @@ -17339,6 +18491,8 @@ snapshots: '@formatjs/icu-messageformat-parser': 2.11.2 tslib: 2.8.1 + ip-address@10.3.1: {} + ipaddr.js@1.9.1: {} is-alphabetical@1.0.4: {} @@ -17461,6 +18615,8 @@ snapshots: is-potential-custom-element-name@1.0.1: {} + is-promise@4.0.0: {} + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -17550,6 +18706,12 @@ snapshots: jose@5.10.0: {} + jose@6.2.4: {} + + js-base64@3.9.1: {} + + js-tokens@10.0.0: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -17596,6 +18758,10 @@ snapshots: json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + json-schema-walker@2.0.0: dependencies: '@apidevtools/json-schema-ref-parser': 11.9.3 @@ -17987,8 +19153,12 @@ snapshots: media-typer@0.3.0: {} + media-typer@1.1.1: {} + merge-descriptors@1.0.3: {} + merge-descriptors@2.0.0: {} + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -18274,10 +19444,21 @@ snapshots: dependencies: mime-db: 1.52.0 + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + mime@1.6.0: {} mime@3.0.0: {} + mimetext@3.0.28: + dependencies: + '@babel/runtime': 7.28.2 + '@babel/runtime-corejs3': 7.29.7 + js-base64: 3.9.1 + mime-types: 2.1.35 + mimic-fn@2.1.0: {} mimic-fn@4.0.0: {} @@ -18419,6 +19600,8 @@ snapshots: nanoid@3.3.11: {} + nanoid@5.1.16: {} + nanoid@5.1.5: {} nanostores@0.11.4: {} @@ -18431,6 +19614,8 @@ snapshots: negotiator@0.6.4: {} + negotiator@1.0.0: {} + next-mdx-remote@6.0.0(@types/react@19.1.8)(react@19.1.0): dependencies: '@babel/code-frame': 7.27.1 @@ -18580,6 +19765,8 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + obug@2.1.4: {} + ohash@1.1.6: {} ohash@2.0.11: {} @@ -18705,10 +19892,21 @@ snapshots: '@cloudflare/workers-types': 4.20250726.0 nanoid: 5.1.5 + partyserver@0.5.8(@cloudflare/workers-types@4.20250726.0): + dependencies: + '@cloudflare/workers-types': 4.20250726.0 + nanoid: 5.1.16 + partysocket@1.1.4: dependencies: event-target-polyfill: 0.0.4 + partysocket@1.3.0(react@19.2.1): + dependencies: + event-target-polyfill: 0.0.4 + optionalDependencies: + react: 19.2.1 + path-exists@4.0.0: {} path-key@3.1.1: {} @@ -18721,6 +19919,8 @@ snapshots: path-to-regexp@6.3.0: {} + path-to-regexp@8.4.2: {} + pathe@1.1.2: {} pathe@2.0.3: {} @@ -18733,6 +19933,10 @@ snapshots: picomatch@4.0.3: {} + picomatch@4.0.5: {} + + pkce-challenge@5.0.1: {} + pkg-types@1.3.1: dependencies: confbox: 0.1.8 @@ -18940,6 +20144,11 @@ snapshots: dependencies: side-channel: 1.1.0 + qs@6.15.3: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + query-selector-shadow-dom@1.0.1: {} queue-microtask@1.2.3: {} @@ -19016,6 +20225,13 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + unpipe: 1.0.0 + react-cookie@8.0.1(@types/react@19.1.8)(react@19.2.1): dependencies: '@types/hoist-non-react-statics': 3.3.7(@types/react@19.1.8) @@ -19341,6 +20557,8 @@ snapshots: require-directory@2.1.1: {} + require-from-string@2.0.2: {} + require-in-the-middle@8.0.1: dependencies: debug: 4.4.1 @@ -19380,6 +20598,27 @@ snapshots: robot3@0.4.1: {} + rolldown@1.2.0: + dependencies: + '@oxc-project/types': 0.140.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.2.0 + '@rolldown/binding-darwin-arm64': 1.2.0 + '@rolldown/binding-darwin-x64': 1.2.0 + '@rolldown/binding-freebsd-x64': 1.2.0 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.0 + '@rolldown/binding-linux-arm64-gnu': 1.2.0 + '@rolldown/binding-linux-arm64-musl': 1.2.0 + '@rolldown/binding-linux-ppc64-gnu': 1.2.0 + '@rolldown/binding-linux-s390x-gnu': 1.2.0 + '@rolldown/binding-linux-x64-gnu': 1.2.0 + '@rolldown/binding-linux-x64-musl': 1.2.0 + '@rolldown/binding-openharmony-arm64': 1.2.0 + '@rolldown/binding-wasm32-wasi': 1.2.0 + '@rolldown/binding-win32-arm64-msvc': 1.2.0 + '@rolldown/binding-win32-x64-msvc': 1.2.0 + rollup@4.46.0: dependencies: '@types/estree': 1.0.8 @@ -19410,6 +20649,16 @@ snapshots: rou3@0.5.1: {} + router@2.2.0: + dependencies: + debug: 4.4.1 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color + rrweb-cssom@0.8.0: {} run-parallel@1.2.0: @@ -19480,6 +20729,22 @@ snapshots: transitivePeerDependencies: - supports-color + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + seroval-plugins@1.3.2(seroval@1.3.2): dependencies: seroval: 1.3.2 @@ -19495,6 +20760,15 @@ snapshots: transitivePeerDependencies: - supports-color + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + set-cookie-parser@2.7.1: {} set-function-length@1.2.2: @@ -19621,6 +20895,11 @@ snapshots: es-errors: 1.3.0 object-inspect: 1.13.4 + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-map@1.0.1: dependencies: call-bound: 1.0.4 @@ -19644,6 +20923,14 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -19703,6 +20990,8 @@ snapshots: statuses@2.0.1: {} + statuses@2.0.2: {} + std-env@3.9.0: {} stop-iteration-iterator@1.1.0: @@ -19723,6 +21012,12 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + string.prototype.includes@2.0.1: dependencies: call-bind: 1.0.8 @@ -19786,6 +21081,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + strip-bom-string@1.0.0: {} strip-bom@3.0.0: {} @@ -19996,6 +21295,12 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 + type-is@2.1.0: + dependencies: + content-type: 2.0.0 + media-typer: 1.1.1 + mime-types: 3.0.2 + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 @@ -20284,13 +21589,13 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 - vite-node@3.0.9(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0): + vite-node@3.0.9(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) transitivePeerDependencies: - '@types/node' - jiti @@ -20305,7 +21610,7 @@ snapshots: - tsx - yaml - vite@6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0): + vite@6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0): dependencies: esbuild: 0.25.8 fdir: 6.4.6(picomatch@4.0.3) @@ -20319,9 +21624,9 @@ snapshots: jiti: 2.6.1 lightningcss: 1.30.2 tsx: 4.20.3 - yaml: 2.8.0 + yaml: 2.9.0 - vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0): + vite@7.2.6(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0): dependencies: esbuild: 0.25.8 fdir: 6.5.0(picomatch@4.0.3) @@ -20335,12 +21640,12 @@ snapshots: jiti: 2.6.1 lightningcss: 1.30.2 tsx: 4.20.3 - yaml: 2.8.0 + yaml: 2.9.0 - vitest@3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0): + vitest@3.0.9(@types/debug@4.1.12)(@types/node@24.1.0)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0): dependencies: '@vitest/expect': 3.0.9 - '@vitest/mocker': 3.0.9(vite@6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0)) + '@vitest/mocker': 3.0.9(vite@6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.0.9 '@vitest/snapshot': 3.0.9 @@ -20356,8 +21661,8 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) - vite-node: 3.0.9(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) + vite-node: 3.0.9(@types/node@24.1.0)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.20.3)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 @@ -20526,6 +21831,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrappy@1.0.2: {} ws@8.18.0: {} @@ -20594,8 +21905,12 @@ snapshots: yaml@2.8.0: {} + yaml@2.9.0: {} + yargs-parser@21.1.1: {} + yargs-parser@22.0.0: {} + yargs@17.7.2: dependencies: cliui: 8.0.1 @@ -20606,6 +21921,15 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yargs@18.0.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 7.2.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + yjs@13.6.27: dependencies: lib0: 0.2.114 @@ -20637,6 +21961,10 @@ snapshots: dependencies: zod: 3.25.76 + zod-to-json-schema@3.25.2(zod@3.25.76): + dependencies: + zod: 3.25.76 + zod@3.22.3: {} zod@3.25.76: {}