History

Refactor executor integration to use Convex-native methods, removing legacy executor client and updating environment variable handling. Adjusted service spawning and URL resolution for improved clarity and functionality.

Rhys Sullivan committed 9 months ago

Commit ed3e4e31 parent 60728c053 files · +3194 −4224Browse files

Unified · Split

53 files
  1. assistant/packages/bot/src/commands/ask.tsx +0 −3
  2. assistant/packages/bot/src/index.ts +1 −5
  3. assistant/packages/bot/src/views/task-message.tsx +7 −7
  4. assistant/packages/bot/tsconfig.json +1 −2
  5. assistant/packages/core/src/agent.ts +33 −5
  6. assistant/packages/server/package.json +1 −2
  7. assistant/packages/server/src/executor-client.ts +0 −12
  8. assistant/packages/server/src/index.ts +38 −8
  9. assistant/packages/server/tsconfig.json +1 −2
  10. dev.ts +38 −29
  11. executor/README.md +13 −150
  12. executor/apps/server/package.json +0 −28
  13. executor/apps/server/src/_measure-descriptors.ts +0 −84
  14. executor/apps/server/src/cli.test.ts +0 −317
  15. executor/apps/server/src/cli.ts +0 −536
  16. executor/apps/server/src/database.ts +0 −236
  17. executor/apps/server/src/index.ts +0 −497
  18. executor/apps/server/src/runtimes/local-bun-runtime.ts +0 −20
  19. executor/apps/server/src/runtimes/sandbox-fragments.ts +0 −224
  20. executor/apps/server/src/runtimes/vercel-sandbox-runtime.ts +0 −168
  21. executor/apps/server/src/service.test.ts +0 −428
  22. executor/apps/server/src/service.ts +0 −911
  23. executor/apps/server/src/tailscale-funnel.ts +0 −116
  24. executor/apps/server/src/worker.ts +0 −111
  25. executor/apps/server/tsconfig.json +0 −16
  26. executor/apps/web/src/lib/session-context.tsx +76 −198
  27. executor/apps/web/tsconfig.json +1 −2
  28. executor/bun.lock +2091 −0
  29. executor/convex/database.test.ts +17 −0
  30. executor/convex/database.ts +115 −4
  31. executor/convex/executor-mcp.e2e.test.ts +164 −0
  32. executor/convex/executor.ts +2 −2
  33. executor/convex/executorNode.ts +8 −8
  34. executor/convex/http.ts +2 −2
  35. executor/convex/lib/adapters/in-process-execution-adapter.test.ts +0 −0
  36. executor/convex/lib/adapters/in-process-execution-adapter.ts +0 −0
  37. executor/convex/lib/events.ts +0 −0
  38. executor/convex/lib/execution-constants.ts +0 −0
  39. executor/convex/lib/mcp-server.test.ts +0 −0
  40. executor/convex/lib/mcp-server.ts +27 −11
  41. executor/convex/lib/runtimes/runtime-core.test.ts +0 −0
  42. executor/convex/lib/runtimes/runtime-core.ts +27 −1
  43. executor/convex/lib/tool-discovery.ts +0 −0
  44. executor/convex/lib/tool-sources.test.ts +0 −0
  45. executor/convex/lib/tool-sources.ts +407 −74
  46. executor/convex/lib/tools.ts +0 −0
  47. executor/convex/lib/typechecker.test.ts +95 −0
  48. executor/convex/lib/typechecker.ts +20 −1
  49. executor/convex/lib/types.ts +2 −0
  50. executor/convex/lib/utils.ts +0 −0
  51. executor/convex/schema.ts +2 −0
  52. executor/package.json +3 −4
  53. executor/packages/contracts/src/index.ts +2 −0
assistant/packages/bot/src/commands/ask.tsx+0−3
@@ -5,7 +5,6 @@ · 4 unmodified lines
5import type { ChatInputCommandInteraction, CommandInteraction } from "discord.js";5import type { ChatInputCommandInteraction, CommandInteraction } from "discord.js";
6import type { Client } from "@assistant/server/client";6import type { Client } from "@assistant/server/client";
7import { unwrap } from "@assistant/server/client";7import { unwrap } from "@assistant/server/client";
8import type { ExecutorClient } from "@assistant/server/executor-client";
9import type { ConvexReactClient } from "convex/react";8import type { ConvexReactClient } from "convex/react";
10import { ConvexProvider } from "convex/react";9import { ConvexProvider } from "convex/react";
11import type { ReacordInstance } from "@openassistant/reacord";10import type { ReacordInstance } from "@openassistant/reacord";
@@ -14,7 +13,6 @@ import { TaskMessage } from "../views/task-message"; · 2 unmodified lines
14 13
15interface AskCommandDeps {14interface AskCommandDeps {
16 readonly api: Client;15 readonly api: Client;
17 readonly executor: ExecutorClient;
18 readonly convex: ConvexReactClient;16 readonly convex: ConvexReactClient;
19 readonly reacord: {17 readonly reacord: {
20 reply: (interaction: CommandInteraction, content: React.ReactNode) => Effect.Effect<ReacordInstance>;18 reply: (interaction: CommandInteraction, content: React.ReactNode) => Effect.Effect<ReacordInstance>;
@@ -53,7 +51,6 @@ export async function handleAskCommand( · 32 unmodified lines
53 agentTaskId={agentTaskId}51 agentTaskId={agentTaskId}
54 prompt={prompt}52 prompt={prompt}
55 workspaceId={workspaceId}53 workspaceId={workspaceId}
56 executor={deps.executor}
57 />54 />
58 </ConvexProvider>,55 </ConvexProvider>,
59 ),56 ),
assistant/packages/bot/src/index.ts+1−5
@@ -14,7 +14,6 @@ import { · 13 unmodified lines
14} from "discord.js";14} from "discord.js";
15import { makeReacord } from "@openassistant/reacord";15import { makeReacord } from "@openassistant/reacord";
16import { createClient } from "@assistant/server/client";16import { createClient } from "@assistant/server/client";
17import { createExecutorClient } from "@assistant/server/executor-client";
18import { ConvexReactClient } from "convex/react";17import { ConvexReactClient } from "convex/react";
19import { handleAskCommand } from "./commands/ask";18import { handleAskCommand } from "./commands/ask";
20 19
@@ -28,7 +27,6 @@ if (!DISCORD_TOKEN) { · 7 unmodified lines
28}27}
29 28
30const SERVER_URL = Bun.env.ASSISTANT_SERVER_URL ?? "http://localhost:3000";29const SERVER_URL = Bun.env.ASSISTANT_SERVER_URL ?? "http://localhost:3000";
31const EXECUTOR_URL = Bun.env.EXECUTOR_URL ?? "http://localhost:4001";
32const CONVEX_URL = Bun.env.CONVEX_URL ?? "http://127.0.0.1:3210";30const CONVEX_URL = Bun.env.CONVEX_URL ?? "http://127.0.0.1:3210";
33 31
34// ---------------------------------------------------------------------------32// ---------------------------------------------------------------------------
@@ -44,7 +42,6 @@ const client = new Client({ · 9 unmodified lines
44 42
45const reacord = makeReacord(client, { maxInstances: 50 });43const reacord = makeReacord(client, { maxInstances: 50 });
46const api = createClient(SERVER_URL);44const api = createClient(SERVER_URL);
47const executor = createExecutorClient(EXECUTOR_URL);
48const convex = new ConvexReactClient(CONVEX_URL, {45const convex = new ConvexReactClient(CONVEX_URL, {
49 unsavedChangesWarning: false,46 unsavedChangesWarning: false,
50});47});
@@ -87,7 +84,7 @@ client.on("interactionCreate", async (interaction) => { · 36 unmodified lines
87 84
88 switch (interaction.commandName) {85 switch (interaction.commandName) {
89 case "ask":86 case "ask":
90 await handleAskCommand(interaction, { api, executor, convex, reacord });87 await handleAskCommand(interaction, { api, convex, reacord });
91 break;88 break;
92 case "clear":89 case "clear":
93 await interaction.reply({ content: `_${"\n".repeat(50)}_` });90 await interaction.reply({ content: `_${"\n".repeat(50)}_` });
@@ -105,7 +102,6 @@ client.once("clientReady", async () => { · 11 unmodified lines
105 console.log(`Logged in as ${client.user?.tag}`);102 console.log(`Logged in as ${client.user?.tag}`);
106 await registerCommands();103 await registerCommands();
107 console.log(`Connected to server at ${SERVER_URL}`);104 console.log(`Connected to server at ${SERVER_URL}`);
108 console.log(`Executor at ${EXECUTOR_URL}`);
109 console.log(`Convex at ${CONVEX_URL}`);105 console.log(`Convex at ${CONVEX_URL}`);
110});106});
111 107
assistant/packages/bot/src/views/task-message.tsx+7−7
@@ -3,7 +3,7 @@ · 2 unmodified lines
3 *3 *
4 * - Watches agentTask in Convex for status, result, error (reactive, no polling)4 * - Watches agentTask in Convex for status, result, error (reactive, no polling)
5 * - Watches pending approvals in Convex (reactive)5 * - Watches pending approvals in Convex (reactive)
6 * - Approval buttons resolve via executor REST API6 * - Approval buttons resolve via Convex mutation
7 */7 */
8 8
9import { useState, useCallback } from "react";9import { useState, useCallback } from "react";
@@ -16,9 +16,8 @@ import { · 6 unmodified lines
16 Loading,16 Loading,
17 useInstance,17 useInstance,
18} from "@openassistant/reacord";18} from "@openassistant/reacord";
19import { useQuery } from "convex/react";19import { useMutation, useQuery } from "convex/react";
20import { api } from "@executor/convex/_generated/api";20import { api } from "@executor/convex/_generated/api";
21import type { ExecutorClient } from "@assistant/server/executor-client";
22 21
23// ---------------------------------------------------------------------------22// ---------------------------------------------------------------------------
24// Component23// Component
@@ -28,11 +27,11 @@ export interface TaskMessageProps { · 3 unmodified lines
28 readonly agentTaskId: string;27 readonly agentTaskId: string;
29 readonly prompt: string;28 readonly prompt: string;
30 readonly workspaceId: string;29 readonly workspaceId: string;
31 readonly executor: ExecutorClient;
32}30}
33 31
34export function TaskMessage({ agentTaskId, prompt, workspaceId, executor }: TaskMessageProps) {32export function TaskMessage({ agentTaskId, prompt, workspaceId }: TaskMessageProps) {
35 const instance = useInstance();33 const instance = useInstance();
34 const resolveApproval = useMutation(api.executor.resolveApproval);
36 35
37 // Reactive queries — no polling!36 // Reactive queries — no polling!
38 const agentTask = useQuery(api.database.getAgentTask, { agentTaskId });37 const agentTask = useQuery(api.database.getAgentTask, { agentTaskId });
@@ -48,14 +47,15 @@ export function TaskMessage({ agentTaskId, prompt, workspaceId, executor }: Task · 9 unmodified lines
48 47
49 const handleApproval = useCallback(async (approvalId: string, decision: "approved" | "denied") => {48 const handleApproval = useCallback(async (approvalId: string, decision: "approved" | "denied") => {
50 try {49 try {
51 await executor.api.approvals({ approvalId }).post({50 await resolveApproval({
52 workspaceId,51 workspaceId,
52 approvalId,
53 decision,53 decision,
54 });54 });
55 } catch (err) {55 } catch (err) {
56 console.error(`[approval ${approvalId}]`, err);56 console.error(`[approval ${approvalId}]`, err);
57 }57 }
58 }, [executor, workspaceId]);58 }, [resolveApproval, workspaceId]);
59 59
60 const accentColor = isDone60 const accentColor = isDone
61 ? status === "completed" ? 0x57f287 : 0xed424561 ? status === "completed" ? 0x57f287 : 0xed4245
assistant/packages/bot/tsconfig.json+1−2
@@ -8,8 +8,7 @@ · 7 unmodified lines
8 "esModuleInterop": true,8 "esModuleInterop": true,
9 "skipLibCheck": true,9 "skipLibCheck": true,
10 "paths": {10 "paths": {
11 "@executor/convex/*": ["../../../executor/convex/*"],11 "@executor/convex/*": ["../../../executor/convex/*"]
12 "@executor/server/*": ["../../../executor/apps/server/*"]
13 }12 }
14 },13 },
15 "include": ["src"]14 "include": ["src"]
assistant/packages/core/src/agent.ts+33−5
@@ -57,6 +57,23 @@ interface McpTool { · 56 unmodified lines
57 inputSchema?: Record<string, unknown>;57 inputSchema?: Record<string, unknown>;
58}58}
59 59
60async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T> {
61 let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
62 const timeoutPromise = new Promise<never>((_resolve, reject) => {
63 timeoutHandle = setTimeout(() => {
64 reject(new Error(`${label} timed out after ${timeoutMs}ms`));
65 }, timeoutMs);
66 });
67
68 try {
69 return await Promise.race([promise, timeoutPromise]);
70 } finally {
71 if (timeoutHandle) {
72 clearTimeout(timeoutHandle);
73 }
74 }
75}
76
60export interface AgentOptions {77export interface AgentOptions {
61 readonly executorUrl: string;78 readonly executorUrl: string;
62 readonly workspaceId: string;79 readonly workspaceId: string;
@@ -143,6 +160,12 @@ export function createAgent(options: AgentOptions) { · 80 unmodified lines
143 160
144 const resolvedApiKey = resolveApiKey(apiKey);161 const resolvedApiKey = resolveApiKey(apiKey);
145 const model = getModel("anthropic", modelId as never);162 const model = getModel("anthropic", modelId as never);
163 const executorBaseUrl = (() => {
164 const raw = executorUrl.trim().replace(/\/$/, "");
165 if (/^https?:\/\//.test(raw)) return raw;
166 if (raw.includes(".convex.cloud")) return raw.replace(".convex.cloud", ".convex.site");
167 throw new Error(`Invalid executorUrl: expected http(s) URL, got '${executorUrl}'`);
168 })();
146 169
147 async function generate(messages: Message[], tools: McpTool[]) {170 async function generate(messages: Message[], tools: McpTool[]) {
148 const { systemPrompt, piMessages } = toPiMessages(messages);171 const { systemPrompt, piMessages } = toPiMessages(messages);
@@ -167,7 +190,7 @@ export function createAgent(options: AgentOptions) { · 18 unmodified lines
167 190
168 // Connect to executor MCP191 // Connect to executor MCP
169 emit({ type: "status", message: "Connecting..." });192 emit({ type: "status", message: "Connecting..." });
170 const mcpUrl = new URL(`${executorUrl}/mcp`);193 const mcpUrl = new URL(`${executorBaseUrl}/mcp`);
171 mcpUrl.searchParams.set("workspaceId", workspaceId);194 mcpUrl.searchParams.set("workspaceId", workspaceId);
172 mcpUrl.searchParams.set("actorId", actorId);195 mcpUrl.searchParams.set("actorId", actorId);
173 if (clientId) mcpUrl.searchParams.set("clientId", clientId);196 if (clientId) mcpUrl.searchParams.set("clientId", clientId);
@@ -177,7 +200,7 @@ export function createAgent(options: AgentOptions) { · 3 unmodified lines
177 200
178 let mcpConnected = false;201 let mcpConnected = false;
179 try {202 try {
180 await mcp.connect(transport);203 await withTimeout(mcp.connect(transport), 20_000, "MCP connection");
181 mcpConnected = true;204 mcpConnected = true;
182 } catch (err) {205 } catch (err) {
183 const msg = `Failed to connect to executor MCP: ${err instanceof Error ? err.message : String(err)}`;206 const msg = `Failed to connect to executor MCP: ${err instanceof Error ? err.message : String(err)}`;
@@ -189,7 +212,7 @@ export function createAgent(options: AgentOptions) { · 5 unmodified lines
189 try {212 try {
190 // List tools213 // List tools
191 emit({ type: "status", message: "Loading tools..." });214 emit({ type: "status", message: "Loading tools..." });
192 const { tools: rawTools } = await mcp.listTools();215 const { tools: rawTools } = await withTimeout(mcp.listTools(), 20_000, "MCP listTools");
193 const tools: McpTool[] = rawTools.map((t) => ({216 const tools: McpTool[] = rawTools.map((t) => ({
194 name: t.name,217 name: t.name,
195 description: t.description,218 description: t.description,
@@ -219,6 +242,7 @@ ${toolSection} · 23 unmodified lines
219 242
220- Use the \`run_code\` tool to execute TypeScript code243- Use the \`run_code\` tool to execute TypeScript code
221- Write complete, self-contained scripts — do all work in a single run_code call when possible244- Write complete, self-contained scripts — do all work in a single run_code call when possible
245- TypeScript syntax is allowed; prefer simple runnable scripts over heavy type scaffolding
222- The code runs in a sandbox — only \`tools.*\` calls are available (no fetch, require, import)246- The code runs in a sandbox — only \`tools.*\` calls are available (no fetch, require, import)
223- Handle errors with try/catch247- Handle errors with try/catch
224- Return a structured result, then summarize what happened248- Return a structured result, then summarize what happened
@@ -235,7 +259,7 @@ ${toolSection} · 10 unmodified lines
235 259
236 // Agent loop260 // Agent loop
237 while (toolCallCount < maxToolCalls) {261 while (toolCallCount < maxToolCalls) {
238 const response = await generate(messages, tools);262 const response = await withTimeout(generate(messages, tools), 90_000, "Model response");
239 263
240 if (!response.toolCalls?.length) {264 if (!response.toolCalls?.length) {
241 const text = response.text ?? "";265 const text = response.text ?? "";
@@ -253,7 +277,11 @@ ${toolSection} · 11 unmodified lines
253 emit({ type: "status", message: `Running ${tc.name}...` });277 emit({ type: "status", message: `Running ${tc.name}...` });
254 278
255 // Call tool via MCP279 // Call tool via MCP
256 const result = await mcp.callTool({ name: tc.name, arguments: tc.args });280 const result = await withTimeout(
281 mcp.callTool({ name: tc.name, arguments: tc.args }),
282 120_000,
283 `MCP tool call (${tc.name})`,
284 );
257 const text = (result.content as Array<{ type: string; text?: string }>)285 const text = (result.content as Array<{ type: string; text?: string }>)
258 .filter((c) => c.type === "text" && c.text)286 .filter((c) => c.type === "text" && c.text)
259 .map((c) => c.text!)287 .map((c) => c.text!)
assistant/packages/server/package.json+1−2
@@ -4,8 +4,7 @@ · 3 unmodified lines
4 "type": "module",4 "type": "module",
5 "exports": {5 "exports": {
6 ".": "./src/index.ts",6 ".": "./src/index.ts",
7 "./client": "./src/client.ts",7 "./client": "./src/client.ts"
8 "./executor-client": "./src/executor-client.ts"
9 },8 },
10 "scripts": {9 "scripts": {
11 "dev": "bun --hot src/index.ts",10 "dev": "bun --hot src/index.ts",
assistant/packages/server/src/executor-client.ts+0−12
@@ -1,12 +0,0 @@
1/**
2 * Typed Eden Treaty client for the executor server.
3 */
4
5import { treaty } from "@elysiajs/eden";
6import type { App } from "@executor/server/src/index";
7
8export function createExecutorClient(baseUrl: string) {
9 return treaty<App>(baseUrl);
10}
11
12export type ExecutorClient = ReturnType<typeof createExecutorClient>;
assistant/packages/server/src/index.ts+38−8
@@ -3,21 +3,51 @@ · 2 unmodified lines
3 */3 */
4 4
5import { createApp } from "./routes";5import { createApp } from "./routes";
6import { createExecutorClient } from "./executor-client";6import { ConvexHttpClient } from "convex/browser";
7import { api } from "@executor/convex/_generated/api";
7 8
8const PORT = Number(Bun.env.PORT ?? 3000);9const PORT = Number(Bun.env.PORT ?? 3000);
9const EXECUTOR_URL = Bun.env.EXECUTOR_URL ?? "http://localhost:4001";
10const CONVEX_URL = Bun.env.CONVEX_URL ?? "http://127.0.0.1:3210";10const CONVEX_URL = Bun.env.CONVEX_URL ?? "http://127.0.0.1:3210";
11const EXECUTOR_URL = Bun.env.EXECUTOR_URL
12 ?? Bun.env.CONVEX_SITE_URL
13 ?? (CONVEX_URL.includes(".convex.cloud")
14 ? CONVEX_URL.replace(".convex.cloud", ".convex.site")
15 : CONVEX_URL);
16const PINNED_WORKSPACE_ID = Bun.env.EXECUTOR_WORKSPACE_ID?.trim();
17const PINNED_ACTOR_ID = Bun.env.EXECUTOR_ACTOR_ID?.trim();
18const PINNED_CLIENT_ID = Bun.env.EXECUTOR_CLIENT_ID?.trim();
19const ANON_SESSION_ID = Bun.env.EXECUTOR_ANON_SESSION_ID?.trim();
11 20
12// Bootstrap anonymous context on executor21// Bootstrap anonymous context on executor Convex backend
13const executor = createExecutorClient(EXECUTOR_URL);22const convex = new ConvexHttpClient(CONVEX_URL);
14const { data: ctx, error: bootstrapError } = await executor.api.auth.anonymous.bootstrap.post({});23let ctx: { workspaceId: string; actorId: string; clientId?: string };
15 24
16if (bootstrapError || !ctx) {25if (PINNED_WORKSPACE_ID && PINNED_ACTOR_ID) {
17 console.error("Failed to bootstrap executor context. Is the executor running at", EXECUTOR_URL, "?");26 ctx = {
18 process.exit(1);27 workspaceId: PINNED_WORKSPACE_ID,
28 actorId: PINNED_ACTOR_ID,
29 clientId: PINNED_CLIENT_ID,
30 };
31} else {
32 try {
33 const bootstrap = await convex.mutation(api.database.bootstrapAnonymousSession, {
34 sessionId: ANON_SESSION_ID,
35 });
36 ctx = {
37 workspaceId: bootstrap.workspaceId,
38 actorId: bootstrap.actorId,
39 clientId: PINNED_CLIENT_ID ?? bootstrap.clientId,
40 };
41 } catch (error) {
42 console.error("Failed to bootstrap executor context from Convex at", CONVEX_URL, error);
43 process.exit(1);
44 }
19}45}
46
20console.log(`[assistant] executor context: workspace=${ctx.workspaceId} actor=${ctx.actorId}`);47console.log(`[assistant] executor context: workspace=${ctx.workspaceId} actor=${ctx.actorId}`);
48if (ANON_SESSION_ID) {
49 console.log(`[assistant] executor anon session: ${ANON_SESSION_ID}`);
50}
21 51
22const contextLines: string[] = [];52const contextLines: string[] = [];
23if (Bun.env.POSTHOG_PROJECT_ID) contextLines.push(`- PostHog project ID: ${Bun.env.POSTHOG_PROJECT_ID}`);53if (Bun.env.POSTHOG_PROJECT_ID) contextLines.push(`- PostHog project ID: ${Bun.env.POSTHOG_PROJECT_ID}`);
assistant/packages/server/tsconfig.json+1−2
@@ -7,8 +7,7 @@ · 6 unmodified lines
7 "esModuleInterop": true,7 "esModuleInterop": true,
8 "skipLibCheck": true,8 "skipLibCheck": true,
9 "paths": {9 "paths": {
10 "@executor/convex/*": ["../../../executor/convex/*"],10 "@executor/convex/*": ["../../../executor/convex/*"]
11 "@executor/server/*": ["../../../executor/apps/server/*"]
12 }11 }
13 },12 },
14 "include": ["src"]13 "include": ["src"]
dev.ts+38−29
@@ -6,17 +6,15 @@ · 5 unmodified lines
6 * Starts:6 * Starts:
7 * 1. Convex cloud dev function push (once)7 * 1. Convex cloud dev function push (once)
8 * 2. Convex cloud dev function watcher8 * 2. Convex cloud dev function watcher
9 * 3. Executor server (port 4001)9 * 3. Executor web UI (port 3002)
10 * 4. Executor web UI (port 3002)10 * 4. Assistant server (port 3000)
11 * 5. Assistant server (port 3000)11 * 5. Discord bot
12 * 6. Discord bot
13 *12 *
14 * All processes are killed when this script exits (Ctrl+C).13 * All processes are killed when this script exits (Ctrl+C).
15 */14 */
16 15
17const colors = {16const colors = {
18 convex: "\x1b[36m", // cyan17 convex: "\x1b[36m", // cyan
19 executor: "\x1b[33m", // yellow
20 web: "\x1b[34m", // blue18 web: "\x1b[34m", // blue
21 assistant: "\x1b[32m", // green19 assistant: "\x1b[32m", // green
22 bot: "\x1b[35m", // magenta20 bot: "\x1b[35m", // magenta
@@ -31,9 +29,18 @@ function prefix(name: ServiceName, line: string): string { · 8 unmodified lines
31 29
32const procs: Bun.Subprocess[] = [];30const procs: Bun.Subprocess[] = [];
33 31
34async function resolveExecutorConvexUrl(): Promise<string> {32function toSiteUrl(convexUrl: string): string {
33 if (convexUrl.includes(".convex.cloud")) {
34 return convexUrl.replace(".convex.cloud", ".convex.site");
35 }
36 return convexUrl;
37}
38
39async function resolveExecutorUrls(): Promise<{ convexUrl: string; executorUrl: string }> {
35 if (Bun.env.CONVEX_URL) {40 if (Bun.env.CONVEX_URL) {
36 return Bun.env.CONVEX_URL;41 const convexUrl = Bun.env.CONVEX_URL;
42 const executorUrl = Bun.env.CONVEX_SITE_URL ?? toSiteUrl(convexUrl);
43 return { convexUrl, executorUrl };
37 }44 }
38 45
39 const envFile = Bun.file("./executor/.env.local");46 const envFile = Bun.file("./executor/.env.local");
@@ -42,20 +49,27 @@ async function resolveExecutorConvexUrl(): Promise<string> { · 2 unmodified lines
42 }49 }
43 50
44 const content = await envFile.text();51 const content = await envFile.text();
45 const line = content52 const lines = content
46 .split("\n")53 .split("\n")
47 .map((entry) => entry.trim())54 .map((entry) => entry.trim());
48 .find((entry) => entry.startsWith("CONVEX_URL="));
49 55
50 if (!line) {56 const convexLine = lines.find((entry) => entry.startsWith("CONVEX_URL="));
57 const siteLine = lines.find((entry) => entry.startsWith("CONVEX_SITE_URL="));
58
59 if (!convexLine) {
51 throw new Error("CONVEX_URL not found in executor/.env.local");60 throw new Error("CONVEX_URL not found in executor/.env.local");
52 }61 }
53 62
54 const url = line.slice("CONVEX_URL=".length).trim();63 const convexUrl = convexLine.slice("CONVEX_URL=".length).trim();
55 if (!url) {64 if (!convexUrl) {
56 throw new Error("CONVEX_URL is empty in executor/.env.local");65 throw new Error("CONVEX_URL is empty in executor/.env.local");
57 }66 }
58 return url;67
68 const executorUrl = siteLine
69 ? siteLine.slice("CONVEX_SITE_URL=".length).trim()
70 : toSiteUrl(convexUrl);
71
72 return { convexUrl, executorUrl };
59}73}
60 74
61function spawnService(name: ServiceName, cmd: string[], opts: {75function spawnService(name: ServiceName, cmd: string[], opts: {
@@ -147,8 +161,9 @@ if (!Bun.env.DISCORD_BOT_TOKEN) { · 85 unmodified lines
147// 1. Push functions (must complete before executor starts)161// 1. Push functions (must complete before executor starts)
148await pushConvexFunctions();162await pushConvexFunctions();
149 163
150const executorConvexUrl = await resolveExecutorConvexUrl();164const urls = await resolveExecutorUrls();
151console.log(prefix("convex", `Using deployment URL: ${executorConvexUrl}`));165console.log(prefix("convex", `Using Convex URL: ${urls.convexUrl}`));
166console.log(prefix("convex", `Using executor HTTP URL: ${urls.executorUrl}`));
152 167
153// 2. Start Convex file watcher (repushes on changes)168// 2. Start Convex file watcher (repushes on changes)
154spawnService("convex", [169spawnService("convex", [
@@ -159,26 +174,20 @@ spawnService("convex", [ · 4 unmodified lines
159});174});
160 175
161// 3. Everything else in parallel176// 3. Everything else in parallel
162spawnService("executor", ["bun", "--hot", "apps/server/src/index.ts"], {
163 cwd: "./executor",
164 env: {
165 EXECUTOR_SERVER_AUTO_EXECUTE: "1",
166 CONVEX_URL: executorConvexUrl,
167 EXECUTOR_CONVEX_URL: executorConvexUrl,
168 },
169});
170
171spawnService("web", ["bun", "run", "dev", "--", "-p", "3002"], {177spawnService("web", ["bun", "run", "dev", "--", "-p", "3002"], {
172 cwd: "./executor/apps/web",178 cwd: "./executor/apps/web",
173});179});
174 180
175// Small delay for executor to be ready181// Small delay for web to be ready
176await Bun.sleep(2000);182await Bun.sleep(1200);
177 183
178spawnService("assistant", ["bun", "run", "--cwd", "packages/server", "dev"], {184spawnService("assistant", ["bun", "run", "--cwd", "packages/server", "dev"], {
179 cwd: "./assistant",185 cwd: "./assistant",
180 env: {186 env: {
181 CONVEX_URL: executorConvexUrl,187 EXECUTOR_URL: urls.executorUrl,
188 CONVEX_URL: urls.convexUrl,
189 EXECUTOR_ANON_SESSION_ID: Bun.env.EXECUTOR_ANON_SESSION_ID ?? "assistant-discord-dev",
190 EXECUTOR_CLIENT_ID: Bun.env.EXECUTOR_CLIENT_ID ?? "bot",
182 },191 },
183});192});
184 193
@@ -187,7 +196,7 @@ if (Bun.env.DISCORD_BOT_TOKEN) { · 2 unmodified lines
187 spawnService("bot", ["bun", "run", "--cwd", "packages/bot", "dev"], {196 spawnService("bot", ["bun", "run", "--cwd", "packages/bot", "dev"], {
188 cwd: "./assistant",197 cwd: "./assistant",
189 env: {198 env: {
190 CONVEX_URL: executorConvexUrl,199 CONVEX_URL: urls.convexUrl,
191 },200 },
192 });201 });
193}202}
executor/README.md+13−150
@@ -1,152 +1,13 @@
1# Executor Monorepo1# Executor Monorepo
2 2
3Prototype executor control plane for running AI-generated code with tool-call approval gates.3Executor is now Convex-native.
4 4
5## What Is Here5## What is here
6 6
7- `apps/server`: Bun server with:7- `convex/`: executor control plane, MCP HTTP endpoint, task execution/actions, policies, credentials, approvals, and persistence.
8 - task execution API8- `convex/lib/`: runtime, MCP server helpers, typechecker, tool loading/discovery utilities.
9 - per-tool-call approval API9- `apps/web`: executor web UI for approvals, task history, and settings.
10 - internal runtime callback API10- `packages/contracts`: shared task/tool/policy contract types.
11 - Convex-backed task and approval history
12 - pluggable sandbox runtime interface
13 - separate worker process for queue execution
14- `apps/web`: web interface for:
15 - pending approvals
16 - task history
17 - task details/logs
18- `packages/contracts`: shared API/types
19- `packages/client`: lightweight client SDK for other consumers (including assistant-side integrations)
20
21## Architecture Notes
22
23- The runtime executes generated code and exposes a `tools.*` proxy to that code.
24- The generated-code runtime uses an `ExecutionAdapter` boundary for tool calls and output streaming.
25- Current default uses an in-process adapter; an HTTP adapter is also included for process/network boundaries.
26- Tools can be marked `auto` or `required` approval.
27- Required tools create approval records per function call (`toolPath` + `input`).
28- A built-in `tools.discover({ query, depth?, limit? })` helper is available so agents can search available tools at runtime.
29- Task execution pauses on required tool calls until that specific call is approved or denied.
30- Runtime targets are swappable by ID (`runtimeId`) so sandbox backends can change later.
31- Convex is used as the event/history store.
32
33Auth/tenancy design draft: `docs/auth-and-tenancy-model.md`
34
35## Anonymous Web Context (No Sign-In)
36
37The web client now bootstraps an anonymous session context before any task calls:
38
39- `POST /api/auth/anonymous/bootstrap`
40
41Response includes:
42
43- `sessionId`
44- `workspaceId`
45- `actorId`
46- `clientId`
47
48The browser persists `sessionId` and reuses it to maintain the same anonymous workspace/actor context.
49
50Legacy unscoped task/approval reads are disabled. Requests must include workspace context.
51
52## External Tool Sources (MCP + OpenAPI + GraphQL)
53
54You can load callable tools automatically from MCP servers and OpenAPI specs via env config:
55
56`EXECUTOR_TOOL_SOURCES` accepts a JSON array of source definitions.
57
58Example:
59
60```json
61[
62 {
63 "type": "mcp",
64 "name": "answeroverflow",
65 "url": "https://www.answeroverflow.com/mcp",
66 "defaultApproval": "auto"
67 },
68 {
69 "type": "openapi",
70 "name": "billing",
71 "spec": "https://example.com/openapi.json",
72 "baseUrl": "https://api.example.com",
73 "defaultReadApproval": "auto",
74 "defaultWriteApproval": "required"
75 }
76]
77```
78
79OpenAPI tools are generated as namespaced callables (`tools.<name>.<tag>.<operation>`), GraphQL sources expose `tools.<name>.graphql` plus discoverable pseudo-tools, and MCP tools are generated as (`tools.<name>.<tool>`).
80
81For MCP sources, optional config keys:
82
83- `transport`: `"streamable-http"` or `"sse"` (default auto-detect)
84- `queryParams`: object of query-string params appended to the MCP endpoint URL (useful for anonymous user scoping before OAuth auth provider integration)
85
86Example MCP config with query params:
87
88```json
89{
90 "type": "mcp",
91 "name": "my-mcp",
92 "url": "https://mcp.example.com/mcp",
93 "transport": "streamable-http",
94 "queryParams": {
95 "userId": "anon_123"
96 }
97}
98```
99
100OpenAPI auth modes in source config:
101
102- `mode: "static"` (token in source config)
103- `mode: "workspace"` (shared credential per workspace)
104- `mode: "actor"` (bring-your-own credential per actor)
105
106Credential and policy management endpoints:
107
108- `POST /api/policies` and `GET /api/policies?workspaceId=...`
109- `POST /api/credentials` and `GET /api/credentials?workspaceId=...`
110- `POST /api/tool-sources`, `GET /api/tool-sources?workspaceId=...`, and `DELETE /api/tool-sources/:sourceId?workspaceId=...`
111
112Tasks should include `workspaceId`, `actorId`, and optional `clientId` so policy and credential resolution can be applied per caller.
113
114The web UI supports adding MCP/OpenAPI sources per workspace and viewing discovered workspace tool inventory.
115
116## MCP Endpoint (`run_code`)
117
118The executor server also exposes an MCP endpoint at `/mcp` with a `run_code` tool.
119
120- tool name: `run_code`
121- required input: `code`
122- optional: `runtimeId`, `timeoutMs`, `workspaceId`, `actorId`, `clientId`, `sessionId`, `waitForResult`, `resultTimeoutMs`, `metadata`
123
124If `workspaceId` / `actorId` are omitted, executor bootstraps anonymous context (optionally keyed by `sessionId`).
125
126## Vercel Sandbox Runtime
127
128This repo includes a `vercel-sandbox` runtime that runs generated code in Vercel Sandbox VMs while keeping the same `await tools.*(...)` flow.
129
130Local setup:
131
132```bash
133vercel project add <project-name>
134vercel link --yes --project <project-name>
135vercel env pull .env.local --yes
136```
137
138Required runtime env:
139
140- `VERCEL_OIDC_TOKEN` (pulled by `vercel env pull`)
141- `EXECUTOR_INTERNAL_BASE_URL` (optional override for callback URL; if unset, server can auto-bootstrap a Tailscale Funnel URL in dev)
142
143Optional:
144
145- `EXECUTOR_INTERNAL_TOKEN` (shared bearer token for internal callback routes; auto-generated if unset)
146- `EXECUTOR_VERCEL_SANDBOX_RUNTIME` (`node22` by default, supports `node24`)
147- `EXECUTOR_AUTO_TAILSCALE_FUNNEL` (`1` by default; set `0` to disable automatic `tailscale funnel --bg` bootstrap)
148
149When creating tasks, set `runtimeId` to `vercel-sandbox` to use this backend.
150 11
151## Run12## Run
152 13
@@ -163,15 +24,17 @@ bun run dev:convex · 10 unmodified lines
163Terminal 2:24Terminal 2:
164 25
165```bash26```bash
166bun run dev27bun run dev:web
167```28```
168 29
169Terminal 3:30## Tests
170 31
171```bash32```bash
172bun run dev:worker33bun test convex/database.test.ts convex/executor-mcp.e2e.test.ts
173```34```
174 35
175Server defaults to `http://localhost:4001`. Worker is required unless `EXECUTOR_SERVER_AUTO_EXECUTE=1`.36## Notes
176 37
177`dev:convex` runs `convex dev --local`, so persistence stays local (no cloud deployment).38- MCP endpoint is served by Convex HTTP routes at `/mcp`.
39- Internal runtime callback routes are served by Convex HTTP routes at `/internal/runs/:runId/*`.
40- `run_code` supports TypeScript typechecking and runtime transpilation before execution.
executor/apps/server/package.json+0−28
@@ -1,28 +0,0 @@
1{
2 "name": "@executor/server",
3 "private": true,
4 "type": "module",
5 "dependencies": {
6 "@executor/contracts": "workspace:*",
7 "@apidevtools/swagger-parser": "^12.1.0",
8 "@modelcontextprotocol/sdk": "^1.26.0",
9 "@vercel/sandbox": "latest",
10 "convex": "^1.31.7",
11 "elysia": "^1.4.22",
12 "openapi-typescript": "^7.10.1",
13 "zod": "^4.3.6"
14 },
15 "scripts": {
16 "dev": "bun --hot src/index.ts",
17 "worker": "bun --hot src/worker.ts",
18 "start": "bun src/index.ts",
19 "cli": "bun src/cli.ts",
20 "test": "bun test",
21 "typecheck": "bunx tsc --noEmit"
22 },
23 "devDependencies": {
24 "@elysiajs/eden": "^1.4.6",
25 "@types/bun": "latest",
26 "typescript": "^5.9.3"
27 }
28}
executor/apps/server/src/_measure-descriptors.ts+0−84
@@ -1,84 +0,0 @@
1import { loadExternalTools } from "./tool-sources";
2import type { ExternalToolSourceConfig } from "./tool-sources";
3
4const sources: ExternalToolSourceConfig[] = [
5 {
6 type: "openapi",
7 name: "stripe",
8 spec: "https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json",
9 baseUrl: "https://api.stripe.com",
10 },
11];
12
13async function measure() {
14 console.log("Loading all sources concurrently...\n");
15 const start = performance.now();
16
17 // Load each source individually so we can measure per-source
18 const results = await Promise.allSettled(
19 sources.map(async (source) => {
20 const t0 = performance.now();
21 const { tools, warnings } = await loadExternalTools([source]);
22 const elapsed = performance.now() - t0;
23
24 // Build the ToolDescriptor[] (same shape the frontend gets)
25 const descriptors = tools.map((t) => ({
26 path: t.path,
27 description: t.description,
28 approval: t.approval,
29 source: t.source,
30 argsType: t.metadata?.argsType,
31 returnsType: t.metadata?.returnsType,
32 }));
33
34 const json = JSON.stringify(descriptors);
35 return {
36 name: source.name,
37 toolCount: tools.length,
38 jsonBytes: json.length,
39 elapsed,
40 warnings,
41 };
42 }),
43 );
44
45 const totalElapsed = performance.now() - start;
46
47 console.log("Source | Tools | JSON size | Time | Warnings");
48 console.log("---------------------|-------|---------------|----------|----------");
49
50 let totalTools = 0;
51 let totalBytes = 0;
52
53 for (const r of results) {
54 if (r.status === "fulfilled") {
55 const { name, toolCount, jsonBytes, elapsed, warnings } = r.value;
56 totalTools += toolCount;
57 totalBytes += jsonBytes;
58 const sizeStr = jsonBytes > 1024 * 1024
59 ? `${(jsonBytes / 1024 / 1024).toFixed(1)} MB`
60 : jsonBytes > 1024
61 ? `${(jsonBytes / 1024).toFixed(1)} KB`
62 : `${jsonBytes} B`;
63 console.log(
64 `${name.padEnd(20)} | ${String(toolCount).padStart(5)} | ${sizeStr.padStart(13)} | ${(elapsed / 1000).toFixed(1)}s`.padEnd(60) +
65 `| ${warnings.length > 0 ? warnings.join("; ") : "ok"}`,
66 );
67 } else {
68 const source = sources[results.indexOf(r)]!;
69 console.log(
70 `${source.name.padEnd(20)} | FAILED: ${r.reason instanceof Error ? r.reason.message.slice(0, 60) : String(r.reason).slice(0, 60)}`,
71 );
72 }
73 }
74
75 const totalSizeStr = totalBytes > 1024 * 1024
76 ? `${(totalBytes / 1024 / 1024).toFixed(1)} MB`
77 : `${(totalBytes / 1024).toFixed(1)} KB`;
78
79 console.log("---------------------|-------|---------------|----------|----------");
80 console.log(`TOTAL | ${String(totalTools).padStart(5)} | ${totalSizeStr.padStart(13)} | ${(totalElapsed / 1000).toFixed(1)}s`);
81 console.log(`\nAvg descriptor size: ${totalTools > 0 ? Math.round(totalBytes / totalTools) : 0} bytes/tool`);
82}
83
84measure().catch(console.error);
executor/apps/server/src/cli.test.ts+0−317
@@ -1,317 +0,0 @@
1/**
2 * E2E integration test for the executor.
3 *
4 * Starts the actual server as a subprocess (the same way users run it),
5 * connects a real MCP client, runs code that invokes tools, exercises
6 * the approval flow, and verifies Convex persistence.
7 *
8 * Requires the Convex local backend to already be running on port 3210.
9 */
10import { test, expect, afterAll } from "bun:test";
11import { Client } from "@modelcontextprotocol/sdk/client/index.js";
12import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
13import { ConvexClient } from "convex/browser";
14import { treaty } from "@elysiajs/eden";
15import type { App } from "./index";
16import { api } from "../../../convex/_generated/api";
17import { resolve } from "node:path";
18
19const SERVER_ENTRY = resolve(import.meta.dir, "index.ts");
20const CONVEX_URL = Bun.env.CONVEX_URL ?? "http://127.0.0.1:3210";
21const PORT = 4099;
22const BASE = `http://127.0.0.1:${PORT}`;
23
24let proc: Bun.Subprocess | null = null;
25let convex: ConvexClient | null = null;
26let executor: ReturnType<typeof treaty<App>>;
27
28afterAll(async () => {
29 proc?.kill();
30 await proc?.exited.catch(() => {});
31 proc = null;
32 await convex?.close();
33 convex = null;
34});
35
36// ── Helpers ──
37
38async function waitForHealth(timeoutMs = 30_000): Promise<void> {
39 const start = Date.now();
40 while (Date.now() - start < timeoutMs) {
41 try {
42 const resp = await fetch(`${BASE}/api/health`);
43 if (resp.ok) return;
44 } catch {}
45 await Bun.sleep(200);
46 }
47 throw new Error("Server did not become healthy");
48}
49
50function connectMcp(workspaceId: string, actorId: string) {
51 const url = new URL(`${BASE}/mcp?workspaceId=${workspaceId}&actorId=${actorId}`);
52 const transport = new StreamableHTTPClientTransport(url);
53 const client = new Client({ name: "e2e-test", version: "0.0.1" }, { capabilities: {} });
54 return { client, transport };
55}
56
57async function bootstrap(): Promise<{ workspaceId: string; actorId: string; sessionId: string }> {
58 const { data, error } = await executor.api.auth.anonymous.bootstrap.post({});
59 if (error) throw error;
60 return data!;
61}
62
63/** Subscribe to Convex and resolve the instant a pending approval for `toolPath` appears. */
64function waitForApproval(workspaceId: string, toolPath: string, timeoutMs = 20_000): Promise<string> {
65 return new Promise<string>((resolve, reject) => {
66 const timer = setTimeout(() => {
67 sub.unsubscribe();
68 reject(new Error(`No pending approval for ${toolPath} within ${timeoutMs}ms`));
69 }, timeoutMs);
70
71 const sub = convex!.onUpdate(
72 api.database.listPendingApprovals,
73 { workspaceId },
74 (approvals) => {
75 const found = approvals.find((a: any) => a.toolPath === toolPath);
76 if (found) {
77 clearTimeout(timer);
78 sub.unsubscribe();
79 resolve(found.id);
80 }
81 },
82 (error) => {
83 clearTimeout(timer);
84 sub.unsubscribe();
85 reject(error);
86 },
87 );
88 });
89}
90
91/** Subscribe to Convex and resolve the instant the task reaches a terminal state. */
92function waitForTask(
93 taskId: string,
94 timeoutMs = 15_000,
95): Promise<{ status: string; stdout?: string }> {
96 return new Promise((resolve, reject) => {
97 const timer = setTimeout(() => {
98 sub.unsubscribe();
99 reject(new Error(`Task ${taskId} did not complete within ${timeoutMs}ms`));
100 }, timeoutMs);
101
102 const sub = convex!.onUpdate(
103 api.database.getTask,
104 { taskId },
105 (task) => {
106 if (!task) return;
107 if (task.status === "completed" || task.status === "failed" || task.status === "denied") {
108 clearTimeout(timer);
109 sub.unsubscribe();
110 resolve(task as any);
111 }
112 },
113 (error) => {
114 clearTimeout(timer);
115 sub.unsubscribe();
116 reject(error);
117 },
118 );
119 });
120}
121
122// ── Start the server once for all tests ──
123
124test("server starts", async () => {
125 convex = new ConvexClient(CONVEX_URL, { unsavedChangesWarning: false });
126
127 proc = Bun.spawn(["bun", SERVER_ENTRY], {
128 stdout: "inherit",
129 stderr: "inherit",
130 env: {
131 ...Bun.env,
132 PORT: String(PORT),
133 EXECUTOR_SERVER_AUTO_EXECUTE: "1",
134 EXECUTOR_AUTO_TAILSCALE_FUNNEL: "0",
135 },
136 });
137
138 await waitForHealth();
139
140 executor = treaty<App>(BASE);
141
142 const { data: health } = await executor.api.health.get();
143 expect(health!.ok).toBe(true);
144 expect(health!.tools).toBeGreaterThan(0);
145}, 45_000);
146
147// ── MCP ──
148
149test("MCP client lists tools including run_code", async () => {
150 const session = await bootstrap();
151 const { client, transport } = connectMcp(session.workspaceId, session.actorId);
152 try {
153 await client.connect(transport);
154 const { tools } = await client.listTools();
155 expect(tools.map((t) => t.name)).toContain("run_code");
156 } finally {
157 await transport.close().catch(() => {});
158 await client.close().catch(() => {});
159 }
160}, 15_000);
161
162test("run_code executes plain code and returns result", async () => {
163 const session = await bootstrap();
164 const { client, transport } = connectMcp(session.workspaceId, session.actorId);
165 try {
166 await client.connect(transport);
167 const result = (await client.callTool({
168 name: "run_code",
169 arguments: { code: "return 40 + 2" },
170 })) as { content: Array<{ type: string; text?: string }>; isError?: boolean };
171
172 expect(result.isError).toBeFalsy();
173 const text = result.content.find((c) => c.type === "text")?.text ?? "";
174 expect(text).toContain("completed");
175 expect(text).toContain("42");
176 } finally {
177 await transport.close().catch(() => {});
178 await client.close().catch(() => {});
179 }
180}, 30_000);
181
182test("run_code calls sandbox tool (math.add) in-band", async () => {
183 const session = await bootstrap();
184 const { client, transport } = connectMcp(session.workspaceId, session.actorId);
185 try {
186 await client.connect(transport);
187 const result = (await client.callTool({
188 name: "run_code",
189 arguments: {
190 code: `const sum = await tools.math.add({ a: 17, b: 25 }); return sum;`,
191 },
192 })) as { content: Array<{ type: string; text?: string }> };
193
194 const text = result.content.find((c) => c.type === "text")?.text ?? "";
195 expect(text).toContain("completed");
196 expect(text).toContain("42");
197 } finally {
198 await transport.close().catch(() => {});
199 await client.close().catch(() => {});
200 }
201}, 30_000);
202
203// ── Approval flow ──
204
205test("approval-required tool blocks until approved", async () => {
206 const session = await bootstrap();
207 const { client, transport } = connectMcp(session.workspaceId, session.actorId);
208 try {
209 await client.connect(transport);
210
211 // Fire off code that hits the approval gate — don't await
212 const resultP = client.callTool({
213 name: "run_code",
214 arguments: {
215 code: `return await tools.admin.send_announcement({ channel: "general", message: "hello from e2e" });`,
216 },
217 });
218
219 // Convex subscription resolves instantly when the approval appears
220 const approvalId = await waitForApproval(session.workspaceId, "admin.send_announcement");
221
222 // Approve it
223 const { data: approveResult } = await executor.api.approvals({ approvalId }).post({
224 workspaceId: session.workspaceId,
225 decision: "approved",
226 reviewerId: "e2e-test",
227 });
228 expect(approveResult).toBeTruthy();
229
230 // Now the tool call completes
231 const result = (await resultP) as {
232 content: Array<{ type: string; text?: string }>;
233 isError?: boolean;
234 };
235 expect(result.isError).toBeFalsy();
236 const text = result.content.find((c) => c.type === "text")?.text ?? "";
237 expect(text).toContain("completed");
238 expect(text).toContain("hello from e2e");
239 } finally {
240 await transport.close().catch(() => {});
241 await client.close().catch(() => {});
242 }
243}, 45_000);
244
245test("denied approval propagates failure", async () => {
246 const session = await bootstrap();
247 const { client, transport } = connectMcp(session.workspaceId, session.actorId);
248 try {
249 await client.connect(transport);
250
251 const resultP = client.callTool({
252 name: "run_code",
253 arguments: {
254 code: `return await tools.admin.delete_data({ key: "important" });`,
255 },
256 });
257
258 const approvalId = await waitForApproval(session.workspaceId, "admin.delete_data");
259
260 await executor.api.approvals({ approvalId }).post({
261 workspaceId: session.workspaceId,
262 decision: "denied",
263 reason: "too dangerous",
264 });
265
266 const result = (await resultP) as {
267 content: Array<{ type: string; text?: string }>;
268 };
269 const text = result.content.find((c) => c.type === "text")?.text ?? "";
270 expect(text).toContain("denied");
271 } finally {
272 await transport.close().catch(() => {});
273 await client.close().catch(() => {});
274 }
275}, 45_000);
276
277// ── Convex persistence ──
278
279test("tasks are persisted and queryable via Convex subscription", async () => {
280 const session = await bootstrap();
281
282 // Create via REST
283 const { data: created, error: createError } = await executor.api.tasks.post({
284 code: "return 'persisted'",
285 workspaceId: session.workspaceId,
286 actorId: session.actorId,
287 });
288 if (createError) throw createError;
289 const taskId = created!.taskId as string;
290
291 // Wait for completion via Convex subscription — no polling
292 const task = await waitForTask(taskId);
293 expect(task.status).toBe("completed");
294 expect(task.stdout).toContain("persisted");
295
296 // Verify it shows up in the list via REST
297 const { data: tasks, error: listError } = await executor.api.tasks.get({
298 query: { workspaceId: session.workspaceId },
299 });
300 if (listError) throw listError;
301 expect(tasks!.some((t) => t.id === taskId)).toBe(true);
302}, 30_000);
303
304// ── Shutdown ──
305
306test("clean shutdown", async () => {
307 expect(proc).toBeTruthy();
308 proc!.kill();
309 const exitCode = await proc!.exited;
310 proc = null;
311 expect(typeof exitCode).toBe("number");
312
313 // Verify it's actually down
314 await Bun.sleep(300);
315 const dead = await fetch(`${BASE}/api/health`).catch(() => null);
316 expect(dead).toBeNull();
317}, 10_000);
executor/apps/server/src/cli.ts+0−536
@@ -1,536 +0,0 @@
1/**
2 * Executor CLI — starts the local Convex backend, pushes functions, and launches the executor server.
3 *
4 * Usage:
5 * bun executor/apps/server/src/cli.ts start [--port 4001] [--convex-port 3210]
6 * bun executor/apps/server/src/cli.ts start --auto-execute
7 *
8 * The CLI manages 3 concerns:
9 * 1. convex-local-backend binary (download if missing, launch, wait for ready)
10 * 2. Convex function push (bundle + deploy schema/functions via `convex dev --once`)
11 * 3. Executor server (the Elysia HTTP + MCP server)
12 */
13
14import { existsSync } from "node:fs";
15import { mkdir, chmod, readdir, rm, rename } from "node:fs/promises";
16import { join, resolve } from "node:path";
17import { homedir, platform, arch } from "node:os";
18
19// ── Config ──
20
21const CONVEX_REPO = "get-convex/convex-backend";
22const GITHUB_RELEASES_API = `https://api.github.com/repos/${CONVEX_REPO}/releases`;
23
24interface CliOptions {
25 port: number;
26 convexPort: number;
27 convexSitePort: number;
28 autoExecute: boolean;
29 dataDir: string;
30}
31
32function parseArgs(args: string[]): { command: string; options: CliOptions } {
33 const command = args[0] ?? "start";
34 const options: CliOptions = {
35 port: 4001,
36 convexPort: 3210,
37 convexSitePort: 3211,
38 autoExecute: false,
39 dataDir: join(homedir(), ".executor"),
40 };
41
42 for (let i = 1; i < args.length; i++) {
43 const arg = args[i];
44 switch (arg) {
45 case "--port":
46 options.port = Number(args[++i]);
47 break;
48 case "--convex-port":
49 options.convexPort = Number(args[++i]);
50 break;
51 case "--auto-execute":
52 options.autoExecute = true;
53 break;
54 case "--data-dir":
55 options.dataDir = args[++i];
56 break;
57 }
58 }
59
60 return { command, options };
61}
62
63// ── Logging ──
64
65const colors = {
66 cyan: "\x1b[36m",
67 yellow: "\x1b[33m",
68 green: "\x1b[32m",
69 red: "\x1b[31m",
70 dim: "\x1b[2m",
71 reset: "\x1b[0m",
72 bold: "\x1b[1m",
73};
74
75function log(msg: string) {
76 console.log(`${colors.cyan}[executor]${colors.reset} ${msg}`);
77}
78
79function logStep(step: string) {
80 console.log(`\n${colors.bold}${colors.green}▸${colors.reset} ${step}`);
81}
82
83function logError(msg: string) {
84 console.error(`${colors.red}[executor]${colors.reset} ${msg}`);
85}
86
87// ── Platform detection ──
88
89function getArtifactName(): string {
90 const p = platform();
91 const a = arch();
92
93 const map: Record<string, Record<string, string>> = {
94 darwin: {
95 arm64: "convex-local-backend-aarch64-apple-darwin.zip",
96 x64: "convex-local-backend-x86_64-apple-darwin.zip",
97 },
98 linux: {
99 arm64: "convex-local-backend-aarch64-unknown-linux-gnu.zip",
100 x64: "convex-local-backend-x86_64-unknown-linux-gnu.zip",
101 },
102 win32: {
103 x64: "convex-local-backend-x86_64-pc-windows-msvc.zip",
104 },
105 };
106
107 const artifact = map[p]?.[a];
108 if (!artifact) {
109 throw new Error(`Unsupported platform: ${p}/${a}`);
110 }
111 return artifact;
112}
113
114function getBinaryName(): string {
115 return platform() === "win32" ? "convex-local-backend.exe" : "convex-local-backend";
116}
117
118// ── Binary management ──
119
120function getBinariesDir(): string {
121 return join(homedir(), ".cache", "convex", "binaries");
122}
123
124async function findLatestVersion(artifactName: string): Promise<string> {
125 log("Checking for latest convex-local-backend release...");
126
127 let url: string | null = `${GITHUB_RELEASES_API}?per_page=30`;
128
129 while (url) {
130 const resp = await fetch(url, {
131 headers: {
132 Accept: "application/vnd.github.v3+json",
133 "User-Agent": "executor-cli",
134 },
135 });
136
137 if (!resp.ok) {
138 throw new Error(`GitHub API returned ${resp.status}: ${await resp.text()}`);
139 }
140
141 const releases = (await resp.json()) as Array<{
142 tag_name: string;
143 prerelease: boolean;
144 draft: boolean;
145 assets: Array<{ name: string }>;
146 }>;
147
148 for (const release of releases) {
149 if (release.prerelease || release.draft) continue;
150 if (release.assets.some((a) => a.name === artifactName)) {
151 return release.tag_name;
152 }
153 }
154
155 // Follow pagination
156 const link = resp.headers.get("link");
157 const next = link?.match(/<([^>]+)>;\s*rel="next"/);
158 url = next ? next[1] : null;
159 }
160
161 throw new Error("No convex-local-backend release found for this platform");
162}
163
164async function ensureBinary(): Promise<string> {
165 const artifactName = getArtifactName();
166 const binaryName = getBinaryName();
167 const binDir = getBinariesDir();
168
169 // Check if any version is already cached
170 if (existsSync(binDir)) {
171 const entries = await readdir(binDir);
172 for (const entry of entries) {
173 const binaryPath = join(binDir, entry, binaryName);
174 if (existsSync(binaryPath)) {
175 log(`Using cached binary: ${binaryPath}`);
176 return binaryPath;
177 }
178 }
179 }
180
181 // Download latest
182 const version = await findLatestVersion(artifactName);
183 const versionDir = join(binDir, version);
184 const binaryPath = join(versionDir, binaryName);
185
186 if (existsSync(binaryPath)) {
187 return binaryPath;
188 }
189
190 log(`Downloading convex-local-backend ${version}...`);
191 const downloadUrl = `https://github.com/${CONVEX_REPO}/releases/download/${version}/${artifactName}`;
192
193 const resp = await fetch(downloadUrl, { redirect: "follow" });
194 if (!resp.ok) {
195 throw new Error(`Download failed: ${resp.status} ${resp.statusText}`);
196 }
197
198 // Extract zip
199 const zipBuffer = await resp.arrayBuffer();
200 const tmpDir = join(binDir, `_tmp_${Date.now()}`);
201 await mkdir(tmpDir, { recursive: true });
202 const tmpZip = join(tmpDir, "download.zip");
203 await Bun.write(tmpZip, zipBuffer);
204
205 // Use unzip to extract
206 const unzip = Bun.spawn(["unzip", "-o", tmpZip, "-d", tmpDir], {
207 stdout: "ignore",
208 stderr: "pipe",
209 });
210 await unzip.exited;
211
212 // Find the binary in extracted files
213 const extracted = await readdir(tmpDir);
214 const foundBinary = extracted.find((f) => f === binaryName || f === "convex-local-backend");
215 if (!foundBinary) {
216 throw new Error(`Binary not found in zip. Contents: ${extracted.join(", ")}`);
217 }
218
219 await mkdir(versionDir, { recursive: true });
220 await rename(join(tmpDir, foundBinary), binaryPath);
221 await chmod(binaryPath, 0o755);
222
223 // Cleanup
224 await rm(tmpDir, { recursive: true, force: true });
225
226 log(`Downloaded to ${binaryPath}`);
227 return binaryPath;
228}
229
230// ── Convex backend lifecycle ──
231
232interface BackendInfo {
233 proc: Bun.Subprocess;
234 url: string;
235 adminKey: string;
236 instanceName: string;
237}
238
239async function waitForBackend(url: string, timeoutMs = 30_000): Promise<void> {
240 const start = Date.now();
241 while (Date.now() - start < timeoutMs) {
242 try {
243 const resp = await fetch(`${url}/instance_name`);
244 if (resp.ok) return;
245 } catch {
246 // not ready yet
247 }
248 await Bun.sleep(200);
249 }
250 throw new Error(`Convex backend did not become ready within ${timeoutMs}ms`);
251}
252
253async function readBackendConfig(
254 instanceName: string,
255): Promise<{ adminKey: string; ports: { cloud: number; site: number } }> {
256 // Check both project-linked and anonymous state dirs
257 const stateBaseDirs = [
258 join(homedir(), ".convex", "convex-backend-state"),
259 join(homedir(), ".convex", "anonymous-convex-backend-state"),
260 ];
261
262 for (const baseDir of stateBaseDirs) {
263 const configPath = join(baseDir, instanceName, "config.json");
264 if (existsSync(configPath)) {
265 const config = await Bun.file(configPath).json();
266 return config;
267 }
268 }
269
270 throw new Error(
271 `Could not find backend config for instance '${instanceName}'. Checked: ${stateBaseDirs.map((d) => join(d, instanceName)).join(", ")}`,
272 );
273}
274
275async function startBackend(binaryPath: string, port: number): Promise<BackendInfo> {
276 logStep("Starting Convex local backend...");
277
278 // Check if already running
279 try {
280 const resp = await fetch(`http://127.0.0.1:${port}/instance_name`);
281 if (resp.ok) {
282 const instanceName = await resp.text();
283 log(`Backend already running: ${instanceName}`);
284 const config = await readBackendConfig(instanceName);
285 return {
286 proc: null as any, // Not our process
287 url: `http://127.0.0.1:${port}`,
288 adminKey: config.adminKey,
289 instanceName,
290 };
291 }
292 } catch {
293 // Not running, start it
294 }
295
296 const proc = Bun.spawn([binaryPath, "--port", String(port)], {
297 stdout: "pipe",
298 stderr: "pipe",
299 env: { ...Bun.env },
300 });
301
302 // Stream backend output with prefix
303 const streamLines = async (stream: ReadableStream<Uint8Array>) => {
304 const reader = stream.getReader();
305 const decoder = new TextDecoder();
306 let buffer = "";
307 while (true) {
308 const { done, value } = await reader.read();
309 if (done) break;
310 buffer += decoder.decode(value, { stream: true });
311 const lines = buffer.split("\n");
312 buffer = lines.pop() ?? "";
313 for (const line of lines) {
314 if (line.trim()) {
315 console.log(`${colors.dim}[convex]${colors.reset} ${line}`);
316 }
317 }
318 }
319 };
320
321 streamLines(proc.stdout);
322 streamLines(proc.stderr);
323
324 log(`Waiting for backend on port ${port}...`);
325 await waitForBackend(`http://127.0.0.1:${port}`);
326
327 const resp = await fetch(`http://127.0.0.1:${port}/instance_name`);
328 const instanceName = await resp.text();
329 log(`Backend ready: ${instanceName}`);
330
331 const config = await readBackendConfig(instanceName);
332
333 return {
334 proc,
335 url: `http://127.0.0.1:${port}`,
336 adminKey: config.adminKey,
337 instanceName,
338 };
339}
340
341// ── Push functions ──
342
343async function pushFunctions(backendUrl: string, adminKey: string): Promise<void> {
344 logStep("Pushing Convex functions...");
345
346 const convexDir = resolve(import.meta.dir, "../../../");
347 log(`Convex project dir: ${convexDir}`);
348
349 // Write a temp env file so `convex dev --once` doesn't touch .env.local.
350 // Using --env-file with CONVEX_SELF_HOSTED_URL/ADMIN_KEY bypasses all
351 // local backend management and avoids the "already running" error.
352 const tmpEnvFile = join(convexDir, ".env.executor-push");
353 await Bun.write(
354 tmpEnvFile,
355 [
356 `CONVEX_SELF_HOSTED_URL=${backendUrl}`,
357 `CONVEX_SELF_HOSTED_ADMIN_KEY=${adminKey}`,
358 ].join("\n"),
359 );
360
361 try {
362 // Strip CONVEX_DEPLOYMENT from env to avoid conflicts — the env file provides the target.
363 const cleanEnv = { ...Bun.env };
364 delete cleanEnv.CONVEX_DEPLOYMENT;
365
366 const proc = Bun.spawn(
367 [
368 "bunx",
369 "convex",
370 "dev",
371 "--once",
372 "--typecheck",
373 "disable",
374 "--codegen",
375 "disable",
376 "--env-file",
377 tmpEnvFile,
378 ],
379 {
380 cwd: convexDir,
381 stdout: "pipe",
382 stderr: "pipe",
383 env: cleanEnv,
384 },
385 );
386
387 const stdout = await Bun.readableStreamToText(proc.stdout);
388 const stderr = await Bun.readableStreamToText(proc.stderr);
389 const exitCode = await proc.exited;
390
391 if (stdout.trim()) log(stdout.trim());
392 if (stderr.trim() && exitCode !== 0) logError(stderr.trim());
393
394 if (exitCode !== 0) {
395 throw new Error(`Function push failed with exit code ${exitCode}`);
396 }
397
398 log("Functions pushed successfully");
399 } finally {
400 // Clean up temp env file
401 try {
402 await rm(tmpEnvFile, { force: true });
403 } catch {}
404 }
405}
406
407// ── Executor server ──
408
409async function startServer(options: CliOptions, backendUrl: string): Promise<Bun.Subprocess> {
410 logStep("Starting executor server...");
411
412 const serverEntry = resolve(import.meta.dir, "index.ts");
413
414 const proc = Bun.spawn(["bun", "--hot", serverEntry], {
415 stdout: "pipe",
416 stderr: "pipe",
417 env: {
418 ...Bun.env,
419 PORT: String(options.port),
420 CONVEX_URL: backendUrl,
421 EXECUTOR_SERVER_AUTO_EXECUTE: options.autoExecute ? "1" : "0",
422 },
423 });
424
425 const streamLines = async (stream: ReadableStream<Uint8Array>, isStderr: boolean) => {
426 const reader = stream.getReader();
427 const decoder = new TextDecoder();
428 let buffer = "";
429 while (true) {
430 const { done, value } = await reader.read();
431 if (done) break;
432 buffer += decoder.decode(value, { stream: true });
433 const lines = buffer.split("\n");
434 buffer = lines.pop() ?? "";
435 for (const line of lines) {
436 if (line.trim()) {
437 const out = isStderr ? process.stderr : process.stdout;
438 out.write(`${colors.yellow}[server]${colors.reset} ${line}\n`);
439 }
440 }
441 }
442 };
443
444 streamLines(proc.stdout, false);
445 streamLines(proc.stderr, true);
446
447 // Wait for server to be ready
448 const start = Date.now();
449 while (Date.now() - start < 15_000) {
450 try {
451 const resp = await fetch(`http://127.0.0.1:${options.port}/api/health`);
452 if (resp.ok) {
453 log(`Server ready on port ${options.port}`);
454 return proc;
455 }
456 } catch {
457 // not ready
458 }
459 await Bun.sleep(200);
460 }
461
462 throw new Error("Executor server did not become ready within 15s");
463}
464
465// ── Main ──
466
467async function main() {
468 const { command, options } = parseArgs(process.argv.slice(2));
469
470 if (command !== "start") {
471 console.log(`
472${colors.bold}executor${colors.reset} — local code execution server
473
474Usage:
475 executor start [options]
476
477Options:
478 --port <n> Executor server port (default: 4001)
479 --convex-port <n> Convex backend port (default: 3210)
480 --auto-execute Auto-execute tasks on creation
481 --data-dir <path> Data directory (default: ~/.executor)
482`);
483 process.exit(command === "help" || command === "--help" ? 0 : 1);
484 }
485
486 console.log(`\n${colors.bold}${colors.cyan}executor${colors.reset} starting up...\n`);
487
488 const procs: Bun.Subprocess[] = [];
489
490 const cleanup = () => {
491 console.log(`\n${colors.dim}Shutting down...${colors.reset}`);
492 for (const p of procs) {
493 try {
494 p.kill();
495 } catch {}
496 }
497 process.exit(0);
498 };
499
500 process.on("SIGINT", cleanup);
501 process.on("SIGTERM", cleanup);
502
503 try {
504 // 1. Ensure convex-local-backend binary
505 logStep("Checking convex-local-backend binary...");
506 const binaryPath = await ensureBinary();
507
508 // 2. Start (or connect to) convex backend
509 const backend = await startBackend(binaryPath, options.convexPort);
510 if (backend.proc) procs.push(backend.proc);
511
512 // 3. Push functions
513 await pushFunctions(backend.url, backend.adminKey);
514
515 // 4. Start executor server
516 const serverProc = await startServer(options, backend.url);
517 procs.push(serverProc);
518
519 console.log(`
520${colors.bold}${colors.green}✓ Executor ready${colors.reset}
521
522 Server: http://127.0.0.1:${options.port}
523 MCP: http://127.0.0.1:${options.port}/mcp
524 Convex: ${backend.url}
525 Instance: ${backend.instanceName}
526`);
527
528 // Keep alive
529 await new Promise(() => {});
530 } catch (error) {
531 logError(error instanceof Error ? error.message : String(error));
532 cleanup();
533 }
534}
535
536main();
executor/apps/server/src/database.ts+0−236
@@ -1,236 +0,0 @@
1import { ConvexHttpClient } from "convex/browser";
2import type {
3 AccessPolicyRecord,
4 AnonymousContext,
5 ApprovalRecord,
6 ApprovalStatus,
7 CredentialRecord,
8 CredentialScope,
9 PendingApprovalRecord,
10 PolicyDecision,
11 TaskEventRecord,
12 TaskRecord,
13 TaskStatus,
14 ToolSourceRecord,
15} from "./types";
16
17const DEFAULT_CONVEX_URL = "http://127.0.0.1:3210";
18
19type MutationName =
20 | "database:createTask"
21 | "database:markTaskRunning"
22 | "database:markTaskFinished"
23 | "database:createApproval"
24 | "database:resolveApproval"
25 | "database:bootstrapAnonymousSession"
26 | "database:upsertAccessPolicy"
27 | "database:upsertCredential"
28 | "database:upsertToolSource"
29 | "database:deleteToolSource"
30 | "database:createTaskEvent";
31
32type QueryName =
33 | "database:getTask"
34 | "database:listTasks"
35 | "database:listQueuedTaskIds"
36 | "database:listRuntimeTargets"
37 | "database:getTaskInWorkspace"
38 | "database:getApproval"
39 | "database:listApprovals"
40 | "database:listPendingApprovals"
41 | "database:getApprovalInWorkspace"
42 | "database:listAccessPolicies"
43 | "database:listCredentials"
44 | "database:resolveCredential"
45 | "database:listToolSources"
46 | "database:listTaskEvents";
47
48export class ExecutorDatabase {
49 private readonly client: ConvexHttpClient;
50
51 constructor(convexUrl = Bun.env.EXECUTOR_CONVEX_URL ?? Bun.env.CONVEX_URL ?? DEFAULT_CONVEX_URL) {
52 this.client = new ConvexHttpClient(convexUrl);
53 }
54
55 // The `as never` casts below are intentional. ConvexHttpClient.mutation() and
56 // .query() expect the exact generated function reference type and its
57 // corresponding args type. Because we call them dynamically with string
58 // function names (e.g. "database:createTask") and generic arg objects,
59 // TypeScript cannot verify the relationship between name and args at the
60 // call site. Properly typing this would require a discriminated-union
61 // overload map for every Convex function, which adds significant
62 // complexity for little safety gain — the real type safety lives in the
63 // public method signatures of this class and the Convex handler
64 // definitions themselves.
65 private async mutation<TArgs extends Record<string, unknown>, TResult>(
66 name: MutationName,
67 args: TArgs,
68 ): Promise<TResult> {
69 return (await this.client.mutation(name as never, args as never)) as TResult;
70 }
71
72 private async query<TArgs extends Record<string, unknown>, TResult>(
73 name: QueryName,
74 args: TArgs,
75 ): Promise<TResult> {
76 return (await this.client.query(name as never, args as never)) as TResult;
77 }
78
79 async createTask(params: {
80 id: string;
81 code: string;
82 runtimeId: string;
83 timeoutMs?: number;
84 metadata?: Record<string, unknown>;
85 workspaceId: string;
86 actorId: string;
87 clientId?: string;
88 }): Promise<TaskRecord> {
89 return await this.mutation("database:createTask", params);
90 }
91
92 async getTask(taskId: string): Promise<TaskRecord | null> {
93 return await this.query("database:getTask", { taskId });
94 }
95
96 async listTasks(workspaceId: string): Promise<TaskRecord[]> {
97 return await this.query("database:listTasks", { workspaceId });
98 }
99
100 async listQueuedTaskIds(limit = 20): Promise<string[]> {
101 return await this.query("database:listQueuedTaskIds", { limit });
102 }
103
104 async listRuntimeTargets(): Promise<Array<{ id: string; label: string; description: string }>> {
105 return await this.query("database:listRuntimeTargets", {});
106 }
107
108 async getTaskInWorkspace(taskId: string, workspaceId: string): Promise<TaskRecord | null> {
109 return await this.query("database:getTaskInWorkspace", { taskId, workspaceId });
110 }
111
112 async markTaskRunning(taskId: string): Promise<TaskRecord | null> {
113 return await this.mutation("database:markTaskRunning", { taskId });
114 }
115
116 async markTaskFinished(params: {
117 taskId: string;
118 status: Extract<TaskStatus, "completed" | "failed" | "timed_out" | "denied">;
119 stdout: string;
120 stderr: string;
121 exitCode?: number;
122 error?: string;
123 }): Promise<TaskRecord | null> {
124 return await this.mutation("database:markTaskFinished", params);
125 }
126
127 async createApproval(params: {
128 id: string;
129 taskId: string;
130 toolPath: string;
131 input: unknown;
132 }): Promise<ApprovalRecord> {
133 return await this.mutation("database:createApproval", params);
134 }
135
136 async getApproval(approvalId: string): Promise<ApprovalRecord | null> {
137 return await this.query("database:getApproval", { approvalId });
138 }
139
140 async listApprovals(workspaceId: string, status?: ApprovalStatus): Promise<ApprovalRecord[]> {
141 return await this.query("database:listApprovals", { workspaceId, status });
142 }
143
144 async listPendingApprovals(workspaceId: string): Promise<PendingApprovalRecord[]> {
145 return await this.query("database:listPendingApprovals", { workspaceId });
146 }
147
148 async resolveApproval(params: {
149 approvalId: string;
150 decision: Exclude<ApprovalStatus, "pending">;
151 reviewerId?: string;
152 reason?: string;
153 }): Promise<ApprovalRecord | null> {
154 return await this.mutation("database:resolveApproval", params);
155 }
156
157 async getApprovalInWorkspace(approvalId: string, workspaceId: string): Promise<ApprovalRecord | null> {
158 return await this.query("database:getApprovalInWorkspace", { approvalId, workspaceId });
159 }
160
161 async bootstrapAnonymousSession(sessionId?: string): Promise<AnonymousContext> {
162 return await this.mutation("database:bootstrapAnonymousSession", { sessionId });
163 }
164
165 async upsertAccessPolicy(params: {
166 id?: string;
167 workspaceId: string;
168 actorId?: string;
169 clientId?: string;
170 toolPathPattern: string;
171 decision: PolicyDecision;
172 priority?: number;
173 }): Promise<AccessPolicyRecord> {
174 return await this.mutation("database:upsertAccessPolicy", params);
175 }
176
177 async listAccessPolicies(workspaceId: string): Promise<AccessPolicyRecord[]> {
178 return await this.query("database:listAccessPolicies", { workspaceId });
179 }
180
181 async upsertCredential(params: {
182 id?: string;
183 workspaceId: string;
184 sourceKey: string;
185 scope: CredentialScope;
186 actorId?: string;
187 secretJson: Record<string, unknown>;
188 }): Promise<CredentialRecord> {
189 return await this.mutation("database:upsertCredential", params);
190 }
191
192 async listCredentials(workspaceId: string): Promise<CredentialRecord[]> {
193 return await this.query("database:listCredentials", { workspaceId });
194 }
195
196 async resolveCredential(params: {
197 workspaceId: string;
198 sourceKey: string;
199 scope: CredentialScope;
200 actorId?: string;
201 }): Promise<CredentialRecord | null> {
202 return await this.query("database:resolveCredential", params);
203 }
204
205 async upsertToolSource(params: {
206 id?: string;
207 workspaceId: string;
208 name: string;
209 type: ToolSourceRecord["type"];
210 config: Record<string, unknown>;
211 enabled?: boolean;
212 }): Promise<ToolSourceRecord> {
213 return await this.mutation("database:upsertToolSource", params);
214 }
215
216 async listToolSources(workspaceId: string): Promise<ToolSourceRecord[]> {
217 return await this.query("database:listToolSources", { workspaceId });
218 }
219
220 async deleteToolSource(workspaceId: string, sourceId: string): Promise<boolean> {
221 return await this.mutation("database:deleteToolSource", { workspaceId, sourceId });
222 }
223
224 async createTaskEvent(input: {
225 taskId: string;
226 eventName: TaskEventRecord["eventName"];
227 type: string;
228 payload: Record<string, unknown>;
229 }): Promise<TaskEventRecord> {
230 return await this.mutation("database:createTaskEvent", input);
231 }
232
233 async listTaskEvents(taskId: string): Promise<TaskEventRecord[]> {
234 return await this.query("database:listTaskEvents", { taskId });
235 }
236}
executor/apps/server/src/index.ts+0−497
@@ -1,497 +0,0 @@
1import { Elysia, t } from "elysia";
2import { ExecutorDatabase } from "./database";
3import { TaskEventHub } from "./events";
4import { handleMcpRequest, type McpWorkspaceContext } from "./mcp-server";
5import { LocalBunRuntime } from "./runtimes/local-bun-runtime";
6import { VercelSandboxRuntime } from "./runtimes/vercel-sandbox-runtime";
7import { ExecutorService, getTaskTerminalState } from "./service";
8import { ensureTailscaleFunnel } from "./tailscale-funnel";
9import { loadExternalTools, parseToolSourcesFromEnv } from "./tool-sources";
10import { DEFAULT_TOOLS } from "./tools";
11import type {
12 ApprovalStatus,
13 TaskStatus,
14 ToolCallRequest,
15 RuntimeOutputEvent,
16} from "./types";
17
18// ── Bootstrap ──
19
20const port = Number(Bun.env.PORT ?? "4001");
21const autoFunnelEnabled = Bun.env.EXECUTOR_AUTO_TAILSCALE_FUNNEL !== "0";
22const explicitInternalBaseUrl = Bun.env.EXECUTOR_INTERNAL_BASE_URL ?? Bun.env.EXECUTOR_PUBLIC_BASE_URL;
23const generatedInternalToken = Bun.env.EXECUTOR_INTERNAL_TOKEN ?? "executor_internal_local_dev_token";
24const internalToken = generatedInternalToken;
25
26let internalBaseUrl = explicitInternalBaseUrl ?? `http://127.0.0.1:${port}`;
27let internalBaseSource = explicitInternalBaseUrl ? "env" : "localhost-default";
28
29if (!explicitInternalBaseUrl && autoFunnelEnabled) {
30 try {
31 const funnel = ensureTailscaleFunnel(port);
32 internalBaseUrl = funnel.url;
33 internalBaseSource = funnel.created ? "tailscale-funnel-created" : "tailscale-funnel-existing";
34 } catch (error) {
35 const message = error instanceof Error ? error.message : String(error);
36 console.warn(`[executor] tailscale funnel unavailable, using localhost callbacks: ${message}`);
37 }
38}
39
40const toolSourceConfigs = (() => {
41 try {
42 return parseToolSourcesFromEnv(Bun.env.EXECUTOR_TOOL_SOURCES);
43 } catch (error) {
44 const message = error instanceof Error ? error.message : String(error);
45 console.warn(`[executor] invalid EXECUTOR_TOOL_SOURCES: ${message}`);
46 return [];
47 }
48})();
49
50const { tools: externalTools, warnings: externalToolWarnings } = await loadExternalTools(toolSourceConfigs);
51if (externalToolWarnings.length > 0) {
52 for (const w of externalToolWarnings) console.warn(`[executor] ${w}`);
53}
54const tools = [...DEFAULT_TOOLS, ...externalTools];
55
56const service = new ExecutorService(new ExecutorDatabase(), new TaskEventHub(), [
57 new LocalBunRuntime(),
58 new VercelSandboxRuntime({
59 controlPlaneBaseUrl: internalBaseUrl,
60 internalToken,
61 runtime: Bun.env.EXECUTOR_VERCEL_SANDBOX_RUNTIME as "node24" | "node22" | undefined,
62 }),
63], tools, {
64 autoExecuteTasks: Bun.env.EXECUTOR_SERVER_AUTO_EXECUTE === "1",
65});
66
67// ── SSE helper ──
68
69function createTaskEventsResponse(taskId: string): Response | Promise<Response> {
70 const encoder = new TextEncoder();
71 let unsubscribe: (() => void) | undefined;
72 let keepalive: ReturnType<typeof setInterval> | undefined;
73
74 const stream = new ReadableStream<Uint8Array>({
75 start(controller) {
76 void (async () => {
77 const task = await service.getTask(taskId);
78 if (!task) {
79 controller.close();
80 return;
81 }
82
83 const replay = await service.listTaskEvents(taskId);
84 for (const event of replay) {
85 const frame = `event: ${event.eventName}\ndata: ${JSON.stringify(event)}\n\n`;
86 controller.enqueue(encoder.encode(frame));
87 }
88
89 if (getTaskTerminalState(task.status)) {
90 controller.close();
91 return;
92 }
93
94 unsubscribe = service.subscribe(taskId, (event) => {
95 try {
96 const frame = `event: ${event.eventName}\ndata: ${JSON.stringify(event)}\n\n`;
97 controller.enqueue(encoder.encode(frame));
98
99 if (
100 event.eventName === "task" &&
101 typeof event.payload === "object" &&
102 event.payload !== null &&
103 "status" in event.payload
104 ) {
105 const status = String((event.payload as { status?: unknown }).status ?? "") as TaskStatus;
106 if (getTaskTerminalState(status)) {
107 if (keepalive) clearInterval(keepalive);
108 if (unsubscribe) unsubscribe();
109 controller.close();
110 }
111 }
112 } catch {
113 if (keepalive) clearInterval(keepalive);
114 if (unsubscribe) unsubscribe();
115 controller.close();
116 }
117 });
118
119 keepalive = setInterval(() => {
120 controller.enqueue(encoder.encode(": keepalive\n\n"));
121 }, 15_000);
122 })().catch(() => {
123 if (keepalive) clearInterval(keepalive);
124 if (unsubscribe) unsubscribe();
125 controller.close();
126 });
127 },
128 cancel() {
129 if (keepalive) clearInterval(keepalive);
130 if (unsubscribe) unsubscribe();
131 },
132 });
133
134 return new Response(stream, {
135 status: 200,
136 headers: {
137 "content-type": "text/event-stream; charset=utf-8",
138 "cache-control": "no-cache",
139 connection: "keep-alive",
140 "access-control-allow-origin": "*",
141 },
142 });
143}
144
145// ── Internal auth guard ──
146
147function isInternalAuthorized(request: Request): boolean {
148 if (!internalToken) return true;
149 const header = request.headers.get("authorization");
150 if (!header || !header.startsWith("Bearer ")) return false;
151 return header.slice("Bearer ".length) === internalToken;
152}
153
154function parseMcpContext(url: URL): McpWorkspaceContext | undefined {
155 const workspaceId = url.searchParams.get("workspaceId");
156 const actorId = url.searchParams.get("actorId");
157 if (!workspaceId || !actorId) return undefined;
158 const clientId = url.searchParams.get("clientId") ?? undefined;
159 return { workspaceId, actorId, clientId };
160}
161
162// ── MCP handler ──
163
164const handleMcp = async ({ request }: { request: Request }) => {
165 const url = new URL(request.url);
166 const context = parseMcpContext(url);
167 return await handleMcpRequest(service, request, context);
168};
169
170// ── Elysia app ──
171
172const app = new Elysia()
173 // CORS
174 .onRequest(({ set }) => {
175 set.headers["access-control-allow-origin"] = "*";
176 set.headers["access-control-allow-methods"] = "GET,POST,DELETE,OPTIONS";
177 set.headers["access-control-allow-headers"] = "content-type,authorization";
178 })
179 .options("/*", () => new Response(null, { status: 204 }))
180
181 // ── MCP (raw protocol passthrough) ──
182 // Optional query params: ?workspaceId=...&actorId=... to bind workspace context.
183 // When bound, run_code description includes sandbox tool inventory and input is simplified.
184 .post("/mcp", handleMcp)
185 .get("/mcp", handleMcp)
186 .delete("/mcp", handleMcp)
187
188 // ── Health ──
189 .get("/api/health", () => ({
190 ok: true as const,
191 tools: service.getBaseToolCount(),
192 }))
193
194 // ── Auth ──
195 .post("/api/auth/anonymous/bootstrap", async ({ body }) => {
196 return await service.bootstrapAnonymousContext(body.sessionId);
197 }, {
198 body: t.Object({
199 sessionId: t.Optional(t.String()),
200 }),
201 })
202
203 // ── Runtime Targets ──
204 .get("/api/runtime-targets", () => service.listRuntimes())
205
206 // ── Tools ──
207 .get("/api/tools", async ({ query }) => {
208 return await service.listTools({
209 workspaceId: query.workspaceId,
210 actorId: query.actorId,
211 clientId: query.clientId,
212 });
213 }, {
214 query: t.Object({
215 workspaceId: t.String(),
216 actorId: t.Optional(t.String()),
217 clientId: t.Optional(t.String()),
218 }),
219 })
220
221 // ── Tool Sources ──
222 .get("/api/tool-sources", async ({ query }) => {
223 return await service.listToolSources(query.workspaceId);
224 }, {
225 query: t.Object({
226 workspaceId: t.String(),
227 }),
228 })
229
230 .post("/api/tool-sources", async ({ body, set }) => {
231 try {
232 return await service.upsertToolSource({
233 id: body.id,
234 workspaceId: body.workspaceId,
235 name: body.name,
236 type: body.type,
237 config: body.config,
238 enabled: body.enabled,
239 });
240 } catch (cause) {
241 set.status = 400;
242 return { error: cause instanceof Error ? cause.message : String(cause) };
243 }
244 }, {
245 body: t.Object({
246 id: t.Optional(t.String()),
247 workspaceId: t.String(),
248 name: t.String(),
249 type: t.Union([t.Literal("mcp"), t.Literal("openapi"), t.Literal("graphql")]),
250 config: t.Record(t.String(), t.Unknown()),
251 enabled: t.Optional(t.Boolean()),
252 }),
253 })
254
255 .delete("/api/tool-sources/:sourceId", async ({ params, query, set }) => {
256 const deleted = await service.deleteToolSource(query.workspaceId, params.sourceId);
257 if (!deleted) {
258 set.status = 404;
259 return { error: "Tool source not found" };
260 }
261 return { ok: true as const };
262 }, {
263 params: t.Object({ sourceId: t.String() }),
264 query: t.Object({ workspaceId: t.String() }),
265 })
266
267 // ── Tasks ──
268 .get("/api/tasks", async ({ query }) => {
269 return await service.listTasks(query.workspaceId);
270 }, {
271 query: t.Object({ workspaceId: t.String() }),
272 })
273
274 .post("/api/tasks", async ({ body, set }) => {
275 try {
276 const created = await service.createTask(body);
277 return { taskId: created.task.id, status: created.task.status };
278 } catch (cause) {
279 set.status = 400;
280 return { error: cause instanceof Error ? cause.message : String(cause) };
281 }
282 }, {
283 body: t.Object({
284 code: t.String(),
285 timeoutMs: t.Optional(t.Number()),
286 runtimeId: t.Optional(t.String()),
287 metadata: t.Optional(t.Record(t.String(), t.Unknown())),
288 workspaceId: t.String(),
289 actorId: t.String(),
290 clientId: t.Optional(t.String()),
291 }),
292 })
293
294 .get("/api/tasks/:taskId", async ({ params, query, set }) => {
295 const task = await service.getTask(params.taskId, query.workspaceId);
296 if (!task) {
297 set.status = 404;
298 return { error: "Task not found" };
299 }
300 return task;
301 }, {
302 params: t.Object({ taskId: t.String() }),
303 query: t.Object({ workspaceId: t.String() }),
304 })
305
306 .get("/api/tasks/:taskId/events", async ({ params, query, set }) => {
307 const task = await service.getTask(params.taskId, query.workspaceId);
308 if (!task) {
309 set.status = 404;
310 return { error: "Task not found" };
311 }
312 return createTaskEventsResponse(params.taskId);
313 }, {
314 params: t.Object({ taskId: t.String() }),
315 query: t.Object({ workspaceId: t.String() }),
316 })
317
318 // ── Approvals ──
319 .get("/api/approvals", async ({ query, set }) => {
320 const status = query.status as ApprovalStatus | undefined;
321
322 if (status === "pending") {
323 return await service.listPendingApprovals(query.workspaceId);
324 }
325
326 if (status && status !== "approved" && status !== "denied") {
327 set.status = 400;
328 return { error: "Invalid approval status" };
329 }
330
331 return await service.listApprovals(query.workspaceId, status ?? undefined);
332 }, {
333 query: t.Object({
334 workspaceId: t.String(),
335 status: t.Optional(t.String()),
336 }),
337 })
338
339 .post("/api/approvals/:approvalId", async ({ params, body, set }) => {
340 const resolved = await service.resolveApproval(
341 body.workspaceId,
342 params.approvalId,
343 body.decision,
344 body.reviewerId,
345 body.reason,
346 );
347
348 if (!resolved) {
349 set.status = 404;
350 return { error: "Approval not found or already resolved" };
351 }
352 return resolved;
353 }, {
354 params: t.Object({ approvalId: t.String() }),
355 body: t.Object({
356 workspaceId: t.String(),
357 decision: t.Union([t.Literal("approved"), t.Literal("denied")]),
358 reviewerId: t.Optional(t.String()),
359 reason: t.Optional(t.String()),
360 }),
361 })
362
363 // ── Policies ──
364 .get("/api/policies", async ({ query }) => {
365 return await service.listAccessPolicies(query.workspaceId);
366 }, {
367 query: t.Object({ workspaceId: t.String() }),
368 })
369
370 .post("/api/policies", async ({ body }) => {
371 return await service.upsertAccessPolicy({
372 id: body.id,
373 workspaceId: body.workspaceId,
374 actorId: body.actorId,
375 clientId: body.clientId,
376 toolPathPattern: body.toolPathPattern,
377 decision: body.decision,
378 priority: body.priority,
379 });
380 }, {
381 body: t.Object({
382 id: t.Optional(t.String()),
383 workspaceId: t.String(),
384 actorId: t.Optional(t.String()),
385 clientId: t.Optional(t.String()),
386 toolPathPattern: t.String(),
387 decision: t.Union([t.Literal("allow"), t.Literal("require_approval"), t.Literal("deny")]),
388 priority: t.Optional(t.Number()),
389 }),
390 })
391
392 // ── Credentials ──
393 .get("/api/credentials", async ({ query }) => {
394 return await service.listCredentials(query.workspaceId);
395 }, {
396 query: t.Object({ workspaceId: t.String() }),
397 })
398
399 .post("/api/credentials", async ({ body, set }) => {
400 if (body.scope === "actor" && (!body.actorId || body.actorId.trim().length === 0)) {
401 set.status = 400;
402 return { error: "actorId is required for actor-scoped credential" };
403 }
404
405 const credential = await service.upsertCredential({
406 id: body.id,
407 workspaceId: body.workspaceId,
408 sourceKey: body.sourceKey,
409 scope: body.scope,
410 actorId: body.actorId,
411 secretJson: body.secretJson,
412 });
413
414 return {
415 id: credential.id,
416 workspaceId: credential.workspaceId,
417 sourceKey: credential.sourceKey,
418 scope: credential.scope,
419 actorId: credential.actorId,
420 hasSecret: true as const,
421 };
422 }, {
423 body: t.Object({
424 id: t.Optional(t.String()),
425 workspaceId: t.String(),
426 sourceKey: t.String(),
427 scope: t.Union([t.Literal("workspace"), t.Literal("actor")]),
428 actorId: t.Optional(t.String()),
429 secretJson: t.Record(t.String(), t.Unknown()),
430 }),
431 })
432
433 // ── Internal endpoints (bearer auth protected) ──
434 .post("/internal/runs/:runId/tool-call", async ({ params, body, request, set }) => {
435 if (!isInternalAuthorized(request)) {
436 set.status = 401;
437 return { error: "Unauthorized internal call" };
438 }
439
440 const call: ToolCallRequest = {
441 runId: params.runId,
442 callId: body.callId,
443 toolPath: body.toolPath,
444 input: body.input,
445 };
446
447 return await service.handleExternalToolCall(call);
448 }, {
449 params: t.Object({ runId: t.String() }),
450 body: t.Object({
451 callId: t.String(),
452 toolPath: t.String(),
453 input: t.Optional(t.Unknown()),
454 }),
455 })
456
457 .post("/internal/runs/:runId/output", async ({ params, body, request, set }) => {
458 if (!isInternalAuthorized(request)) {
459 set.status = 401;
460 return { error: "Unauthorized internal call" };
461 }
462
463 const event: RuntimeOutputEvent = {
464 runId: params.runId,
465 stream: body.stream,
466 line: body.line,
467 timestamp: typeof body.timestamp === "number" ? body.timestamp : Date.now(),
468 };
469
470 const task = await service.getTask(event.runId);
471 if (!task) {
472 set.status = 404;
473 return { error: `Run not found: ${event.runId}` };
474 }
475
476 await service.appendRuntimeOutput(event);
477 return { ok: true as const };
478 }, {
479 params: t.Object({ runId: t.String() }),
480 body: t.Object({
481 stream: t.Union([t.Literal("stdout"), t.Literal("stderr")]),
482 line: t.String(),
483 timestamp: t.Optional(t.Number()),
484 }),
485 })
486
487 ;
488
489export type App = typeof app;
490
491app.listen(port);
492
493console.log(`executor server listening on http://localhost:${port}`);
494console.log(`[executor] internal callback base: ${internalBaseUrl} (${internalBaseSource})`);
495console.log(`[executor] internal callback auth token enabled: yes`);
496console.log(`[executor] tools loaded: ${tools.length} (${externalTools.length} external)`);
497console.log(`[executor] server auto execute enabled: ${Bun.env.EXECUTOR_SERVER_AUTO_EXECUTE === "1" ? "yes" : "no"}`);
executor/apps/server/src/runtimes/local-bun-runtime.ts+0−20
@@ -1,20 +0,0 @@
1import { runCodeWithAdapter } from "./runtime-core";
2import type {
3 ExecutionAdapter,
4 SandboxExecutionRequest,
5 SandboxExecutionResult,
6 SandboxRuntime,
7} from "../types";
8
9export class LocalBunRuntime implements SandboxRuntime {
10 readonly id = "local-bun";
11 readonly label = "Local JS Runtime";
12 readonly description = "Runs generated JavaScript in-process with pluggable execution adapter.";
13
14 async run(
15 request: SandboxExecutionRequest,
16 adapter: ExecutionAdapter,
17 ): Promise<SandboxExecutionResult> {
18 return await runCodeWithAdapter(request, adapter);
19 }
20}
executor/apps/server/src/runtimes/sandbox-fragments.ts+0−224
@@ -1,224 +0,0 @@
1/**
2 * String fragments for the Vercel sandbox runner script.
3 *
4 * The Vercel sandbox runs code in a remote microVM that cannot import local
5 * modules, so its entire runtime must be shipped as a self-contained JS string.
6 * These fragments mirror the TypeScript logic in runtime-core.ts — keep them
7 * in sync when making behavioural changes.
8 *
9 * Constants from execution-constants.ts are interpolated at build time so the
10 * sandbox never hardcodes magic strings.
11 */
12
13import {
14 APPROVAL_DENIED_PREFIX,
15 TASK_TIMEOUT_MARKER,
16} from "../execution-constants";
17
18// ---------------------------------------------------------------------------
19// Shared helper: formatArgs
20// Mirror of: runtime-core.ts formatArgs()
21// ---------------------------------------------------------------------------
22export function buildFormatArgs(): string {
23 return `
24function formatArgs(args) {
25 return args.map((value) => {
26 if (typeof value === "string") return value;
27 try {
28 return JSON.stringify(value);
29 } catch {
30 return String(value);
31 }
32 }).join(" ");
33}`;
34}
35
36// ---------------------------------------------------------------------------
37// HTTP helper (sandbox-only — runtime-core uses the adapter directly)
38// ---------------------------------------------------------------------------
39export function buildCallInternal(): string {
40 return `
41async function callInternal(path, payload) {
42 const response = await fetch(baseUrl + path, {
43 method: "POST",
44 headers: {
45 "content-type": "application/json",
46 ...(token ? { authorization: "Bearer " + token } : {}),
47 },
48 body: JSON.stringify(payload),
49 });
50
51 const text = await response.text();
52 let data = {};
53 if (text.length > 0) {
54 try {
55 data = JSON.parse(text);
56 } catch {
57 data = { error: text };
58 }
59 }
60
61 if (!response.ok) {
62 const message = typeof data.error === "string"
63 ? data.error
64 : "Internal request failed (" + response.status + ")";
65 throw new Error(message);
66 }
67
68 return data;
69}`;
70}
71
72// ---------------------------------------------------------------------------
73// Output helpers
74// Mirror of: runtime-core.ts appendStdout / appendStderr
75// ---------------------------------------------------------------------------
76export function buildOutputHelpers(): string {
77 return `
78function emitOutput(stream, line) {
79 return callInternal("/internal/runs/" + encodeURIComponent(runId) + "/output", {
80 stream,
81 line,
82 timestamp: Date.now(),
83 });
84}
85
86function appendStdout(line) {
87 stdoutLines.push(line);
88 void emitOutput("stdout", line);
89}
90
91function appendStderr(line) {
92 stderrLines.push(line);
93 void emitOutput("stderr", line);
94}`;
95}
96
97// ---------------------------------------------------------------------------
98// Shared helper: createToolsProxy
99// Mirror of: runtime-core.ts createToolsProxy()
100// The sandbox version calls HTTP endpoints instead of adapter.invokeTool().
101// ---------------------------------------------------------------------------
102export function buildCreateToolsProxy(): string {
103 return `
104function createToolsProxy(path = []) {
105 const callable = () => {};
106 return new Proxy(callable, {
107 get(_target, prop) {
108 if (prop === "then") return undefined;
109 if (typeof prop !== "string") return undefined;
110 return createToolsProxy([...path, prop]);
111 },
112 async apply(_target, _thisArg, args) {
113 const toolPath = path.join(".");
114 if (!toolPath) {
115 throw new Error("Tool path missing in invocation");
116 }
117
118 const data = await callInternal(
119 "/internal/runs/" + encodeURIComponent(runId) + "/tool-call",
120 {
121 callId: "call_" + randomUUID(),
122 toolPath,
123 input: args.length > 0 ? args[0] : {},
124 },
125 );
126
127 if (data.ok) {
128 return data.value;
129 }
130
131 if (data.denied) {
132 throw new Error(${JSON.stringify(APPROVAL_DENIED_PREFIX)} + String(data.error || "Tool call denied"));
133 }
134
135 throw new Error(String(data.error || "Tool call failed"));
136 },
137 });
138}`;
139}
140
141// ---------------------------------------------------------------------------
142// Shared: sandbox + context setup, execution, and result mapping
143// Mirror of: runtime-core.ts runCodeWithAdapter() execution & catch blocks
144// ---------------------------------------------------------------------------
145export function buildSandboxExecution(): string {
146 return `
147const tools = createToolsProxy();
148const consoleProxy = {
149 log: (...args) => appendStdout(formatArgs(args)),
150 info: (...args) => appendStdout(formatArgs(args)),
151 warn: (...args) => appendStderr(formatArgs(args)),
152 error: (...args) => appendStderr(formatArgs(args)),
153};
154
155const sandbox = Object.assign(Object.create(null), {
156 tools,
157 console: consoleProxy,
158 setTimeout,
159 clearTimeout,
160});
161const context = vm.createContext(sandbox, {
162 codeGeneration: {
163 strings: false,
164 wasm: false,
165 },
166});
167const runnerScript = new vm.Script("(async () => {\\n\\"use strict\\";\\n" + userCode + "\\n})()");
168
169const timeoutPromise = new Promise((_, reject) => {
170 setTimeout(() => reject(new Error(${JSON.stringify(TASK_TIMEOUT_MARKER)})), requestTimeoutMs);
171});
172
173let result;
174try {
175 const value = await Promise.race([
176 Promise.resolve(runnerScript.runInContext(context, { timeout: Math.max(1, requestTimeoutMs) })),
177 timeoutPromise,
178 ]);
179 if (value !== undefined) {
180 appendStdout("result: " + formatArgs([value]));
181 }
182
183 result = {
184 status: "completed",
185 stdout: stdoutLines.join("\\n"),
186 stderr: stderrLines.join("\\n"),
187 exitCode: 0,
188 durationMs: Date.now() - startedAt,
189 };
190} catch (error) {
191 const message = error instanceof Error ? error.message : String(error);
192
193 if (message === ${JSON.stringify(TASK_TIMEOUT_MARKER)} || message.includes("Script execution timed out")) {
194 const timeoutMessage = "Execution timed out after " + requestTimeoutMs + "ms";
195 appendStderr(timeoutMessage);
196 result = {
197 status: "timed_out",
198 stdout: stdoutLines.join("\\n"),
199 stderr: stderrLines.join("\\n"),
200 error: timeoutMessage,
201 durationMs: Date.now() - startedAt,
202 };
203 } else if (message.startsWith(${JSON.stringify(APPROVAL_DENIED_PREFIX)})) {
204 const deniedMessage = message.slice(${JSON.stringify(APPROVAL_DENIED_PREFIX)}.length).trim();
205 appendStderr(deniedMessage);
206 result = {
207 status: "denied",
208 stdout: stdoutLines.join("\\n"),
209 stderr: stderrLines.join("\\n"),
210 error: deniedMessage,
211 durationMs: Date.now() - startedAt,
212 };
213 } else {
214 appendStderr(message);
215 result = {
216 status: "failed",
217 stdout: stdoutLines.join("\\n"),
218 stderr: stderrLines.join("\\n"),
219 error: message,
220 durationMs: Date.now() - startedAt,
221 };
222 }
223}`;
224}
executor/apps/server/src/runtimes/vercel-sandbox-runtime.ts+0−168
@@ -1,168 +0,0 @@
1import { Sandbox } from "@vercel/sandbox";
2import type {
3 ExecutionAdapter,
4 SandboxExecutionRequest,
5 SandboxExecutionResult,
6 SandboxRuntime,
7} from "../types";
8import {
9 buildFormatArgs,
10 buildCallInternal,
11 buildOutputHelpers,
12 buildCreateToolsProxy,
13 buildSandboxExecution,
14} from "./sandbox-fragments";
15
16const RESULT_MARKER = "__EXECUTOR_RESULT__";
17
18interface VercelSandboxRuntimeOptions {
19 controlPlaneBaseUrl: string;
20 internalToken?: string;
21 runtime?: "node24" | "node22";
22}
23
24function stripTrailingSlash(value: string): string {
25 return value.replace(/\/$/, "");
26}
27
28function buildRunnerScript(codeFilePath: string): string {
29 // Composed from sandbox-fragments.ts — see that file for the mirror
30 // relationship with runtime-core.ts.
31 return `
32import { readFile } from "node:fs/promises";
33import { randomUUID } from "node:crypto";
34import vm from "node:vm";
35
36const RESULT_MARKER = ${JSON.stringify(RESULT_MARKER)};
37const runId = process.env.EXECUTOR_RUN_ID;
38const baseUrl = process.env.EXECUTOR_INTERNAL_BASE_URL;
39const token = process.env.EXECUTOR_INTERNAL_TOKEN || "";
40const requestTimeoutMs = Number(process.env.EXECUTOR_REQUEST_TIMEOUT_MS || "15000");
41
42if (!runId) {
43 throw new Error("Missing EXECUTOR_RUN_ID");
44}
45
46if (!baseUrl) {
47 throw new Error("Missing EXECUTOR_INTERNAL_BASE_URL");
48}
49
50const userCode = await readFile(${JSON.stringify(codeFilePath)}, "utf8");
51const startedAt = Date.now();
52const stdoutLines = [];
53const stderrLines = [];
54${buildFormatArgs()}
55${buildCallInternal()}
56${buildOutputHelpers()}
57${buildCreateToolsProxy()}
58${buildSandboxExecution()}
59
60process.stdout.write(RESULT_MARKER + JSON.stringify(result) + "\\n");
61`;
62}
63
64function parseResultFromStdout(stdout: string): SandboxExecutionResult | null {
65 const lines = stdout.split("\n");
66 const resultLine = lines.find((line) => line.startsWith(RESULT_MARKER));
67 if (!resultLine) {
68 return null;
69 }
70
71 try {
72 return JSON.parse(resultLine.slice(RESULT_MARKER.length)) as SandboxExecutionResult;
73 } catch {
74 return null;
75 }
76}
77
78export class VercelSandboxRuntime implements SandboxRuntime {
79 readonly id = "vercel-sandbox";
80 readonly label = "Vercel Sandbox Runtime";
81 readonly description = "Runs generated JavaScript inside Vercel Sandbox microVMs.";
82
83 constructor(private readonly options: VercelSandboxRuntimeOptions) {}
84
85 async run(
86 request: SandboxExecutionRequest,
87 _adapter: ExecutionAdapter,
88 ): Promise<SandboxExecutionResult> {
89 const startedAt = Date.now();
90 const baseUrl = stripTrailingSlash(this.options.controlPlaneBaseUrl);
91 if (!baseUrl) {
92 return {
93 status: "failed",
94 stdout: "",
95 stderr: "",
96 error: "Vercel sandbox runtime misconfigured: missing controlPlaneBaseUrl",
97 durationMs: Date.now() - startedAt,
98 };
99 }
100
101 if (/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i.test(baseUrl)) {
102 return {
103 status: "failed",
104 stdout: "",
105 stderr: "",
106 error:
107 "Vercel sandbox runtime requires a publicly reachable EXECUTOR_INTERNAL_BASE_URL (localhost is not reachable from Vercel).",
108 durationMs: Date.now() - startedAt,
109 };
110 }
111
112 const sandboxTimeoutMs = Math.max(request.timeoutMs + 30_000, 120_000);
113 const sandbox = await Sandbox.create({
114 runtime: this.options.runtime ?? "node22",
115 timeout: sandboxTimeoutMs,
116 });
117
118 const codePath = "task-code.js";
119 const runnerPath = "executor-runner.mjs";
120
121 try {
122 await sandbox.writeFiles([
123 { path: codePath, content: Buffer.from(request.code, "utf8") },
124 { path: runnerPath, content: Buffer.from(buildRunnerScript(codePath), "utf8") },
125 ]);
126
127 const command = await sandbox.runCommand({
128 cmd: "node",
129 args: [runnerPath],
130 env: {
131 EXECUTOR_RUN_ID: request.taskId,
132 EXECUTOR_INTERNAL_BASE_URL: baseUrl,
133 EXECUTOR_INTERNAL_TOKEN: this.options.internalToken ?? "",
134 EXECUTOR_REQUEST_TIMEOUT_MS: String(request.timeoutMs),
135 },
136 });
137
138 const [stdout, stderr] = await Promise.all([
139 command.stdout(),
140 command.stderr(),
141 ]);
142
143 const parsed = parseResultFromStdout(stdout);
144 if (parsed) {
145 return parsed;
146 }
147
148 return {
149 status: command.exitCode === 0 ? "completed" : "failed",
150 stdout,
151 stderr,
152 exitCode: command.exitCode,
153 error: command.exitCode === 0 ? undefined : `Sandbox command exited with code ${command.exitCode}`,
154 durationMs: Date.now() - startedAt,
155 };
156 } catch (error) {
157 return {
158 status: "failed",
159 stdout: "",
160 stderr: "",
161 error: error instanceof Error ? error.message : String(error),
162 durationMs: Date.now() - startedAt,
163 };
164 } finally {
165 await sandbox.stop();
166 }
167 }
168}
executor/apps/server/src/service.test.ts+0−428
@@ -1,428 +0,0 @@
1import { expect, test } from "bun:test";
2import { ExecutorDatabase } from "./database";
3import { TaskEventHub } from "./events";
4import { ExecutorService } from "./service";
5import type {
6 AccessPolicyRecord,
7 ApprovalRecord,
8 ExecutionAdapter,
9 PendingApprovalRecord,
10 TaskEventRecord,
11 TaskRecord,
12 ToolSourceRecord,
13 SandboxExecutionRequest,
14 SandboxExecutionResult,
15 SandboxRuntime,
16 ToolDefinition,
17} from "./types";
18
19class TestExecutorDatabase extends ExecutorDatabase {
20 private readonly tasks = new Map<string, TaskRecord>();
21 private readonly approvals = new Map<string, ApprovalRecord>();
22 private readonly events = new Map<string, TaskEventRecord[]>();
23 private readonly policies = new Map<string, AccessPolicyRecord>();
24
25 constructor() {
26 super("http://127.0.0.1:3210");
27 }
28
29 async createTask(params: {
30 id: string;
31 code: string;
32 runtimeId: string;
33 timeoutMs?: number;
34 metadata?: Record<string, unknown>;
35 workspaceId: string;
36 actorId: string;
37 clientId?: string;
38 }): Promise<TaskRecord> {
39 const now = Date.now();
40 const task: TaskRecord = {
41 id: params.id,
42 code: params.code,
43 runtimeId: params.runtimeId,
44 status: "queued",
45 timeoutMs: params.timeoutMs ?? 15_000,
46 metadata: params.metadata ?? {},
47 workspaceId: params.workspaceId,
48 actorId: params.actorId,
49 clientId: params.clientId,
50 createdAt: now,
51 updatedAt: now,
52 };
53 this.tasks.set(task.id, task);
54 return task;
55 }
56
57 async getTask(taskId: string): Promise<TaskRecord | null> {
58 return this.tasks.get(taskId) ?? null;
59 }
60
61 async getTaskInWorkspace(taskId: string, workspaceId: string): Promise<TaskRecord | null> {
62 const task = this.tasks.get(taskId);
63 if (!task || task.workspaceId !== workspaceId) {
64 return null;
65 }
66 return task;
67 }
68
69 async markTaskRunning(taskId: string): Promise<TaskRecord | null> {
70 const task = this.tasks.get(taskId);
71 if (!task) {
72 return null;
73 }
74
75 const now = Date.now();
76 const updated: TaskRecord = {
77 ...task,
78 status: "running",
79 startedAt: task.startedAt ?? now,
80 updatedAt: now,
81 };
82 this.tasks.set(taskId, updated);
83 return updated;
84 }
85
86 async markTaskFinished(params: {
87 taskId: string;
88 status: "completed" | "failed" | "timed_out" | "denied";
89 stdout: string;
90 stderr: string;
91 exitCode?: number;
92 error?: string;
93 }): Promise<TaskRecord | null> {
94 const task = this.tasks.get(params.taskId);
95 if (!task) {
96 return null;
97 }
98
99 const now = Date.now();
100 const updated: TaskRecord = {
101 ...task,
102 status: params.status,
103 stdout: params.stdout,
104 stderr: params.stderr,
105 exitCode: params.exitCode,
106 error: params.error,
107 completedAt: now,
108 updatedAt: now,
109 };
110 this.tasks.set(params.taskId, updated);
111 return updated;
112 }
113
114 async createApproval(params: {
115 id: string;
116 taskId: string;
117 toolPath: string;
118 input: unknown;
119 }): Promise<ApprovalRecord> {
120 const approval: ApprovalRecord = {
121 id: params.id,
122 taskId: params.taskId,
123 toolPath: params.toolPath,
124 input: params.input,
125 status: "pending",
126 createdAt: Date.now(),
127 };
128 this.approvals.set(approval.id, approval);
129 return approval;
130 }
131
132 async getApproval(approvalId: string): Promise<ApprovalRecord | null> {
133 return this.approvals.get(approvalId) ?? null;
134 }
135
136 async listPendingApprovals(workspaceId: string): Promise<PendingApprovalRecord[]> {
137 const pending = [...this.approvals.values()].filter((approval) => approval.status === "pending");
138 const inWorkspace = pending.filter((approval) => {
139 const task = this.tasks.get(approval.taskId);
140 return task?.workspaceId === workspaceId;
141 });
142
143 return inWorkspace.map((approval) => {
144 const task = this.tasks.get(approval.taskId)!;
145 return {
146 ...approval,
147 task: {
148 id: task.id,
149 status: task.status,
150 runtimeId: task.runtimeId,
151 timeoutMs: task.timeoutMs,
152 createdAt: task.createdAt,
153 },
154 };
155 });
156 }
157
158 async resolveApproval(params: {
159 approvalId: string;
160 decision: "approved" | "denied";
161 reviewerId?: string;
162 reason?: string;
163 }): Promise<ApprovalRecord | null> {
164 const approval = this.approvals.get(params.approvalId);
165 if (!approval || approval.status !== "pending") {
166 return null;
167 }
168
169 const updated: ApprovalRecord = {
170 ...approval,
171 status: params.decision,
172 reviewerId: params.reviewerId,
173 reason: params.reason,
174 resolvedAt: Date.now(),
175 };
176 this.approvals.set(params.approvalId, updated);
177 return updated;
178 }
179
180 async getApprovalInWorkspace(approvalId: string, workspaceId: string): Promise<ApprovalRecord | null> {
181 const approval = this.approvals.get(approvalId);
182 if (!approval) {
183 return null;
184 }
185
186 const task = this.tasks.get(approval.taskId);
187 if (!task || task.workspaceId !== workspaceId) {
188 return null;
189 }
190
191 return approval;
192 }
193
194 async listApprovals(workspaceId: string, status?: "pending" | "approved" | "denied"): Promise<ApprovalRecord[]> {
195 return [...this.approvals.values()].filter((approval) => {
196 const task = this.tasks.get(approval.taskId);
197 if (!task || task.workspaceId !== workspaceId) {
198 return false;
199 }
200 if (!status) {
201 return true;
202 }
203 return approval.status === status;
204 });
205 }
206
207 async listToolSources(_workspaceId: string): Promise<ToolSourceRecord[]> {
208 return [];
209 }
210
211 async listAccessPolicies(_workspaceId: string): Promise<AccessPolicyRecord[]> {
212 return [...this.policies.values()]
213 .filter((policy) => policy.workspaceId === _workspaceId)
214 .sort((a, b) => {
215 if (a.priority !== b.priority) {
216 return b.priority - a.priority;
217 }
218 return a.createdAt - b.createdAt;
219 });
220 }
221
222 async upsertAccessPolicy(params: {
223 id?: string;
224 workspaceId: string;
225 actorId?: string;
226 clientId?: string;
227 toolPathPattern: string;
228 decision: "allow" | "require_approval" | "deny";
229 priority?: number;
230 }): Promise<AccessPolicyRecord> {
231 const now = Date.now();
232 const id = params.id ?? `policy_${crypto.randomUUID()}`;
233 const existing = this.policies.get(id);
234
235 const record: AccessPolicyRecord = {
236 id,
237 workspaceId: params.workspaceId,
238 actorId: params.actorId,
239 clientId: params.clientId,
240 toolPathPattern: params.toolPathPattern,
241 decision: params.decision,
242 priority: params.priority ?? 100,
243 createdAt: existing?.createdAt ?? now,
244 updatedAt: now,
245 };
246
247 this.policies.set(id, record);
248 return record;
249 }
250
251 async resolveCredential(): Promise<null> {
252 return null;
253 }
254
255 async createTaskEvent(input: {
256 taskId: string;
257 eventName: string;
258 type: string;
259 payload: Record<string, unknown>;
260 }): Promise<TaskEventRecord> {
261 const existing = this.events.get(input.taskId) ?? [];
262 const event: TaskEventRecord = {
263 id: existing.length + 1,
264 taskId: input.taskId,
265 eventName: input.eventName,
266 type: input.type,
267 payload: input.payload,
268 createdAt: Date.now(),
269 };
270 existing.push(event);
271 this.events.set(input.taskId, existing);
272 return event;
273 }
274
275 async listTaskEvents(taskId: string): Promise<TaskEventRecord[]> {
276 return this.events.get(taskId) ?? [];
277 }
278}
279
280class InlineToolRuntime implements SandboxRuntime {
281 readonly id = "inline";
282 readonly label = "Inline";
283 readonly description = "Calls one tool then exits";
284
285 constructor(
286 private readonly toolPath = "admin.delete_data",
287 private readonly input: unknown = { key: "abc" },
288 ) {}
289
290 async run(
291 request: SandboxExecutionRequest,
292 adapter: ExecutionAdapter,
293 ): Promise<SandboxExecutionResult> {
294 const startedAt = Date.now();
295 const result = await adapter.invokeTool({
296 runId: request.taskId,
297 callId: "call_inline_1",
298 toolPath: this.toolPath,
299 input: this.input,
300 });
301
302 if (!result.ok) {
303 return {
304 status: result.denied ? "denied" : "failed",
305 stdout: "",
306 stderr: result.error,
307 error: result.error,
308 durationMs: Date.now() - startedAt,
309 };
310 }
311
312 await adapter.emitOutput({
313 runId: request.taskId,
314 stream: "stdout",
315 line: `tool_result:${JSON.stringify(result.value)}`,
316 timestamp: Date.now(),
317 });
318
319 return {
320 status: "completed",
321 stdout: `task:${request.taskId}`,
322 stderr: "",
323 exitCode: 0,
324 durationMs: Date.now() - startedAt,
325 };
326 }
327}
328
329const tools: ToolDefinition[] = [
330 {
331 path: "admin.delete_data",
332 description: "Requires approval",
333 approval: "required",
334 run: async (input) => ({ deleted: true, input }),
335 },
336];
337
338async function waitForTaskStatus(
339 service: ExecutorService,
340 taskId: string,
341 expected: TaskRecord["status"],
342 timeoutMs = 2_000,
343): Promise<TaskRecord | null> {
344 let task = await service.getTask(taskId);
345 const waitUntil = Date.now() + timeoutMs;
346 while (task?.status !== expected && Date.now() < waitUntil) {
347 await Bun.sleep(25);
348 task = await service.getTask(taskId);
349 }
350 return task;
351}
352
353test("tool-level approval gates individual function call", async () => {
354 const service = new ExecutorService(
355 new TestExecutorDatabase(),
356 new TaskEventHub(),
357 [new InlineToolRuntime()],
358 tools,
359 );
360
361 const created = await service.createTask({
362 code: "unused",
363 runtimeId: "inline",
364 workspaceId: "ws_test",
365 actorId: "actor_test",
366 });
367
368 await new Promise((resolve) => setTimeout(resolve, 5));
369 const approvals = await service.listPendingApprovals("ws_test");
370
371 expect(approvals.length).toBe(1);
372 expect(approvals[0]?.toolPath).toBe("admin.delete_data");
373
374 const resolved = await service.resolveApproval("ws_test", approvals[0]!.id, "approved", "test-user");
375 expect(resolved).toBeTruthy();
376
377 const task = await waitForTaskStatus(service, created.task.id, "completed");
378
379 expect(task?.status).toBe("completed");
380 expect((await service.listApprovals("ws_test", "approved")).length).toBe(1);
381});
382
383test("policy deny blocks tool call without creating approval", async () => {
384 const service = new ExecutorService(
385 new TestExecutorDatabase(),
386 new TaskEventHub(),
387 [new InlineToolRuntime()],
388 tools,
389 );
390
391 await service.upsertAccessPolicy({
392 workspaceId: "ws_deny",
393 toolPathPattern: "admin.delete_data",
394 decision: "deny",
395 priority: 500,
396 });
397
398 const created = await service.createTask({
399 code: "unused",
400 runtimeId: "inline",
401 workspaceId: "ws_deny",
402 actorId: "actor_test",
403 });
404
405 const task = await waitForTaskStatus(service, created.task.id, "denied");
406 expect(task?.status).toBe("denied");
407 expect((await service.listPendingApprovals("ws_deny")).length).toBe(0);
408});
409
410test("unknown tool path fails task execution", async () => {
411 const service = new ExecutorService(
412 new TestExecutorDatabase(),
413 new TaskEventHub(),
414 [new InlineToolRuntime("admin.missing_tool")],
415 tools,
416 );
417
418 const created = await service.createTask({
419 code: "unused",
420 runtimeId: "inline",
421 workspaceId: "ws_unknown",
422 actorId: "actor_test",
423 });
424
425 const task = await waitForTaskStatus(service, created.task.id, "failed");
426 expect(task?.status).toBe("failed");
427 expect(task?.error).toContain("Unknown tool");
428});
executor/apps/server/src/service.ts+0−911
@@ -1,911 +0,0 @@
1import { ExecutorDatabase } from "./database";
2import { TaskEventHub, type LiveTaskEvent } from "./events";
3import { InProcessExecutionAdapter } from "./adapters/in-process-execution-adapter";
4import { APPROVAL_DENIED_PREFIX } from "./execution-constants";
5import { createDiscoverTool } from "./tool-discovery";
6import type { ExternalToolSourceConfig } from "./tool-sources";
7import { loadExternalTools, parseGraphqlOperationPaths } from "./tool-sources";
8import type {
9 AccessPolicyRecord,
10 AnonymousContext,
11 ApprovalRecord,
12 ApprovalStatus,
13 CredentialScope,
14 CreateTaskInput,
15 PendingApprovalRecord,
16 SandboxRuntime,
17 TaskEventRecord,
18 TaskRecord,
19 TaskStatus,
20 ToolCredentialSpec,
21 ToolCallResult,
22 ToolCallRequest,
23 ToolDefinition,
24 ToolDescriptor,
25 ToolSourceRecord,
26 RuntimeOutputEvent,
27 PolicyDecision,
28 ResolvedToolCredential,
29 CredentialRecord,
30 ToolRunContext,
31} from "./types";
32import { asPayload, describeError } from "./utils";
33
34function createTaskId(): string {
35 return `task_${crypto.randomUUID()}`;
36}
37
38function createApprovalId(): string {
39 return `approval_${crypto.randomUUID()}`;
40}
41
42// NOTE: Duplicated in convex/database.ts — these must be kept in sync.
43// They can't share code because Convex functions run in a separate environment.
44function matchesToolPath(pattern: string, toolPath: string): boolean {
45 const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
46 const regex = new RegExp(`^${escaped}$`);
47 return regex.test(toolPath);
48}
49
50// NOTE: Duplicated in convex/database.ts — these must be kept in sync.
51function policySpecificity(policy: AccessPolicyRecord, actorId?: string, clientId?: string): number {
52 let score = 0;
53 if (policy.actorId && actorId && policy.actorId === actorId) score += 4;
54 if (policy.clientId && clientId && policy.clientId === clientId) score += 2;
55 score += Math.max(1, policy.toolPathPattern.replace(/\*/g, "").length);
56 score += policy.priority;
57 return score;
58}
59
60function sourceSignature(workspaceId: string, sources: Array<{ id: string; updatedAt: number; enabled: boolean }>): string {
61 const parts = sources
62 .map((source) => `${source.id}:${source.updatedAt}:${source.enabled ? 1 : 0}`)
63 .sort();
64 return `${workspaceId}|${parts.join(",")}`;
65}
66
67function normalizeExternalToolSource(raw: {
68 type: ToolSourceRecord["type"];
69 name: string;
70 config: Record<string, unknown>;
71}): ExternalToolSourceConfig {
72 const merged = {
73 type: raw.type,
74 name: raw.name,
75 ...raw.config,
76 } as Record<string, unknown>;
77
78 if (raw.type === "mcp") {
79 if (typeof merged.url !== "string" || merged.url.trim().length === 0) {
80 throw new Error(`MCP source '${raw.name}' missing url`);
81 }
82
83 if (
84 merged.transport !== undefined &&
85 merged.transport !== "sse" &&
86 merged.transport !== "streamable-http"
87 ) {
88 throw new Error(`MCP source '${raw.name}' has invalid transport (expected 'sse' or 'streamable-http')`);
89 }
90
91 if (merged.queryParams !== undefined) {
92 const queryParams = merged.queryParams;
93 if (!queryParams || typeof queryParams !== "object" || Array.isArray(queryParams)) {
94 throw new Error(`MCP source '${raw.name}' queryParams must be an object`);
95 }
96
97 for (const [key, value] of Object.entries(queryParams as Record<string, unknown>)) {
98 if (typeof key !== "string" || key.trim().length === 0) {
99 throw new Error(`MCP source '${raw.name}' queryParams contains an invalid key`);
100 }
101 if (typeof value !== "string") {
102 throw new Error(`MCP source '${raw.name}' queryParams values must be strings`);
103 }
104 }
105 }
106
107 return merged as unknown as ExternalToolSourceConfig;
108 }
109
110 if (raw.type === "graphql") {
111 if (typeof merged.endpoint !== "string" || merged.endpoint.trim().length === 0) {
112 throw new Error(`GraphQL source '${raw.name}' missing endpoint`);
113 }
114 return merged as unknown as ExternalToolSourceConfig;
115 }
116
117 const spec = merged.spec;
118 if (typeof spec !== "string" && typeof spec !== "object") {
119 throw new Error(`OpenAPI source '${raw.name}' missing spec`);
120 }
121
122 return merged as unknown as ExternalToolSourceConfig;
123}
124
125export class ExecutorService {
126 private readonly db: ExecutorDatabase;
127 private readonly hub: TaskEventHub;
128 private readonly runtimes = new Map<string, SandboxRuntime>();
129 private readonly baseTools = new Map<string, ToolDefinition>();
130 private readonly workspaceToolCache = new Map<
131 string,
132 { signature: string; loadedAt: number; tools: Map<string, ToolDefinition> }
133 >();
134 private readonly workspaceToolLoadWarnings = new Map<string, string[]>();
135 private readonly inFlightTaskIds = new Set<string>();
136 private readonly autoExecuteTasks: boolean;
137
138 constructor(
139 db: ExecutorDatabase,
140 hub: TaskEventHub,
141 runtimes: SandboxRuntime[],
142 tools: ToolDefinition[],
143 options?: { autoExecuteTasks?: boolean },
144 ) {
145 this.db = db;
146 this.hub = hub;
147 this.autoExecuteTasks = options?.autoExecuteTasks ?? true;
148 for (const runtime of runtimes) {
149 this.runtimes.set(runtime.id, runtime);
150 }
151 for (const tool of tools) {
152 this.baseTools.set(tool.path, tool);
153 }
154 }
155
156 async listTasks(workspaceId: string): Promise<TaskRecord[]> {
157 return await this.db.listTasks(workspaceId);
158 }
159
160 async listQueuedTaskIds(limit = 20): Promise<string[]> {
161 return await this.db.listQueuedTaskIds(limit);
162 }
163
164 async runTask(taskId: string): Promise<void> {
165 await this.executeTask(taskId);
166 }
167
168 async getTask(taskId: string, workspaceId?: string): Promise<TaskRecord | null> {
169 if (workspaceId) {
170 return await this.db.getTaskInWorkspace(taskId, workspaceId);
171 }
172 return await this.db.getTask(taskId);
173 }
174
175 async listTaskEvents(taskId: string): Promise<TaskEventRecord[]> {
176 return await this.db.listTaskEvents(taskId);
177 }
178
179 subscribe(taskId: string, listener: (event: LiveTaskEvent) => void): () => void {
180 return this.hub.subscribe(taskId, listener);
181 }
182
183 async listApprovals(workspaceId: string, status?: ApprovalStatus): Promise<ApprovalRecord[]> {
184 return await this.db.listApprovals(workspaceId, status);
185 }
186
187 async upsertAccessPolicy(input: {
188 id?: string;
189 workspaceId: string;
190 actorId?: string;
191 clientId?: string;
192 toolPathPattern: string;
193 decision: PolicyDecision;
194 priority?: number;
195 }): Promise<AccessPolicyRecord> {
196 return await this.db.upsertAccessPolicy(input);
197 }
198
199 async listAccessPolicies(workspaceId: string): Promise<AccessPolicyRecord[]> {
200 return await this.db.listAccessPolicies(workspaceId);
201 }
202
203 async upsertCredential(input: {
204 id?: string;
205 workspaceId: string;
206 sourceKey: string;
207 scope: CredentialScope;
208 actorId?: string;
209 secretJson: Record<string, unknown>;
210 }): Promise<CredentialRecord> {
211 return await this.db.upsertCredential(input);
212 }
213
214 async listCredentials(
215 workspaceId: string,
216 ): Promise<Array<Omit<CredentialRecord, "secretJson"> & { hasSecret: boolean }>> {
217 return (await this.db.listCredentials(workspaceId)).map((credential) => ({
218 id: credential.id,
219 workspaceId: credential.workspaceId,
220 sourceKey: credential.sourceKey,
221 scope: credential.scope,
222 actorId: credential.actorId,
223 createdAt: credential.createdAt,
224 updatedAt: credential.updatedAt,
225 hasSecret: Object.keys(credential.secretJson).length > 0,
226 }));
227 }
228
229 async listToolSources(workspaceId: string): Promise<ToolSourceRecord[]> {
230 return await this.db.listToolSources(workspaceId);
231 }
232
233 async upsertToolSource(input: {
234 id?: string;
235 workspaceId: string;
236 name: string;
237 type: ToolSourceRecord["type"];
238 config: Record<string, unknown>;
239 enabled?: boolean;
240 }): Promise<ToolSourceRecord & { warnings?: string[] }> {
241 const source = await this.db.upsertToolSource(input);
242 this.workspaceToolCache.delete(source.workspaceId);
243 await this.getWorkspaceTools(source.workspaceId);
244 const warnings = this.workspaceToolLoadWarnings.get(source.workspaceId) ?? [];
245 return { ...source, warnings };
246 }
247
248 async deleteToolSource(workspaceId: string, sourceId: string): Promise<boolean> {
249 const deleted = await this.db.deleteToolSource(workspaceId, sourceId);
250 if (deleted) {
251 this.workspaceToolCache.delete(workspaceId);
252 await this.getWorkspaceTools(workspaceId);
253 }
254 return deleted;
255 }
256
257 async listPendingApprovals(workspaceId: string): Promise<PendingApprovalRecord[]> {
258 return await this.db.listPendingApprovals(workspaceId);
259 }
260
261 async bootstrapAnonymousContext(sessionId?: string): Promise<AnonymousContext> {
262 return await this.db.bootstrapAnonymousSession(sessionId);
263 }
264
265 async listTools(context?: {
266 workspaceId: string;
267 actorId?: string;
268 clientId?: string;
269 }): Promise<ToolDescriptor[]> {
270 if (!context) {
271 const all = [...this.baseTools.values()];
272 return all.map((tool) => ({
273 path: tool.path,
274 description: tool.description,
275 approval: tool.approval,
276 source: tool.source,
277 argsType: tool.metadata?.argsType,
278 returnsType: tool.metadata?.returnsType,
279 }));
280 }
281
282 const [workspaceTools, policies] = await Promise.all([
283 this.getWorkspaceTools(context.workspaceId),
284 this.db.listAccessPolicies(context.workspaceId),
285 ]);
286 const all = [...workspaceTools.values()];
287 return all
288 .filter((tool) => {
289 const decision = this.getDecisionForContext(tool, context, policies);
290 return decision !== "deny";
291 })
292 .map((tool) => {
293 const decision = this.getDecisionForContext(tool, context, policies);
294 return {
295 path: tool.path,
296 description: tool.description,
297 approval: decision === "require_approval" ? "required" : "auto",
298 source: tool.source,
299 argsType: tool.metadata?.argsType,
300 returnsType: tool.metadata?.returnsType,
301 };
302 });
303 }
304
305 listRuntimes(): Array<{ id: string; label: string; description: string }> {
306 return [...this.runtimes.values()].map((runtime) => ({
307 id: runtime.id,
308 label: runtime.label,
309 description: runtime.description,
310 }));
311 }
312
313 getBaseToolCount(): number {
314 return this.baseTools.size;
315 }
316
317 async createTask(input: CreateTaskInput): Promise<{ task: TaskRecord }> {
318 if (!input.code || input.code.trim().length === 0) {
319 throw new Error("Task code is required");
320 }
321
322 if (!input.workspaceId || input.workspaceId.trim().length === 0) {
323 throw new Error("workspaceId is required");
324 }
325
326 if (!input.actorId || input.actorId.trim().length === 0) {
327 throw new Error("actorId is required");
328 }
329
330 const runtimeId = input.runtimeId ?? "local-bun";
331 if (!this.runtimes.has(runtimeId)) {
332 throw new Error(`Unknown runtime: ${runtimeId}`);
333 }
334
335 const task = await this.db.createTask({
336 id: createTaskId(),
337 code: input.code,
338 runtimeId,
339 timeoutMs: input.timeoutMs,
340 metadata: input.metadata,
341 workspaceId: input.workspaceId,
342 actorId: input.actorId,
343 clientId: input.clientId,
344 });
345
346 await this.publish(task.id, "task", "task.created", {
347 taskId: task.id,
348 status: task.status,
349 runtimeId: task.runtimeId,
350 timeoutMs: task.timeoutMs,
351 workspaceId: task.workspaceId,
352 actorId: task.actorId,
353 clientId: task.clientId,
354 createdAt: task.createdAt,
355 });
356
357 await this.publish(task.id, "task", "task.queued", {
358 taskId: task.id,
359 status: "queued",
360 });
361
362 if (this.autoExecuteTasks) {
363 void this.executeTask(task.id);
364 }
365 return { task };
366 }
367
368 async resolveApproval(
369 workspaceId: string,
370 approvalId: string,
371 decision: "approved" | "denied",
372 reviewerId?: string,
373 reason?: string,
374 ): Promise<{ approval: ApprovalRecord; task: TaskRecord } | null> {
375 const scopedApproval = await this.db.getApprovalInWorkspace(approvalId, workspaceId);
376 if (!scopedApproval || scopedApproval.status !== "pending") {
377 return null;
378 }
379
380 const approval = await this.db.resolveApproval({
381 approvalId,
382 decision,
383 reviewerId,
384 reason,
385 });
386
387 if (!approval) {
388 return null;
389 }
390
391 await this.publish(approval.taskId, "approval", "approval.resolved", {
392 approvalId: approval.id,
393 taskId: approval.taskId,
394 toolPath: approval.toolPath,
395 decision: approval.status,
396 reviewerId: approval.reviewerId,
397 reason: approval.reason,
398 resolvedAt: approval.resolvedAt,
399 });
400
401 const task = await this.db.getTask(approval.taskId);
402 if (!task) {
403 throw new Error(`Task ${approval.taskId} missing while resolving approval`);
404 }
405
406 return { approval, task };
407 }
408
409 async handleExternalToolCall(call: ToolCallRequest): Promise<ToolCallResult> {
410 const task = await this.db.getTask(call.runId);
411 if (!task) {
412 return {
413 ok: false,
414 error: `Run not found: ${call.runId}`,
415 };
416 }
417
418 try {
419 const value = await this.invokeTool(task, call);
420 return { ok: true, value };
421 } catch (error) {
422 const message = describeError(error);
423 if (message.startsWith(APPROVAL_DENIED_PREFIX)) {
424 return {
425 ok: false,
426 denied: true,
427 error: message.replace(APPROVAL_DENIED_PREFIX, "").trim(),
428 };
429 }
430
431 return {
432 ok: false,
433 error: message,
434 };
435 }
436 }
437
438 async appendRuntimeOutput(event: RuntimeOutputEvent): Promise<void> {
439 await this.publish(
440 event.runId,
441 "task",
442 event.stream === "stdout" ? "task.stdout" : "task.stderr",
443 {
444 taskId: event.runId,
445 line: event.line,
446 timestamp: event.timestamp,
447 },
448 );
449 }
450
451 private async publish(
452 taskId: string,
453 eventName: TaskEventRecord["eventName"],
454 type: string,
455 payload: Record<string, unknown>,
456 ): Promise<void> {
457 const event = await this.db.createTaskEvent({ taskId, eventName, type, payload });
458 this.hub.publish(taskId, {
459 id: event.id,
460 eventName,
461 payload,
462 createdAt: event.createdAt,
463 });
464 }
465
466 private async waitForApproval(approvalId: string): Promise<"approved" | "denied"> {
467 while (true) {
468 const approval = await this.db.getApproval(approvalId);
469 if (!approval) {
470 throw new Error(`Approval ${approvalId} not found`);
471 }
472
473 if (approval.status !== "pending") {
474 return approval.status as "approved" | "denied";
475 }
476
477 await Bun.sleep(600);
478 }
479 }
480
481 private async getWorkspaceTools(workspaceId: string): Promise<Map<string, ToolDefinition>> {
482 const sources = (await this.db.listToolSources(workspaceId)).filter((source) => source.enabled);
483 const signature = sourceSignature(workspaceId, sources);
484 const cached = this.workspaceToolCache.get(workspaceId);
485 if (cached && cached.signature === signature) {
486 return cached.tools;
487 }
488
489 const configs: ExternalToolSourceConfig[] = [];
490 const warnings: string[] = [];
491 for (const source of sources) {
492 try {
493 configs.push(normalizeExternalToolSource(source));
494 } catch (error) {
495 const message = error instanceof Error ? error.message : String(error);
496 warnings.push(`Source '${source.name}': ${message}`);
497 console.warn(`[executor] skipping invalid source ${source.id}: ${message}`);
498 }
499 }
500
501 const { tools: externalTools, warnings: loadWarnings } = await loadExternalTools(configs);
502 warnings.push(...loadWarnings);
503 this.workspaceToolLoadWarnings.set(workspaceId, warnings);
504
505 const merged = new Map<string, ToolDefinition>();
506 for (const tool of this.baseTools.values()) {
507 if (tool.path === "discover") continue;
508 merged.set(tool.path, tool);
509 }
510 for (const tool of externalTools) {
511 merged.set(tool.path, tool);
512 }
513
514 const discover = createDiscoverTool([...merged.values()]);
515 merged.set(discover.path, discover);
516
517 this.workspaceToolCache.set(workspaceId, {
518 signature,
519 loadedAt: Date.now(),
520 tools: merged,
521 });
522
523 return merged;
524 }
525
526 private getToolDecision(
527 task: TaskRecord,
528 tool: ToolDefinition,
529 policies: AccessPolicyRecord[],
530 ): PolicyDecision {
531 return this.getDecisionForContext(
532 tool,
533 {
534 workspaceId: task.workspaceId,
535 actorId: task.actorId,
536 clientId: task.clientId,
537 },
538 policies,
539 );
540 }
541
542 private getDecisionForContext(
543 tool: ToolDefinition,
544 context: { workspaceId: string; actorId?: string; clientId?: string },
545 policies: AccessPolicyRecord[],
546 ): PolicyDecision {
547 const defaultDecision: PolicyDecision = tool.approval === "required" ? "require_approval" : "allow";
548 const candidates = policies
549 .filter((policy) => {
550 if (policy.actorId && policy.actorId !== context.actorId) return false;
551 if (policy.clientId && policy.clientId !== context.clientId) return false;
552 return matchesToolPath(policy.toolPathPattern, tool.path);
553 })
554 .sort(
555 (a, b) =>
556 policySpecificity(b, context.actorId, context.clientId) -
557 policySpecificity(a, context.actorId, context.clientId),
558 );
559
560 return candidates[0]?.decision ?? defaultDecision;
561 }
562
563 private isToolAllowedForTask(
564 task: TaskRecord,
565 toolPath: string,
566 workspaceTools: Map<string, ToolDefinition>,
567 policies: AccessPolicyRecord[],
568 ): boolean {
569 const tool = workspaceTools.get(toolPath);
570 if (!tool) return false;
571 return this.getToolDecision(task, tool, policies) !== "deny";
572 }
573
574 private async resolveCredentialHeaders(
575 spec: ToolCredentialSpec,
576 task: TaskRecord,
577 ): Promise<ResolvedToolCredential | null> {
578 const record = await this.db.resolveCredential({
579 workspaceId: task.workspaceId,
580 sourceKey: spec.sourceKey,
581 scope: spec.mode,
582 actorId: task.actorId,
583 });
584
585 const source = record?.secretJson ?? spec.staticSecretJson ?? null;
586 if (!source) {
587 return null;
588 }
589
590 const headers: Record<string, string> = {};
591 if (spec.authType === "bearer") {
592 const token = String((source as Record<string, unknown>).token ?? "").trim();
593 if (token) headers.authorization = `Bearer ${token}`;
594 } else if (spec.authType === "apiKey") {
595 const headerName = spec.headerName ?? String((source as Record<string, unknown>).headerName ?? "x-api-key");
596 const value = String((source as Record<string, unknown>).value ?? (source as Record<string, unknown>).token ?? "").trim();
597 if (value) headers[headerName] = value;
598 } else if (spec.authType === "basic") {
599 const username = String((source as Record<string, unknown>).username ?? "");
600 const password = String((source as Record<string, unknown>).password ?? "");
601 if (username || password) {
602 const encoded = Buffer.from(`${username}:${password}`, "utf8").toString("base64");
603 headers.authorization = `Basic ${encoded}`;
604 }
605 }
606
607 if (Object.keys(headers).length === 0) {
608 return null;
609 }
610
611 return {
612 sourceKey: spec.sourceKey,
613 mode: spec.mode,
614 headers,
615 };
616 }
617
618 /**
619 * For GraphQL tools with _graphqlSource, resolve the approval decision
620 * by parsing the query and checking policies against each virtual field path
621 * (e.g. linear.mutation.issueCreate, linear.query.issues).
622 *
623 * Returns the most restrictive decision across all field paths.
624 */
625 private getGraphqlDecision(
626 task: TaskRecord,
627 tool: ToolDefinition,
628 input: unknown,
629 workspaceTools: Map<string, ToolDefinition>,
630 policies: AccessPolicyRecord[],
631 ): { decision: PolicyDecision; effectivePaths: string[] } {
632 const sourceName = tool._graphqlSource!;
633 const payload = input && typeof input === "object" ? (input as Record<string, unknown>) : {};
634 const queryString = typeof payload.query === "string" ? payload.query : "";
635
636 if (!queryString.trim()) {
637 // No query to parse — fall back to tool's own approval
638 return { decision: this.getToolDecision(task, tool, policies), effectivePaths: [tool.path] };
639 }
640
641 const { fieldPaths } = parseGraphqlOperationPaths(sourceName, queryString);
642 if (fieldPaths.length === 0) {
643 return { decision: this.getToolDecision(task, tool, policies), effectivePaths: [tool.path] };
644 }
645
646 let worstDecision: PolicyDecision = "allow";
647
648 for (const fieldPath of fieldPaths) {
649 // Look up the pseudo-tool for this field path to get its default approval
650 const pseudoTool = workspaceTools.get(fieldPath);
651 const fieldDecision = pseudoTool
652 ? this.getDecisionForContext(pseudoTool, {
653 workspaceId: task.workspaceId,
654 actorId: task.actorId,
655 clientId: task.clientId,
656 }, policies)
657 : // Unknown field — check if any policies match, otherwise default to mutation=required
658 this.getDecisionForContext(
659 { ...tool, path: fieldPath, approval: fieldPath.includes(".mutation.") ? "required" : "auto" },
660 {
661 workspaceId: task.workspaceId,
662 actorId: task.actorId,
663 clientId: task.clientId,
664 },
665 policies,
666 );
667
668 // Escalate: deny > require_approval > allow
669 if (fieldDecision === "deny") {
670 worstDecision = "deny";
671 break; // Can't get worse
672 }
673 if (fieldDecision === "require_approval") {
674 worstDecision = "require_approval";
675 }
676 }
677
678 return { decision: worstDecision, effectivePaths: fieldPaths };
679 }
680
681 private async invokeTool(task: TaskRecord, call: ToolCallRequest): Promise<unknown> {
682 const { toolPath, input, callId } = call;
683 const [workspaceTools, policies] = await Promise.all([
684 this.getWorkspaceTools(task.workspaceId),
685 this.db.listAccessPolicies(task.workspaceId),
686 ]);
687 const tool = workspaceTools.get(toolPath);
688 if (!tool) {
689 throw new Error(`Unknown tool: ${toolPath}`);
690 }
691
692 // Determine approval decision — for GraphQL tools, parse the query for granular paths
693 let decision: PolicyDecision;
694 let effectiveToolPath = toolPath;
695
696 if (tool._graphqlSource) {
697 const result = this.getGraphqlDecision(task, tool, input, workspaceTools, policies);
698 decision = result.decision;
699 // Use the field paths for event reporting so approvals show what's actually being called
700 if (result.effectivePaths.length > 0) {
701 effectiveToolPath = result.effectivePaths.join(", ");
702 }
703 } else {
704 decision = this.getToolDecision(task, tool, policies);
705 }
706
707 if (decision === "deny") {
708 await this.publish(task.id, "task", "tool.call.denied", {
709 taskId: task.id,
710 callId,
711 toolPath: effectiveToolPath,
712 reason: "policy_deny",
713 });
714 throw new Error(`${APPROVAL_DENIED_PREFIX}${effectiveToolPath} (policy denied)`);
715 }
716
717 let credential: ResolvedToolCredential | undefined;
718 if (tool.credential) {
719 const resolved = await this.resolveCredentialHeaders(tool.credential, task);
720 if (!resolved) {
721 throw new Error(
722 `Missing credential for source '${tool.credential.sourceKey}' (${tool.credential.mode} scope)`,
723 );
724 }
725 credential = resolved;
726 }
727
728 await this.publish(task.id, "task", "tool.call.started", {
729 taskId: task.id,
730 callId,
731 toolPath: effectiveToolPath,
732 approval: decision === "require_approval" ? "required" : "auto",
733 input: asPayload(input),
734 });
735
736 if (decision === "require_approval") {
737 const approval = await this.db.createApproval({
738 id: createApprovalId(),
739 taskId: task.id,
740 toolPath: effectiveToolPath,
741 input,
742 });
743
744 await this.publish(task.id, "approval", "approval.requested", {
745 approvalId: approval.id,
746 taskId: task.id,
747 callId,
748 toolPath: approval.toolPath,
749 input: asPayload(approval.input),
750 createdAt: approval.createdAt,
751 });
752
753 const approvalDecision = await this.waitForApproval(approval.id);
754 if (approvalDecision === "denied") {
755 await this.publish(task.id, "task", "tool.call.denied", {
756 taskId: task.id,
757 callId,
758 toolPath: effectiveToolPath,
759 approvalId: approval.id,
760 });
761 throw new Error(`${APPROVAL_DENIED_PREFIX}${effectiveToolPath} (${approval.id})`);
762 }
763 }
764
765 try {
766 const context: ToolRunContext = {
767 taskId: task.id,
768 workspaceId: task.workspaceId,
769 actorId: task.actorId,
770 clientId: task.clientId,
771 credential,
772 isToolAllowed: (path) => this.isToolAllowedForTask(task, path, workspaceTools, policies),
773 };
774 const value = await tool.run(input, context);
775 await this.publish(task.id, "task", "tool.call.completed", {
776 taskId: task.id,
777 callId,
778 toolPath: effectiveToolPath,
779 output: asPayload(value),
780 });
781 return value;
782 } catch (error) {
783 const message = describeError(error);
784 await this.publish(task.id, "task", "tool.call.failed", {
785 taskId: task.id,
786 callId,
787 toolPath: effectiveToolPath,
788 error: message,
789 });
790 throw error;
791 }
792 }
793
794 private async executeTask(taskId: string): Promise<void> {
795 if (this.inFlightTaskIds.has(taskId)) {
796 return;
797 }
798
799 this.inFlightTaskIds.add(taskId);
800 try {
801 const task = await this.db.getTask(taskId);
802 if (!task || task.status !== "queued") {
803 return;
804 }
805
806 const runtime = this.runtimes.get(task.runtimeId);
807 if (!runtime) {
808 const failed = await this.db.markTaskFinished({
809 taskId,
810 status: "failed",
811 stdout: "",
812 stderr: "",
813 error: `Runtime not found: ${task.runtimeId}`,
814 });
815
816 if (failed) {
817 await this.publish(taskId, "task", "task.failed", {
818 taskId,
819 status: failed.status,
820 error: failed.error,
821 });
822 }
823 return;
824 }
825
826 const running = await this.db.markTaskRunning(taskId);
827 if (!running) {
828 return;
829 }
830
831 await this.publish(taskId, "task", "task.running", {
832 taskId,
833 status: running.status,
834 startedAt: running.startedAt,
835 });
836
837 const adapter = new InProcessExecutionAdapter({
838 runId: taskId,
839 invokeTool: async (call) => await this.invokeTool(running, call),
840 emitOutput: async (event) => {
841 await this.appendRuntimeOutput(event);
842 },
843 });
844
845 const runtimeResult = await runtime.run(
846 {
847 taskId,
848 code: running.code,
849 timeoutMs: running.timeoutMs,
850 },
851 adapter,
852 );
853
854 const finished = await this.db.markTaskFinished({
855 taskId,
856 status: runtimeResult.status,
857 stdout: runtimeResult.stdout,
858 stderr: runtimeResult.stderr,
859 exitCode: runtimeResult.exitCode,
860 error: runtimeResult.error,
861 });
862
863 if (!finished) {
864 return;
865 }
866
867 const terminalEvent =
868 runtimeResult.status === "completed"
869 ? "task.completed"
870 : runtimeResult.status === "timed_out"
871 ? "task.timed_out"
872 : runtimeResult.status === "denied"
873 ? "task.denied"
874 : "task.failed";
875
876 await this.publish(taskId, "task", terminalEvent, {
877 taskId,
878 status: finished.status,
879 exitCode: finished.exitCode,
880 durationMs: runtimeResult.durationMs,
881 error: finished.error,
882 completedAt: finished.completedAt,
883 });
884 } catch (error) {
885 const message = describeError(error);
886 const denied = message.startsWith(APPROVAL_DENIED_PREFIX);
887 const finished = await this.db.markTaskFinished({
888 taskId,
889 status: denied ? "denied" : "failed",
890 stdout: "",
891 stderr: "",
892 error: denied ? message.replace(APPROVAL_DENIED_PREFIX, "") : message,
893 });
894
895 if (finished) {
896 await this.publish(taskId, "task", denied ? "task.denied" : "task.failed", {
897 taskId,
898 status: finished.status,
899 error: finished.error,
900 completedAt: finished.completedAt,
901 });
902 }
903 } finally {
904 this.inFlightTaskIds.delete(taskId);
905 }
906 }
907}
908
909export function getTaskTerminalState(status: TaskStatus): boolean {
910 return status === "completed" || status === "failed" || status === "timed_out" || status === "denied";
911}
executor/apps/server/src/tailscale-funnel.ts+0−116
@@ -1,116 +0,0 @@
1interface CommandResult {
2 ok: boolean;
3 exitCode: number;
4 stdout: string;
5 stderr: string;
6}
7
8interface FunnelStatusEntry {
9 Handlers?: Record<string, { Proxy?: string }>;
10}
11
12interface FunnelStatus {
13 Web?: Record<string, FunnelStatusEntry>;
14 AllowFunnel?: Record<string, boolean>;
15}
16
17function runCommand(args: string[]): CommandResult {
18 const proc = Bun.spawnSync(args, {
19 stdout: "pipe",
20 stderr: "pipe",
21 });
22
23 const stdout = proc.stdout.toString();
24 const stderr = proc.stderr.toString();
25 const exitCode = proc.exitCode ?? 1;
26
27 return {
28 ok: exitCode === 0,
29 exitCode,
30 stdout,
31 stderr,
32 };
33}
34
35function normalizeHostname(hostnamePort: string): string {
36 return hostnamePort.endsWith(":443") ? hostnamePort.slice(0, -4) : hostnamePort;
37}
38
39function extractFunnelUrlForPort(status: FunnelStatus, port: number): string | null {
40 const web = status.Web;
41 if (!web || typeof web !== "object") {
42 return null;
43 }
44
45 const allowFunnel = status.AllowFunnel ?? {};
46
47 for (const [host, entry] of Object.entries(web)) {
48 if (allowFunnel[host] !== true) {
49 continue;
50 }
51
52 const handlers = entry.Handlers;
53 if (!handlers || typeof handlers !== "object") {
54 continue;
55 }
56
57 for (const handler of Object.values(handlers)) {
58 const proxy = handler.Proxy;
59 if (typeof proxy !== "string") {
60 continue;
61 }
62
63 if (proxy.includes(`:${port}`)) {
64 return `https://${normalizeHostname(host)}`;
65 }
66 }
67 }
68
69 return null;
70}
71
72function readFunnelStatus(port: number): string | null {
73 const statusResult = runCommand(["tailscale", "funnel", "status", "--json"]);
74 if (!statusResult.ok || statusResult.stdout.trim().length === 0) {
75 return null;
76 }
77
78 try {
79 const parsed = JSON.parse(statusResult.stdout) as FunnelStatus;
80 return extractFunnelUrlForPort(parsed, port);
81 } catch {
82 return null;
83 }
84}
85
86export interface EnsureFunnelResult {
87 url: string;
88 created: boolean;
89}
90
91export function ensureTailscaleFunnel(port: number): EnsureFunnelResult {
92 const existing = readFunnelStatus(port);
93 if (existing) {
94 return { url: existing, created: false };
95 }
96
97 const startResult = runCommand([
98 "tailscale",
99 "funnel",
100 "--bg",
101 "--yes",
102 String(port),
103 ]);
104
105 if (!startResult.ok) {
106 const message = startResult.stderr.trim() || startResult.stdout.trim() || "unknown error";
107 throw new Error(`tailscale funnel failed: ${message}`);
108 }
109
110 const created = readFunnelStatus(port);
111 if (!created) {
112 throw new Error("tailscale funnel started but no URL found in status output");
113 }
114
115 return { url: created, created: true };
116}
executor/apps/server/src/worker.ts+0−111
@@ -1,111 +0,0 @@
1import { ConvexClient } from "convex/browser";
2import { api } from "../../../convex/_generated/api";
3import { ExecutorDatabase } from "./database";
4import { TaskEventHub } from "./events";
5import { LocalBunRuntime } from "./runtimes/local-bun-runtime";
6import { VercelSandboxRuntime } from "./runtimes/vercel-sandbox-runtime";
7import { ExecutorService } from "./service";
8import { loadExternalTools, parseToolSourcesFromEnv } from "./tool-sources";
9import { DEFAULT_TOOLS } from "./tools";
10
11const convexUrl = Bun.env.EXECUTOR_CONVEX_URL ?? Bun.env.CONVEX_URL ?? "http://127.0.0.1:3210";
12const internalBaseUrl = Bun.env.EXECUTOR_INTERNAL_BASE_URL ?? Bun.env.EXECUTOR_PUBLIC_BASE_URL ?? "http://127.0.0.1:4001";
13const internalToken = Bun.env.EXECUTOR_INTERNAL_TOKEN ?? "executor_internal_local_dev_token";
14const pollMs = Number(Bun.env.EXECUTOR_WORKER_POLL_MS ?? "2000");
15const queueBatchSize = Number(Bun.env.EXECUTOR_WORKER_BATCH_SIZE ?? "20");
16
17const toolSourceConfigs = (() => {
18 try {
19 return parseToolSourcesFromEnv(Bun.env.EXECUTOR_TOOL_SOURCES);
20 } catch (error) {
21 const message = error instanceof Error ? error.message : String(error);
22 console.warn(`[worker] invalid EXECUTOR_TOOL_SOURCES: ${message}`);
23 return [];
24 }
25})();
26
27const { tools: externalTools, warnings: externalToolWarnings } = await loadExternalTools(toolSourceConfigs);
28if (externalToolWarnings.length > 0) {
29 for (const warning of externalToolWarnings) {
30 console.warn(`[worker] ${warning}`);
31 }
32}
33
34const service = new ExecutorService(
35 new ExecutorDatabase(convexUrl),
36 new TaskEventHub(),
37 [
38 new LocalBunRuntime(),
39 new VercelSandboxRuntime({
40 controlPlaneBaseUrl: internalBaseUrl,
41 internalToken,
42 runtime: Bun.env.EXECUTOR_VERCEL_SANDBOX_RUNTIME as "node24" | "node22" | undefined,
43 }),
44 ],
45 [...DEFAULT_TOOLS, ...externalTools],
46 { autoExecuteTasks: false },
47);
48
49const convexClient = new ConvexClient(convexUrl, {
50 unsavedChangesWarning: false,
51});
52
53let draining = false;
54
55async function drainQueue(trigger: string): Promise<void> {
56 if (draining) {
57 return;
58 }
59
60 draining = true;
61 try {
62 while (true) {
63 const queuedTaskIds = await service.listQueuedTaskIds(queueBatchSize);
64 if (queuedTaskIds.length === 0) {
65 return;
66 }
67
68 console.log(`[worker] ${trigger}: processing ${queuedTaskIds.length} queued task(s)`);
69 for (const taskId of queuedTaskIds) {
70 await service.runTask(taskId);
71 }
72 }
73 } catch (error) {
74 const message = error instanceof Error ? error.message : String(error);
75 console.error(`[worker] drain failed: ${message}`);
76 } finally {
77 draining = false;
78 }
79}
80
81const queueSubscription = convexClient.onUpdate(
82 api.database.listQueuedTaskIds,
83 { limit: 1 },
84 (taskIds) => {
85 if (taskIds.length > 0) {
86 void drainQueue("onUpdate");
87 }
88 },
89 (error) => {
90 console.warn(`[worker] queue watcher error: ${error.message}`);
91 },
92);
93
94const interval = setInterval(() => {
95 void drainQueue("interval");
96}, pollMs);
97
98await drainQueue("startup");
99
100function shutdown(signal: string): void {
101 console.log(`[worker] received ${signal}, shutting down...`);
102 queueSubscription.unsubscribe();
103 clearInterval(interval);
104 void convexClient.close();
105 process.exit(0);
106}
107
108process.on("SIGINT", () => shutdown("SIGINT"));
109process.on("SIGTERM", () => shutdown("SIGTERM"));
110
111console.log(`[worker] listening for queued tasks via Convex (${convexUrl})`);
executor/apps/server/tsconfig.json+0−16
@@ -1,16 +0,0 @@
1{
2 "compilerOptions": {
3 "target": "ESNext",
4 "module": "ESNext",
5 "moduleResolution": "bundler",
6 "strict": true,
7 "noEmit": true,
8 "types": [
9 "bun"
10 ],
11 "skipLibCheck": true
12 },
13 "include": [
14 "src/**/*.ts"
15 ]
16}
executor/apps/web/src/lib/session-context.tsx+76−198
@@ -4,12 +4,12 @@ import { · 3 unmodified lines
4 createContext,4 createContext,
5 useCallback,5 useCallback,
6 useContext,6 useContext,
7 useEffect,
8 useMemo,7 useMemo,
9 useState,8 useState,
10 type ReactNode,9 type ReactNode,
11} from "react";10} from "react";
12import { useMutation, useQuery } from "convex/react";11import { useMutation, useQuery as useConvexQuery } from "convex/react";
12import { useQuery as useTanstackQuery } from "@tanstack/react-query";
13import { workosEnabled } from "@/lib/auth-capabilities";13import { workosEnabled } from "@/lib/auth-capabilities";
14import { convexApi } from "@/lib/convex-api";14import { convexApi } from "@/lib/convex-api";
15import type { AnonymousContext } from "./types";15import type { AnonymousContext } from "./types";
@@ -36,8 +36,6 @@ interface SessionState { · 20 unmodified lines
36 status: string;36 status: string;
37 role: string;37 role: string;
38 }>;38 }>;
39 selectedOrganizationId: string | null;
40 switchOrganization: (organizationId: string | null) => void;
41 workspaces: Array<{39 workspaces: Array<{
42 id: string;40 id: string;
43 docId: Id<"workspaces"> | null;41 docId: Id<"workspaces"> | null;
@@ -65,8 +63,6 @@ const SessionContext = createContext<SessionState>({ · 21 unmodified lines
65 clientConfig: null,63 clientConfig: null,
66 mode: "guest",64 mode: "guest",
67 organizations: [],65 organizations: [],
68 selectedOrganizationId: null,
69 switchOrganization: () => {},
70 workspaces: [],66 workspaces: [],
71 switchWorkspace: () => {},67 switchWorkspace: () => {},
72 creatingWorkspace: false,68 creatingWorkspace: false,
@@ -78,7 +74,6 @@ const SessionContext = createContext<SessionState>({ · 5 unmodified lines
78 74
79const SESSION_KEY = "executor_session_id";75const SESSION_KEY = "executor_session_id";
80const ACTIVE_WORKSPACE_KEY = "executor_active_workspace_id";76const ACTIVE_WORKSPACE_KEY = "executor_active_workspace_id";
81const ACTIVE_ORGANIZATION_KEY = "executor_active_organization_id";
82const ACTIVE_WORKSPACE_BY_ACCOUNT_KEY = "executor_active_workspace_by_account";77const ACTIVE_WORKSPACE_BY_ACCOUNT_KEY = "executor_active_workspace_by_account";
83 78
84function readWorkspaceByAccount() {79function readWorkspaceByAccount() {
@@ -98,203 +93,98 @@ function writeWorkspaceByAccount(value: Record<string, string>) { · 13 unmodified lines
98 93
99export function SessionProvider({ children }: { children: ReactNode }) {94export function SessionProvider({ children }: { children: ReactNode }) {
100 const bootstrapAnonymousSession = useMutation(convexApi.database.bootstrapAnonymousSession);95 const bootstrapAnonymousSession = useMutation(convexApi.database.bootstrapAnonymousSession);
101 const [guestContext, setGuestContext] = useState<AnonymousContext | null>(null);96 const [storedSessionId, setStoredSessionId] = useState<string | null>(() => {
102 const [storedSessionId, setStoredSessionId] = useState<string | null>(null);97 if (typeof window === "undefined") {
103 const [activeWorkspaceId, setActiveWorkspaceId] = useState<string | null>(null);98 return null;
104 const [selectedOrganizationId, setSelectedOrganizationId] = useState<string | null>(null);99 }
105 const [loading, setLoading] = useState(true);100 return localStorage.getItem(SESSION_KEY);
106 const [error, setError] = useState<string | null>(null);101 });
102 const [activeWorkspaceId, setActiveWorkspaceId] = useState<string | null>(() => {
103 if (typeof window === "undefined") {
104 return null;
105 }
106 return localStorage.getItem(ACTIVE_WORKSPACE_KEY);
107 });
108 const [runtimeError, setRuntimeError] = useState<string | null>(null);
107 109
108 const clientConfig = useQuery(convexApi.app.getClientConfig, {});110 const clientConfig = useConvexQuery(convexApi.app.getClientConfig, {});
109 111
110 const authApi = convexApi.auth;112 const authApi = convexApi.auth;
111 const bootstrapCurrentWorkosAccount = useMutation(authApi.bootstrapCurrentWorkosAccount);113 const bootstrapCurrentWorkosAccount = useMutation(authApi.bootstrapCurrentWorkosAccount);
112 const createWorkspaceMutation = useMutation(authApi.createWorkspace);114 const createWorkspaceMutation = useMutation(authApi.createWorkspace);
113 const generateWorkspaceIconUploadUrl = useMutation(authApi.generateWorkspaceIconUploadUrl);115 const generateWorkspaceIconUploadUrl = useMutation(authApi.generateWorkspaceIconUploadUrl);
114 const [bootstrappingWorkos, setBootstrappingWorkos] = useState(false);
115 const [workosBootstrapAttempted, setWorkosBootstrapAttempted] = useState(false);
116 const [creatingWorkspace, setCreatingWorkspace] = useState(false);116 const [creatingWorkspace, setCreatingWorkspace] = useState(false);
117 117
118 const account = useQuery(118 const bootstrapSessionQuery = useTanstackQuery({
119 queryKey: ["session-bootstrap", storedSessionId ?? "new"],
120 retry: false,
121 staleTime: Number.POSITIVE_INFINITY,
122 queryFn: async () => {
123 const context = await bootstrapAnonymousSession({ sessionId: storedSessionId ?? undefined });
124 localStorage.setItem(SESSION_KEY, context.sessionId);
125 if (context.sessionId !== storedSessionId) {
126 setStoredSessionId(context.sessionId);
127 }
128 return context;
129 },
130 });
131
132 const guestContext: AnonymousContext | null = bootstrapSessionQuery.data ?? null;
133
134 const account = useConvexQuery(
119 authApi.getCurrentAccount,135 authApi.getCurrentAccount,
120 workosEnabled ? { sessionId: storedSessionId ?? undefined } : "skip",136 workosEnabled ? { sessionId: storedSessionId ?? undefined } : "skip",
121 );137 );
122 const workspaces = useQuery(138 const workspaces = useConvexQuery(
123 authApi.getMyWorkspaces,139 authApi.getMyWorkspaces,
124 workosEnabled ? { sessionId: storedSessionId ?? undefined } : "skip",140 workosEnabled ? { sessionId: storedSessionId ?? undefined } : "skip",
125 );141 );
126 const organizations = useQuery(142 const organizations = useConvexQuery(
127 convexApi.organizations.listMine,143 convexApi.organizations.listMine,
128 workosEnabled ? { sessionId: storedSessionId ?? undefined } : "skip",144 workosEnabled ? { sessionId: storedSessionId ?? undefined } : "skip",
129 );145 );
130 146
131 const bootstrap = useCallback(async (sessionId?: string) => {147 const resolvedActiveWorkspaceId = useMemo(() => {
132 setLoading(true);148 if (!workspaces || workspaces.length === 0) {
133 setError(null);149 return activeWorkspaceId;
134 try {
135 const context = await bootstrapAnonymousSession({ sessionId });
136 localStorage.setItem(SESSION_KEY, context.sessionId);
137 setStoredSessionId(context.sessionId);
138 setGuestContext(context);
139 } catch (cause) {
140 setError(cause instanceof Error ? cause.message : "Failed to bootstrap session");
141 } finally {
142 setLoading(false);
143 }
144 }, [bootstrapAnonymousSession]);
145
146 useEffect(() => {
147 const stored = localStorage.getItem(SESSION_KEY);
148 const activeWorkspace = localStorage.getItem(ACTIVE_WORKSPACE_KEY);
149 const activeOrganization = localStorage.getItem(ACTIVE_ORGANIZATION_KEY);
150 if (activeWorkspace) {
151 setActiveWorkspaceId(activeWorkspace);
152 }
153 if (activeOrganization) {
154 setSelectedOrganizationId(activeOrganization);
155 }150 }
156 void bootstrap(stored ?? undefined);
157 }, [bootstrap]);
158 151
159 useEffect(() => {152 if (activeWorkspaceId && workspaces.some((workspace) => workspace.runtimeWorkspaceId === activeWorkspaceId)) {
160 if (!workspaces || workspaces.length === 0) {153 return activeWorkspaceId;
161 return;
162 }154 }
163 155
164 const accountId = account?.provider === "workos" ? String(account._id) : null;156 const accountId = account?.provider === "workos" ? String(account._id) : null;
165 const byAccount = accountId ? readWorkspaceByAccount() : null;157 const accountStoredWorkspace = accountId ? readWorkspaceByAccount()[accountId] : null;
166 const accountStoredWorkspace = accountId ? byAccount?.[accountId] : null;158 if (accountStoredWorkspace && workspaces.some((workspace) => workspace.runtimeWorkspaceId === accountStoredWorkspace)) {
167 const currentCandidate = activeWorkspaceId ?? accountStoredWorkspace;159 return accountStoredWorkspace;
168
169 if (currentCandidate && workspaces.some((workspace) => workspace.runtimeWorkspaceId === currentCandidate)) {
170 if (activeWorkspaceId !== currentCandidate) {
171 setActiveWorkspaceId(currentCandidate);
172 }
173 return;
174 }160 }
175 161
176 const organizationWorkspace = workspaces.find(162 const organizationWorkspace = workspaces.find(
177 (workspace) => workspace.kind === "organization" || workspace.kind === "org",163 (workspace) => workspace.kind === "organization" || workspace.kind === "org",
178 );164 );
179 const nextWorkspace = organizationWorkspace?.runtimeWorkspaceId ?? workspaces[0]?.runtimeWorkspaceId;165 return organizationWorkspace?.runtimeWorkspaceId ?? workspaces[0]?.runtimeWorkspaceId ?? null;
180 if (!nextWorkspace) {
181 return;
182 }
183
184 setActiveWorkspaceId(nextWorkspace);
185 if (accountId) {
186 writeWorkspaceByAccount({
187 ...(byAccount ?? {}),
188 [accountId]: nextWorkspace,
189 });
190 }
191 localStorage.setItem(ACTIVE_WORKSPACE_KEY, nextWorkspace);
192 }, [workspaces, activeWorkspaceId, account]);166 }, [workspaces, activeWorkspaceId, account]);
193 167
194 useEffect(() => {168 const bootstrapWorkosAccountQuery = useTanstackQuery({
195 if (!organizations || organizations.length === 0) {169 queryKey: ["workos-account-bootstrap", storedSessionId ?? "none"],
196 if (selectedOrganizationId !== null) {170 enabled: workosEnabled && account !== undefined,
197 setSelectedOrganizationId(null);171 retry: false,
198 localStorage.removeItem(ACTIVE_ORGANIZATION_KEY);172 staleTime: Number.POSITIVE_INFINITY,
199 }173 queryFn: async () => bootstrapCurrentWorkosAccount({}),
200 return;174 });
201 }
202
203 if (selectedOrganizationId && organizations.some((organization) => organization.id === selectedOrganizationId)) {
204 return;
205 }
206
207 const nextOrganizationId = organizations[0]?.id ?? null;
208 setSelectedOrganizationId(nextOrganizationId);
209 if (nextOrganizationId) {
210 localStorage.setItem(ACTIVE_ORGANIZATION_KEY, nextOrganizationId);
211 }
212 }, [organizations, selectedOrganizationId]);
213
214 useEffect(() => {
215 if (!workspaces || workspaces.length === 0 || !activeWorkspaceId) {
216 return;
217 }
218
219 const activeWorkspace = workspaces.find((workspace) => workspace.runtimeWorkspaceId === activeWorkspaceId);
220 if (!activeWorkspace) {
221 return;
222 }
223
224 const workspaceOrganizationId = activeWorkspace.organizationId ? String(activeWorkspace.organizationId) : null;
225 if (workspaceOrganizationId === selectedOrganizationId) {
226 return;
227 }
228
229 setSelectedOrganizationId(workspaceOrganizationId);
230 if (workspaceOrganizationId) {
231 localStorage.setItem(ACTIVE_ORGANIZATION_KEY, workspaceOrganizationId);
232 } else {
233 localStorage.removeItem(ACTIVE_ORGANIZATION_KEY);
234 }
235 }, [workspaces, activeWorkspaceId, selectedOrganizationId]);
236
237 useEffect(() => {
238 if (
239 !workosEnabled
240 || account === undefined
241 || bootstrappingWorkos
242 || workosBootstrapAttempted
243 ) {
244 return;
245 }
246
247 let cancelled = false;
248 void (async () => {
249 try {
250 setWorkosBootstrapAttempted(true);
251 setBootstrappingWorkos(true);
252 await bootstrapCurrentWorkosAccount({});
253 } catch (cause) {
254 if (!cancelled) {
255 setError(cause instanceof Error ? cause.message : "Failed to bootstrap WorkOS account");
256 }
257 } finally {
258 if (!cancelled) {
259 setBootstrappingWorkos(false);
260 }
261 }
262 })();
263
264 return () => {
265 cancelled = true;
266 };
267 }, [account, bootstrapCurrentWorkosAccount, bootstrappingWorkos, workosBootstrapAttempted]);
268
269 useEffect(() => {
270 if (account === undefined) {
271 setWorkosBootstrapAttempted(false);
272 }
273 }, [account]);
274 175
275 const resetWorkspace = useCallback(async () => {176 const resetWorkspace = useCallback(async () => {
276 localStorage.removeItem(SESSION_KEY);177 localStorage.removeItem(SESSION_KEY);
277 localStorage.removeItem(ACTIVE_WORKSPACE_KEY);178 localStorage.removeItem(ACTIVE_WORKSPACE_KEY);
278 localStorage.removeItem(ACTIVE_ORGANIZATION_KEY);
279 setStoredSessionId(null);179 setStoredSessionId(null);
280 setActiveWorkspaceId(null);180 setActiveWorkspaceId(null);
281 setSelectedOrganizationId(null);181 setRuntimeError(null);
282 await bootstrap();182 }, []);
283 }, [bootstrap]);
284 183
285 const switchWorkspace = useCallback((workspaceId: string) => {184 const switchWorkspace = useCallback((workspaceId: string) => {
286 setActiveWorkspaceId(workspaceId);185 setActiveWorkspaceId(workspaceId);
287 localStorage.setItem(ACTIVE_WORKSPACE_KEY, workspaceId);186 localStorage.setItem(ACTIVE_WORKSPACE_KEY, workspaceId);
288 187
289 const selectedWorkspace = workspaces?.find((workspace) => workspace.runtimeWorkspaceId === workspaceId) ?? null;
290 const nextOrganizationId = selectedWorkspace?.organizationId ? String(selectedWorkspace.organizationId) : null;
291 setSelectedOrganizationId(nextOrganizationId);
292 if (nextOrganizationId) {
293 localStorage.setItem(ACTIVE_ORGANIZATION_KEY, nextOrganizationId);
294 } else {
295 localStorage.removeItem(ACTIVE_ORGANIZATION_KEY);
296 }
297
298 if (account?.provider === "workos") {188 if (account?.provider === "workos") {
299 const accountId = String(account._id);189 const accountId = String(account._id);
300 const byAccount = readWorkspaceByAccount();190 const byAccount = readWorkspaceByAccount();
@@ -303,36 +193,11 @@ export function SessionProvider({ children }: { children: ReactNode }) { · 2 unmodified lines
303 [accountId]: workspaceId,193 [accountId]: workspaceId,
304 });194 });
305 }195 }
306 }, [account, workspaces]);196 }, [account]);
307
308 const switchOrganization = useCallback((organizationId: string | null) => {
309 setSelectedOrganizationId(organizationId);
310 if (organizationId) {
311 localStorage.setItem(ACTIVE_ORGANIZATION_KEY, organizationId);
312 } else {
313 localStorage.removeItem(ACTIVE_ORGANIZATION_KEY);
314 }
315
316 if (!workspaces || workspaces.length === 0) {
317 return;
318 }
319
320 const firstWorkspaceForOrg = workspaces.find((workspace) => {
321 const workspaceOrgId = workspace.organizationId ? String(workspace.organizationId) : null;
322 if (organizationId === null) {
323 return workspaceOrgId === null;
324 }
325 return workspaceOrgId === organizationId;
326 });
327
328 if (firstWorkspaceForOrg?.runtimeWorkspaceId) {
329 switchWorkspace(firstWorkspaceForOrg.runtimeWorkspaceId);
330 }
331 }, [switchWorkspace, workspaces]);
332 197
333 const createWorkspace = useCallback(async (name: string, iconFile?: File | null) => {198 const createWorkspace = useCallback(async (name: string, iconFile?: File | null) => {
334 setCreatingWorkspace(true);199 setCreatingWorkspace(true);
335 setError(null);200 setRuntimeError(null);
336 try {201 try {
337 let iconStorageId: Id<"_storage"> | undefined;202 let iconStorageId: Id<"_storage"> | undefined;
338 203
@@ -371,7 +236,7 @@ export function SessionProvider({ children }: { children: ReactNode }) { · 32 unmodified lines
371 }236 }
372 } catch (cause) {237 } catch (cause) {
373 const message = cause instanceof Error ? cause.message : "Failed to create workspace";238 const message = cause instanceof Error ? cause.message : "Failed to create workspace";
374 setError(message);239 setRuntimeError(message);
375 throw cause;240 throw cause;
376 } finally {241 } finally {
377 setCreatingWorkspace(false);242 setCreatingWorkspace(false);
@@ -389,7 +254,7 @@ export function SessionProvider({ children }: { children: ReactNode }) { · 11 unmodified lines
389 }254 }
390 255
391 const activeWorkspace =256 const activeWorkspace =
392 workspaces.find((workspace) => workspace.runtimeWorkspaceId === activeWorkspaceId)257 workspaces.find((workspace) => workspace.runtimeWorkspaceId === resolvedActiveWorkspaceId)
393 ?? workspaces[0]258 ?? workspaces[0]
394 ?? null;259 ?? null;
395 if (!activeWorkspace) {260 if (!activeWorkspace) {
@@ -407,20 +272,35 @@ export function SessionProvider({ children }: { children: ReactNode }) { · 11 unmodified lines
407 createdAt: Date.now(),272 createdAt: Date.now(),
408 lastSeenAt: Date.now(),273 lastSeenAt: Date.now(),
409 };274 };
410 }, [account, activeWorkspaceId, workspaces]);275 }, [account, resolvedActiveWorkspaceId, workspaces]);
411 276
412 const mode: "guest" | "workos" = workosContext ? "workos" : "guest";277 const mode: "guest" | "workos" = workosContext ? "workos" : "guest";
413 const context = workosContext ?? guestContext;278 const context = workosContext ?? guestContext;
279
280 const bootstrapSessionError =
281 bootstrapSessionQuery.error instanceof Error
282 ? bootstrapSessionQuery.error.message
283 : bootstrapSessionQuery.error
284 ? "Failed to bootstrap session"
285 : null;
286 const bootstrapWorkosError =
287 bootstrapWorkosAccountQuery.error instanceof Error
288 ? bootstrapWorkosAccountQuery.error.message
289 : bootstrapWorkosAccountQuery.error
290 ? "Failed to bootstrap WorkOS account"
291 : null;
292 const error = runtimeError ?? bootstrapSessionError ?? bootstrapWorkosError;
293
414 const waitingForWorkosAccount = Boolean(294 const waitingForWorkosAccount = Boolean(
415 workosEnabled295 workosEnabled
416 && account === undefined296 && account === undefined
417 && !guestContext297 && !guestContext
418 && !bootstrappingWorkos,298 && !bootstrapWorkosAccountQuery.isFetching,
419 );299 );
420 const effectiveLoading = !context && !error && (300 const effectiveLoading = !context && !error && (
421 loading301 bootstrapSessionQuery.isLoading
422 || waitingForWorkosAccount302 || waitingForWorkosAccount
423 || bootstrappingWorkos303 || bootstrapWorkosAccountQuery.isFetching
424 );304 );
425 const workspaceOptions = useMemo(() => {305 const workspaceOptions = useMemo(() => {
426 if (mode === "workos" && workspaces) {306 if (mode === "workos" && workspaces) {
@@ -463,8 +343,6 @@ export function SessionProvider({ children }: { children: ReactNode }) { · 36 unmodified lines
463 clientConfig: clientConfig ?? null,343 clientConfig: clientConfig ?? null,
464 mode,344 mode,
465 organizations: organizations ?? [],345 organizations: organizations ?? [],
466 selectedOrganizationId,
467 switchOrganization,
468 workspaces: workspaceOptions,346 workspaces: workspaceOptions,
469 switchWorkspace,347 switchWorkspace,
470 creatingWorkspace,348 creatingWorkspace,
executor/apps/web/tsconfig.json+1−2
@@ -19,8 +19,7 @@ · 18 unmodified lines
19 }19 }
20 ],20 ],
21 "paths": {21 "paths": {
22 "@/*": ["./src/*"],22 "@/*": ["./src/*"]
23 "@executor/server/*": ["../server/*"]
24 }23 }
25 },24 },
26 "include": [25 "include": [
executor/bun.lock+2091−0
@@ -0,0 +1,2091 @@
1{
2 "lockfileVersion": 1,
3 "configVersion": 1,
4 "workspaces": {
5 "": {
6 "name": "executor-monorepo",
7 "dependencies": {
8 "@convex-dev/stripe": "^0.1.3",
9 "@convex-dev/workos-authkit": "^0.1.6",
10 "convex": "^1.31.7",
11 },
12 "devDependencies": {
13 "@types/bun": "latest",
14 "convex-test": "^0.0.41",
15 "typescript": "latest",
16 },
17 },
18 "apps/server": {
19 "name": "@executor/server",
20 "dependencies": {
21 "@apidevtools/swagger-parser": "^12.1.0",
22 "@executor/contracts": "workspace:*",
23 "@modelcontextprotocol/sdk": "^1.26.0",
24 "@vercel/sandbox": "latest",
25 "convex": "^1.31.7",
26 "elysia": "^1.4.22",
27 "openapi-typescript": "^7.10.1",
28 "zod": "^4.3.6",
29 },
30 "devDependencies": {
31 "@elysiajs/eden": "^1.4.6",
32 "@types/bun": "latest",
33 "typescript": "^5.9.3",
34 },
35 },
36 "apps/web": {
37 "name": "@executor/web",
38 "version": "0.1.0",
39 "dependencies": {
40 "@convex-dev/workos": "^0.0.1",
41 "@elysiajs/eden": "^1.4.6",
42 "@executor/contracts": "workspace:*",
43 "@monaco-editor/react": "^4.7.0",
44 "@tanstack/react-query": "^5.80.7",
45 "@workos-inc/authkit-nextjs": "^2.13.0",
46 "class-variance-authority": "^0.7.1",
47 "clsx": "^2.1.1",
48 "convex": "^1.31.7",
49 "lucide-react": "^0.563.0",
50 "monaco-editor": "^0.55.1",
51 "next": "16.1.6",
52 "next-themes": "^0.4.6",
53 "radix-ui": "^1.4.3",
54 "react": "19.2.3",
55 "react-dom": "19.2.3",
56 "sonner": "^2.0.7",
57 "tailwind-merge": "^3.4.0",
58 "tldts": "^7.0.22",
59 },
60 "devDependencies": {
61 "@tailwindcss/postcss": "^4",
62 "@types/node": "^20",
63 "@types/react": "^19",
64 "@types/react-dom": "^19",
65 "eslint": "^9",
66 "eslint-config-next": "16.1.6",
67 "shadcn": "^3.8.4",
68 "tailwindcss": "^4",
69 "tw-animate-css": "^1.4.0",
70 "typescript": "^5",
71 },
72 },
73 "packages/contracts": {
74 "name": "@executor/contracts",
75 "version": "0.0.1",
76 },
77 },
78 "trustedDependencies": [
79 "sharp",
80 "unrs-resolver",
81 ],
82 "packages": {
83 "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
84
85 "@antfu/ni": ["@antfu/ni@25.0.0", "", { "dependencies": { "ansis": "^4.0.0", "fzf": "^0.5.2", "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" }, "bin": { "na": "bin/na.mjs", "ni": "bin/ni.mjs", "nr": "bin/nr.mjs", "nci": "bin/nci.mjs", "nlx": "bin/nlx.mjs", "nun": "bin/nun.mjs", "nup": "bin/nup.mjs" } }, "sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA=="],
86
87 "@apidevtools/json-schema-ref-parser": ["@apidevtools/json-schema-ref-parser@14.0.1", "", { "dependencies": { "@types/json-schema": "^7.0.15", "js-yaml": "^4.1.0" } }, "sha512-Oc96zvmxx1fqoSEdUmfmvvb59/KDOnUoJ7s2t7bISyAn0XEz57LCCw8k2Y4Pf3mwKaZLMciESALORLgfe2frCw=="],
88
89 "@apidevtools/openapi-schemas": ["@apidevtools/openapi-schemas@2.1.0", "", {}, "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ=="],
90
91 "@apidevtools/swagger-methods": ["@apidevtools/swagger-methods@3.0.2", "", {}, "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg=="],
92
93 "@apidevtools/swagger-parser": ["@apidevtools/swagger-parser@12.1.0", "", { "dependencies": { "@apidevtools/json-schema-ref-parser": "14.0.1", "@apidevtools/openapi-schemas": "^2.1.0", "@apidevtools/swagger-methods": "^3.0.2", "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "call-me-maybe": "^1.0.2" }, "peerDependencies": { "openapi-types": ">=7" } }, "sha512-e5mJoswsnAX0jG+J09xHFYQXb/bUc5S3pLpMxUuRUA2H8T2kni3yEoyz2R3Dltw5f4A6j6rPNMpWTK+iVDFlng=="],
94
95 "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
96
97 "@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="],
98
99 "@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="],
100
101 "@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="],
102
103 "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
104
105 "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="],
106
107 "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow=="],
108
109 "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="],
110
111 "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
112
113 "@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="],
114
115 "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="],
116
117 "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
118
119 "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.28.6", "", {}, "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug=="],
120
121 "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.28.6", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg=="],
122
123 "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
124
125 "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
126
127 "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="],
128
129 "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="],
130
131 "@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="],
132
133 "@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="],
134
135 "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w=="],
136
137 "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A=="],
138
139 "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.28.6", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA=="],
140
141 "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw=="],
142
143 "@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
144
145 "@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="],
146
147 "@babel/traverse": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="],
148
149 "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
150
151 "@borewit/text-codec": ["@borewit/text-codec@0.2.1", "", {}, "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw=="],
152
153 "@convex-dev/stripe": ["@convex-dev/stripe@0.1.3", "", { "dependencies": { "stripe": "^20.0.0" }, "peerDependencies": { "convex": "^1.29.3", "react": "^18.3.1 || ^19.0.0" } }, "sha512-yL0ygrWrjto9f7rprCb4KYp+p3Oka7KG5e3HBoJ9qSzbncpavZI+JTkGZnLCYZjPOo2ByCrBJvtGAxfP169Nzw=="],
154
155 "@convex-dev/workos": ["@convex-dev/workos@0.0.1", "", { "dependencies": { "@workos-inc/authkit-react": "^0.11.0", "tsdown": "^0.12.7", "vitest": "^3.1.4" }, "peerDependencies": { "convex": "^1.25.4", "react": "^18.0.0 || ^19.0.0-0 || ^19.0.0" } }, "sha512-8gZOgmcTitcKXwagdU69XC4Va6wMPFIhSqSOEaXmFXMEPtkMgxPW1dhJzrmm9UQ4iRgZsckjd2O5aQjUH7kHGQ=="],
156
157 "@convex-dev/workos-authkit": ["@convex-dev/workos-authkit@0.1.6", "", { "dependencies": { "@convex-dev/workos": "^0.0.1", "@convex-dev/workpool": "^0.2.19", "@workos-inc/authkit-react": "^0.13.0", "@workos-inc/node": "^7.75.1", "convex-helpers": "^0.1.104", "type-fest": "^5.1.0" }, "peerDependencies": { "convex": "^1.29.3", "react": "^18.3.1 || ^19.0.0" } }, "sha512-o7FVJlMQcWTmYTflAnB5D0N+uWK9pEqQZ456xrP2kZN2KUpN236kf+oqFk0kIWzRvFMh/78V57N2LQjEH784eA=="],
158
159 "@convex-dev/workpool": ["@convex-dev/workpool@0.2.19", "", { "peerDependencies": { "convex": ">=1.25.0 <1.35.0", "convex-helpers": "^0.1.94" } }, "sha512-U2KwYnsKILyxW1baWEhDv+ZtnL5FZbYFxBT5owQ0Lw/kseiudMZraA4clH+/6gowHSahWpkq4wndhcOfpfhuOA=="],
160
161 "@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.52.0", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^17.2.1", "eciesjs": "^0.4.10", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.2", "which": "^4.0.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-CaQcc8JvtzQhUSm9877b6V4Tb7HCotkcyud9X2YwdqtQKwgljkMRwU96fVYKnzN3V0Hj74oP7Es+vZ0mS+Aa1w=="],
162
163 "@ecies/ciphers": ["@ecies/ciphers@0.2.5", "", { "peerDependencies": { "@noble/ciphers": "^1.0.0" } }, "sha512-GalEZH4JgOMHYYcYmVqnFirFsjZHeoGMDt9IxEnM9F7GRUUyUksJ7Ou53L83WHJq3RWKD3AcBpo0iQh0oMpf8A=="],
164
165 "@elysiajs/eden": ["@elysiajs/eden@1.4.6", "", { "peerDependencies": { "elysia": ">=1.4.19" } }, "sha512-Tsa4NwXEWg/u73vWiYZQ3L5/ecgZSxqiEjYwpS+4qBKXeTZqZKl2hcgHJSVBL+InEDMi35Xugct7qyAXE5oM4Q=="],
166
167 "@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="],
168
169 "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
170
171 "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
172
173 "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A=="],
174
175 "@esbuild/android-arm": ["@esbuild/android-arm@0.27.0", "", { "os": "android", "cpu": "arm" }, "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ=="],
176
177 "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.0", "", { "os": "android", "cpu": "arm64" }, "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ=="],
178
179 "@esbuild/android-x64": ["@esbuild/android-x64@0.27.0", "", { "os": "android", "cpu": "x64" }, "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q=="],
180
181 "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg=="],
182
183 "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g=="],
184
185 "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw=="],
186
187 "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g=="],
188
189 "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ=="],
190
191 "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ=="],
192
193 "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.0", "", { "os": "linux", "cpu": "ia32" }, "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw=="],
194
195 "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg=="],
196
197 "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg=="],
198
199 "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA=="],
200
201 "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ=="],
202
203 "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w=="],
204
205 "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.0", "", { "os": "linux", "cpu": "x64" }, "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw=="],
206
207 "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.0", "", { "os": "none", "cpu": "arm64" }, "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w=="],
208
209 "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.0", "", { "os": "none", "cpu": "x64" }, "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA=="],
210
211 "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ=="],
212
213 "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A=="],
214
215 "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.0", "", { "os": "none", "cpu": "arm64" }, "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA=="],
216
217 "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA=="],
218
219 "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg=="],
220
221 "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ=="],
222
223 "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.0", "", { "os": "win32", "cpu": "x64" }, "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg=="],
224
225 "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="],
226
227 "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
228
229 "@eslint/config-array": ["@eslint/config-array@0.21.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA=="],
230
231 "@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="],
232
233 "@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
234
235 "@eslint/eslintrc": ["@eslint/eslintrc@3.3.3", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ=="],
236
237 "@eslint/js": ["@eslint/js@9.39.2", "", {}, "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA=="],
238
239 "@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="],
240
241 "@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
242
243 "@executor/contracts": ["@executor/contracts@workspace:packages/contracts"],
244
245 "@executor/server": ["@executor/server@workspace:apps/server"],
246
247 "@executor/web": ["@executor/web@workspace:apps/web"],
248
249 "@floating-ui/core": ["@floating-ui/core@1.7.4", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg=="],
250
251 "@floating-ui/dom": ["@floating-ui/dom@1.7.5", "", { "dependencies": { "@floating-ui/core": "^1.7.4", "@floating-ui/utils": "^0.2.10" } }, "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg=="],
252
253 "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.7", "", { "dependencies": { "@floating-ui/dom": "^1.7.5" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg=="],
254
255 "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
256
257 "@hono/node-server": ["@hono/node-server@1.19.9", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw=="],
258
259 "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
260
261 "@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
262
263 "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
264
265 "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
266
267 "@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
268
269 "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
270
271 "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
272
273 "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
274
275 "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
276
277 "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
278
279 "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
280
281 "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
282
283 "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
284
285 "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
286
287 "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
288
289 "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
290
291 "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
292
293 "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
294
295 "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
296
297 "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
298
299 "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
300
301 "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
302
303 "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
304
305 "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
306
307 "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
308
309 "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
310
311 "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
312
313 "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
314
315 "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
316
317 "@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="],
318
319 "@inquirer/confirm": ["@inquirer/confirm@5.1.21", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ=="],
320
321 "@inquirer/core": ["@inquirer/core@10.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", "wrap-ansi": "^6.2.0", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A=="],
322
323 "@inquirer/figures": ["@inquirer/figures@1.0.15", "", {}, "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g=="],
324
325 "@inquirer/type": ["@inquirer/type@3.0.10", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA=="],
326
327 "@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="],
328
329 "@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.1", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ=="],
330
331 "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
332
333 "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
334
335 "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
336
337 "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
338
339 "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
340
341 "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.26.0", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg=="],
342
343 "@monaco-editor/loader": ["@monaco-editor/loader@1.7.0", "", { "dependencies": { "state-local": "^1.0.6" } }, "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA=="],
344
345 "@monaco-editor/react": ["@monaco-editor/react@4.7.0", "", { "dependencies": { "@monaco-editor/loader": "^1.5.0" }, "peerDependencies": { "monaco-editor": ">= 0.25.0 < 1", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA=="],
346
347 "@mswjs/interceptors": ["@mswjs/interceptors@0.41.2", "", { "dependencies": { "@open-draft/deferred-promise": "^2.2.0", "@open-draft/logger": "^0.3.0", "@open-draft/until": "^2.0.0", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "strict-event-emitter": "^0.5.1" } }, "sha512-7G0Uf0yK3f2bjElBLGHIQzgRgMESczOMyYVasq1XK8P5HaXtlW4eQhz9MBL+TQILZLaruq+ClGId+hH0w4jvWw=="],
348
349 "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
350
351 "@next/env": ["@next/env@16.1.6", "", {}, "sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ=="],
352
353 "@next/eslint-plugin-next": ["@next/eslint-plugin-next@16.1.6", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ=="],
354
355 "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.1.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw=="],
356
357 "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.1.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ=="],
358
359 "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw=="],
360
361 "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ=="],
362
363 "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ=="],
364
365 "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg=="],
366
367 "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.1.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw=="],
368
369 "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.1.6", "", { "os": "win32", "cpu": "x64" }, "sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A=="],
370
371 "@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="],
372
373 "@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="],
374
375 "@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
376
377 "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
378
379 "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
380
381 "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
382
383 "@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="],
384
385 "@open-draft/deferred-promise": ["@open-draft/deferred-promise@2.2.0", "", {}, "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA=="],
386
387 "@open-draft/logger": ["@open-draft/logger@0.3.0", "", { "dependencies": { "is-node-process": "^1.2.0", "outvariant": "^1.4.0" } }, "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ=="],
388
389 "@open-draft/until": ["@open-draft/until@2.1.0", "", {}, "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg=="],
390
391 "@oxc-project/types": ["@oxc-project/types@0.112.0", "", {}, "sha512-m6RebKHIRsax2iCwVpYW2ErQwa4ywHJrE4sCK3/8JK8ZZAWOKXaRJFl/uP51gaVyyXlaS4+chU1nSCdzYf6QqQ=="],
392
393 "@peculiar/asn1-schema": ["@peculiar/asn1-schema@2.6.0", "", { "dependencies": { "asn1js": "^3.0.6", "pvtsutils": "^1.3.6", "tslib": "^2.8.1" } }, "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg=="],
394
395 "@peculiar/json-schema": ["@peculiar/json-schema@1.1.12", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w=="],
396
397 "@peculiar/webcrypto": ["@peculiar/webcrypto@1.5.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.3.8", "@peculiar/json-schema": "^1.1.12", "pvtsutils": "^1.3.5", "tslib": "^2.6.2", "webcrypto-core": "^1.8.0" } }, "sha512-BRs5XUAwiyCDQMsVA9IDvDa7UBR9gAvPHgugOeGng3YN6vJ9JYonyDc0lNczErgtCWtucjR5N7VtaonboD/ezg=="],
398
399 "@quansync/fs": ["@quansync/fs@1.0.0", "", { "dependencies": { "quansync": "^1.0.0" } }, "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ=="],
400
401 "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="],
402
403 "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
404
405 "@radix-ui/react-accessible-icon": ["@radix-ui/react-accessible-icon@1.1.7", "", { "dependencies": { "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A=="],
406
407 "@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA=="],
408
409 "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw=="],
410
411 "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="],
412
413 "@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g=="],
414
415 "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.10", "", { "dependencies": { "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog=="],
416
417 "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw=="],
418
419 "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA=="],
420
421 "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="],
422
423 "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="],
424
425 "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
426
427 "@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.2.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww=="],
428
429 "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="],
430
431 "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="],
432
433 "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="],
434
435 "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw=="],
436
437 "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="],
438
439 "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
440
441 "@radix-ui/react-form": ["@radix-ui/react-form@0.1.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-label": "2.1.7", "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ=="],
442
443 "@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg=="],
444
445 "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="],
446
447 "@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="],
448
449 "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg=="],
450
451 "@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA=="],
452
453 "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w=="],
454
455 "@radix-ui/react-one-time-password-field": ["@radix-ui/react-one-time-password-field@0.1.8", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg=="],
456
457 "@radix-ui/react-password-toggle-field": ["@radix-ui/react-password-toggle-field@0.1.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-is-hydrated": "0.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw=="],
458
459 "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="],
460
461 "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="],
462
463 "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="],
464
465 "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="],
466
467 "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
468
469 "@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.7", "", { "dependencies": { "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg=="],
470
471 "@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.3.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ=="],
472
473 "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="],
474
475 "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.10", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A=="],
476
477 "@radix-ui/react-select": ["@radix-ui/react-select@2.2.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ=="],
478
479 "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA=="],
480
481 "@radix-ui/react-slider": ["@radix-ui/react-slider@1.3.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw=="],
482
483 "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
484
485 "@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="],
486
487 "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="],
488
489 "@radix-ui/react-toast": ["@radix-ui/react-toast@1.2.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g=="],
490
491 "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ=="],
492
493 "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q=="],
494
495 "@radix-ui/react-toolbar": ["@radix-ui/react-toolbar@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-separator": "1.1.7", "@radix-ui/react-toggle-group": "1.1.11" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg=="],
496
497 "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="],
498
499 "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="],
500
501 "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="],
502
503 "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="],
504
505 "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="],
506
507 "@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.0", "", { "dependencies": { "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA=="],
508
509 "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="],
510
511 "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="],
512
513 "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="],
514
515 "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="],
516
517 "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="],
518
519 "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="],
520
521 "@redocly/ajv": ["@redocly/ajv@8.17.2", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-rcbDZOfXAgGEJeJ30aWCVVJvxV9ooevb/m1/SFblO2qHs4cqTk178gx7T/vdslf57EA4lTofrwsq5K8rxK9g+g=="],
522
523 "@redocly/config": ["@redocly/config@0.22.2", "", {}, "sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ=="],
524
525 "@redocly/openapi-core": ["@redocly/openapi-core@1.34.6", "", { "dependencies": { "@redocly/ajv": "^8.11.2", "@redocly/config": "^0.22.0", "colorette": "^1.2.0", "https-proxy-agent": "^7.0.5", "js-levenshtein": "^1.1.6", "js-yaml": "^4.1.0", "minimatch": "^5.0.1", "pluralize": "^8.0.0", "yaml-ast-parser": "0.0.43" } }, "sha512-2+O+riuIUgVSuLl3Lyh5AplWZyVMNuG2F98/o6NrutKJfW4/GTZdPpZlIphS0HGgcOHgmWcCSHj+dWFlZaGSHw=="],
526
527 "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.3", "", { "os": "android", "cpu": "arm64" }, "sha512-0T1k9FinuBZ/t7rZ8jN6OpUKPnUjNdYHoj/cESWrQ3ZraAJ4OMm6z7QjSfCxqj8mOp9kTKc1zHK3kGz5vMu+nQ=="],
528
529 "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JWWLzvcmc/3pe7qdJqPpuPk91SoE/N+f3PcWx/6ZwuyDVyungAEJPvKm/eEldiDdwTmaEzWfIR+HORxYWrCi1A=="],
530
531 "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-MTakBxfx3tde5WSmbHxuqlDsIW0EzQym+PJYGF4P6lG2NmKzi128OGynoFUqoD5ryCySEY85dug4v+LWGBElIw=="],
532
533 "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jje3oopyOLs7IwfvXoS6Lxnmie5JJO7vW29fdGFu5YGY1EDbVDhD+P9vDihqS5X6fFiqL3ZQZCMBg6jyHkSVww=="],
534
535 "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3", "", { "os": "linux", "cpu": "arm" }, "sha512-A0n8P3hdLAaqzSFrQoA42p23ZKBYQOw+8EH5r15Sa9X1kD9/JXe0YT2gph2QTWvdr0CVK2BOXiK6ENfy6DXOag=="],
536
537 "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-kWXkoxxarYISBJ4bLNf5vFkEbb4JvccOwxWDxuK9yee8lg5XA7OpvlTptfRuwEvYcOZf+7VS69Uenpmpyo5Bjw=="],
538
539 "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-Z03/wrqau9Bicfgb3Dbs6SYTHliELk2PM2LpG2nFd+cGupTMF5kanLEcj2vuuJLLhptNyS61rtk7SOZ+lPsTUA=="],
540
541 "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.3", "", { "os": "linux", "cpu": "x64" }, "sha512-iSXXZsQp08CSilff/DCTFZHSVEpEwdicV3W8idHyrByrcsRDVh9sGC3sev6d8BygSGj3vt8GvUKBPCoyMA4tgQ=="],
542
543 "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.3", "", { "os": "linux", "cpu": "x64" }, "sha512-qaj+MFudtdCv9xZo9znFvkgoajLdc+vwf0Kz5N44g+LU5XMe+IsACgn3UG7uTRlCCvhMAGXm1XlpEA5bZBrOcw=="],
544
545 "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.3", "", { "os": "none", "cpu": "arm64" }, "sha512-U662UnMETyjT65gFmG9ma+XziENrs7BBnENi/27swZPYagubfHRirXHG2oMl+pEax2WvO7Kb9gHZmMakpYqBHQ=="],
546
547 "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.3", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-gekrQ3Q2HiC1T5njGyuUJoGpK/l6B/TNXKed3fZXNf9YRTJn3L5MOZsFBn4bN2+UX+8+7hgdlTcEsexX988G4g=="],
548
549 "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-85y5JifyMgs8m5K2XzR/VDsapKbiFiohl7s5lEj7nmNGO0pkTXE7q6TQScei96BNAsoK7JC3pA7ukA8WRHVJpg=="],
550
551 "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.3", "", { "os": "win32", "cpu": "x64" }, "sha512-a4VUQZH7LxGbUJ3qJ/TzQG8HxdHvf+jOnqf7B7oFx1TEBm+j2KNL2zr5SQ7wHkNAcaPevF6gf9tQnVBnC4mD+A=="],
552
553 "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="],
554
555 "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.57.1", "", { "os": "android", "cpu": "arm" }, "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg=="],
556
557 "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.57.1", "", { "os": "android", "cpu": "arm64" }, "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w=="],
558
559 "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.57.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg=="],
560
561 "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.57.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w=="],
562
563 "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.57.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug=="],
564
565 "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.57.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q=="],
566
567 "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.57.1", "", { "os": "linux", "cpu": "arm" }, "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw=="],
568
569 "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.57.1", "", { "os": "linux", "cpu": "arm" }, "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw=="],
570
571 "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.57.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g=="],
572
573 "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.57.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q=="],
574
575 "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA=="],
576
577 "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw=="],
578
579 "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.57.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w=="],
580
581 "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.57.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw=="],
582
583 "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A=="],
584
585 "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw=="],
586
587 "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.57.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg=="],
588
589 "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.57.1", "", { "os": "linux", "cpu": "x64" }, "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg=="],
590
591 "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.57.1", "", { "os": "linux", "cpu": "x64" }, "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw=="],
592
593 "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.57.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw=="],
594
595 "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.57.1", "", { "os": "none", "cpu": "arm64" }, "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ=="],
596
597 "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.57.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ=="],
598
599 "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.57.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew=="],
600
601 "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.57.1", "", { "os": "win32", "cpu": "x64" }, "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ=="],
602
603 "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.57.1", "", { "os": "win32", "cpu": "x64" }, "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA=="],
604
605 "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
606
607 "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="],
608
609 "@sinclair/typebox": ["@sinclair/typebox@0.34.48", "", {}, "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA=="],
610
611 "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="],
612
613 "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
614
615 "@tailwindcss/node": ["@tailwindcss/node@4.1.18", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.18" } }, "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ=="],
616
617 "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.18", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.18", "@tailwindcss/oxide-darwin-arm64": "4.1.18", "@tailwindcss/oxide-darwin-x64": "4.1.18", "@tailwindcss/oxide-freebsd-x64": "4.1.18", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", "@tailwindcss/oxide-linux-x64-musl": "4.1.18", "@tailwindcss/oxide-wasm32-wasi": "4.1.18", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" } }, "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A=="],
618
619 "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.18", "", { "os": "android", "cpu": "arm64" }, "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q=="],
620
621 "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.18", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A=="],
622
623 "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.18", "", { "os": "darwin", "cpu": "x64" }, "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw=="],
624
625 "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.18", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA=="],
626
627 "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18", "", { "os": "linux", "cpu": "arm" }, "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA=="],
628
629 "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw=="],
630
631 "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg=="],
632
633 "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g=="],
634
635 "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ=="],
636
637 "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.18", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.0", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA=="],
638
639 "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.18", "", { "os": "win32", "cpu": "arm64" }, "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA=="],
640
641 "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.18", "", { "os": "win32", "cpu": "x64" }, "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q=="],
642
643 "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.18", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.18", "@tailwindcss/oxide": "4.1.18", "postcss": "^8.4.41", "tailwindcss": "4.1.18" } }, "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g=="],
644
645 "@tanstack/query-core": ["@tanstack/query-core@5.90.20", "", {}, "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg=="],
646
647 "@tanstack/react-query": ["@tanstack/react-query@5.90.20", "", { "dependencies": { "@tanstack/query-core": "5.90.20" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-vXBxa+qeyveVO7OA0jX1z+DeyCA4JKnThKv411jd5SORpBKgkcVnYKCiBgECvADvniBX7tobwBmg01qq9JmMJw=="],
648
649 "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="],
650
651 "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
652
653 "@ts-morph/common": ["@ts-morph/common@0.27.0", "", { "dependencies": { "fast-glob": "^3.3.3", "minimatch": "^10.0.1", "path-browserify": "^1.0.1" } }, "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ=="],
654
655 "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
656
657 "@types/accepts": ["@types/accepts@1.3.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ=="],
658
659 "@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="],
660
661 "@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],
662
663 "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="],
664
665 "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],
666
667 "@types/content-disposition": ["@types/content-disposition@0.5.9", "", {}, "sha512-8uYXI3Gw35MhiVYhG3s295oihrxRyytcRHjSjqnqZVDDy/xcGBRny7+Xj1Wgfhv5QzRtN2hB2dVRBUX9XW3UcQ=="],
668
669 "@types/cookie": ["@types/cookie@0.5.4", "", {}, "sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA=="],
670
671 "@types/cookies": ["@types/cookies@0.9.2", "", { "dependencies": { "@types/connect": "*", "@types/express": "*", "@types/keygrip": "*", "@types/node": "*" } }, "sha512-1AvkDdZM2dbyFybL4fxpuNCaWyv//0AwsuUk2DWeXyM1/5ZKm6W3z6mQi24RZ4l2ucY+bkSHzbDVpySqPGuV8A=="],
672
673 "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="],
674
675 "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
676
677 "@types/express": ["@types/express@4.17.25", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "^1" } }, "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw=="],
678
679 "@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.8", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA=="],
680
681 "@types/http-assert": ["@types/http-assert@1.5.6", "", {}, "sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw=="],
682
683 "@types/http-errors": ["@types/http-errors@2.0.5", "", {}, "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg=="],
684
685 "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
686
687 "@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
688
689 "@types/keygrip": ["@types/keygrip@1.0.6", "", {}, "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ=="],
690
691 "@types/koa": ["@types/koa@2.15.0", "", { "dependencies": { "@types/accepts": "*", "@types/content-disposition": "*", "@types/cookies": "*", "@types/http-assert": "*", "@types/http-errors": "*", "@types/keygrip": "*", "@types/koa-compose": "*", "@types/node": "*" } }, "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g=="],
692
693 "@types/koa-compose": ["@types/koa-compose@3.2.9", "", { "dependencies": { "@types/koa": "*" } }, "sha512-BroAZ9FTvPiCy0Pi8tjD1OfJ7bgU1gQf0eR6e1Vm+JJATy9eKOG3hQMFtMciMawiSOVnLMdmUOC46s7HBhSTsA=="],
694
695 "@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="],
696
697 "@types/node": ["@types/node@20.19.33", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw=="],
698
699 "@types/qs": ["@types/qs@6.14.0", "", {}, "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ=="],
700
701 "@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="],
702
703 "@types/react": ["@types/react@19.2.13", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-KkiJeU6VbYbUOp5ITMIc7kBfqlYkKA5KhEHVrGMmUUMt7NeaZg65ojdPk+FtNrBAOXNVM5QM72jnADjM+XVRAQ=="],
704
705 "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
706
707 "@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="],
708
709 "@types/serve-static": ["@types/serve-static@1.15.10", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "<1" } }, "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw=="],
710
711 "@types/statuses": ["@types/statuses@2.0.6", "", {}, "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA=="],
712
713 "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
714
715 "@types/validate-npm-package-name": ["@types/validate-npm-package-name@4.0.2", "", {}, "sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw=="],
716
717 "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.54.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/type-utils": "8.54.0", "@typescript-eslint/utils": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.54.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ=="],
718
719 "@typescript-eslint/parser": ["@typescript-eslint/parser@8.54.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA=="],
720
721 "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.54.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.54.0", "@typescript-eslint/types": "^8.54.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g=="],
722
723 "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.54.0", "", { "dependencies": { "@typescript-eslint/types": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0" } }, "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg=="],
724
725 "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.54.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw=="],
726
727 "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.54.0", "", { "dependencies": { "@typescript-eslint/types": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0", "@typescript-eslint/utils": "8.54.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA=="],
728
729 "@typescript-eslint/types": ["@typescript-eslint/types@8.54.0", "", {}, "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA=="],
730
731 "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.54.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.54.0", "@typescript-eslint/tsconfig-utils": "8.54.0", "@typescript-eslint/types": "8.54.0", "@typescript-eslint/visitor-keys": "8.54.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA=="],
732
733 "@typescript-eslint/utils": ["@typescript-eslint/utils@8.54.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA=="],
734
735 "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.54.0", "", { "dependencies": { "@typescript-eslint/types": "8.54.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA=="],
736
737 "@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="],
738
739 "@unrs/resolver-binding-android-arm64": ["@unrs/resolver-binding-android-arm64@1.11.1", "", { "os": "android", "cpu": "arm64" }, "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g=="],
740
741 "@unrs/resolver-binding-darwin-arm64": ["@unrs/resolver-binding-darwin-arm64@1.11.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g=="],
742
743 "@unrs/resolver-binding-darwin-x64": ["@unrs/resolver-binding-darwin-x64@1.11.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ=="],
744
745 "@unrs/resolver-binding-freebsd-x64": ["@unrs/resolver-binding-freebsd-x64@1.11.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw=="],
746
747 "@unrs/resolver-binding-linux-arm-gnueabihf": ["@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1", "", { "os": "linux", "cpu": "arm" }, "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw=="],
748
749 "@unrs/resolver-binding-linux-arm-musleabihf": ["@unrs/resolver-binding-linux-arm-musleabihf@1.11.1", "", { "os": "linux", "cpu": "arm" }, "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw=="],
750
751 "@unrs/resolver-binding-linux-arm64-gnu": ["@unrs/resolver-binding-linux-arm64-gnu@1.11.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ=="],
752
753 "@unrs/resolver-binding-linux-arm64-musl": ["@unrs/resolver-binding-linux-arm64-musl@1.11.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w=="],
754
755 "@unrs/resolver-binding-linux-ppc64-gnu": ["@unrs/resolver-binding-linux-ppc64-gnu@1.11.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA=="],
756
757 "@unrs/resolver-binding-linux-riscv64-gnu": ["@unrs/resolver-binding-linux-riscv64-gnu@1.11.1", "", { "os": "linux", "cpu": "none" }, "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ=="],
758
759 "@unrs/resolver-binding-linux-riscv64-musl": ["@unrs/resolver-binding-linux-riscv64-musl@1.11.1", "", { "os": "linux", "cpu": "none" }, "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew=="],
760
761 "@unrs/resolver-binding-linux-s390x-gnu": ["@unrs/resolver-binding-linux-s390x-gnu@1.11.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg=="],
762
763 "@unrs/resolver-binding-linux-x64-gnu": ["@unrs/resolver-binding-linux-x64-gnu@1.11.1", "", { "os": "linux", "cpu": "x64" }, "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w=="],
764
765 "@unrs/resolver-binding-linux-x64-musl": ["@unrs/resolver-binding-linux-x64-musl@1.11.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA=="],
766
767 "@unrs/resolver-binding-wasm32-wasi": ["@unrs/resolver-binding-wasm32-wasi@1.11.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^0.2.11" }, "cpu": "none" }, "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ=="],
768
769 "@unrs/resolver-binding-win32-arm64-msvc": ["@unrs/resolver-binding-win32-arm64-msvc@1.11.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw=="],
770
771 "@unrs/resolver-binding-win32-ia32-msvc": ["@unrs/resolver-binding-win32-ia32-msvc@1.11.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ=="],
772
773 "@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.11.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g=="],
774
775 "@vercel/oidc": ["@vercel/oidc@3.1.0", "", {}, "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w=="],
776
777 "@vercel/sandbox": ["@vercel/sandbox@1.4.1", "", { "dependencies": { "@vercel/oidc": "^3.1.0", "async-retry": "1.3.3", "jsonlines": "0.1.1", "ms": "2.1.3", "picocolors": "^1.1.1", "tar-stream": "3.1.7", "undici": "^7.16.0", "xdg-app-paths": "5.1.0", "zod": "3.24.4" } }, "sha512-5jaNLv6QJ0112ZFhCv9hQDCV3IYogpbEn5LzMcY5E8TZsf5tF0avat2tBe7McOJvgVs0SDkuzjvGjUMKtTkjrA=="],
778
779 "@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="],
780
781 "@vitest/mocker": ["@vitest/mocker@3.2.4", "", { "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ=="],
782
783 "@vitest/pretty-format": ["@vitest/pretty-format@3.2.4", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA=="],
784
785 "@vitest/runner": ["@vitest/runner@3.2.4", "", { "dependencies": { "@vitest/utils": "3.2.4", "pathe": "^2.0.3", "strip-literal": "^3.0.0" } }, "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ=="],
786
787 "@vitest/snapshot": ["@vitest/snapshot@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ=="],
788
789 "@vitest/spy": ["@vitest/spy@3.2.4", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw=="],
790
791 "@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="],
792
793 "@workos-inc/authkit-js": ["@workos-inc/authkit-js@0.14.0", "", {}, "sha512-Wt6rKoZdZnuAgiEBlvMDKhleU9DAwpyyy1SibacrnOWQgF4rcNlC+NTnHiiXu6OiOjQo6pPxhW42kCL+Gi+fjw=="],
794
795 "@workos-inc/authkit-nextjs": ["@workos-inc/authkit-nextjs@2.13.0", "", { "dependencies": { "@workos-inc/node": "^7.72.0", "iron-session": "^8.0.1", "jose": "^5.2.3", "path-to-regexp": "^6.2.2" }, "peerDependencies": { "next": "^13.5.9 || ^14.2.26 || ^15.2.3 || ^16", "react": "^18.0 || ^19.0.0", "react-dom": "^18.0 || ^19.0.0" } }, "sha512-ppxzhfakPumHPPggYSROaAlgxfS7viFMPmWPG76Tp6Rh9G7YqkBSp7xtvMtM6gXOFFMvvEJRcKEta6YHeercTQ=="],
796
797 "@workos-inc/authkit-react": ["@workos-inc/authkit-react@0.13.0", "", { "dependencies": { "@workos-inc/authkit-js": "0.14.0" }, "peerDependencies": { "react": ">=17" } }, "sha512-JhcPI9+I0MGOu7B33Gych76Xi7jKfKKfoZ4Mb6JPY9raeEqJQcnN4jMite2ynmMdmiZljIq7wkyf2WAsEU3SzQ=="],
798
799 "@workos-inc/node": ["@workos-inc/node@7.82.0", "", { "dependencies": { "iron-session": "~6.3.1", "jose": "~5.6.3", "leb": "^1.0.0", "qs": "6.14.1" } }, "sha512-8h6XjIJf8nqNGYQMkWsjZ72WXMtzqrb4Azz39schXWoSRmwoK6tK+GpeAviJ9slddiJdOcp0Ht9/r+L6pGQMCg=="],
800
801 "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
802
803 "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
804
805 "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
806
807 "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
808
809 "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
810
811 "ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="],
812
813 "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="],
814
815 "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="],
816
817 "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
818
819 "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
820
821 "ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="],
822
823 "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
824
825 "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
826
827 "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
828
829 "array-buffer-byte-length": ["array-buffer-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" } }, "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw=="],
830
831 "array-includes": ["array-includes@3.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.24.0", "es-object-atoms": "^1.1.1", "get-intrinsic": "^1.3.0", "is-string": "^1.1.1", "math-intrinsics": "^1.1.0" } }, "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ=="],
832
833 "array.prototype.findlast": ["array.prototype.findlast@1.2.5", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ=="],
834
835 "array.prototype.findlastindex": ["array.prototype.findlastindex@1.2.6", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-shim-unscopables": "^1.1.0" } }, "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ=="],
836
837 "array.prototype.flat": ["array.prototype.flat@1.3.3", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-shim-unscopables": "^1.0.2" } }, "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg=="],
838
839 "array.prototype.flatmap": ["array.prototype.flatmap@1.3.3", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-shim-unscopables": "^1.0.2" } }, "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg=="],
840
841 "array.prototype.tosorted": ["array.prototype.tosorted@1.1.4", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA=="],
842
843 "arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="],
844
845 "asn1js": ["asn1js@3.0.7", "", { "dependencies": { "pvtsutils": "^1.3.6", "pvutils": "^1.1.3", "tslib": "^2.8.1" } }, "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ=="],
846
847 "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="],
848
849 "ast-kit": ["ast-kit@2.2.0", "", { "dependencies": { "@babel/parser": "^7.28.5", "pathe": "^2.0.3" } }, "sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw=="],
850
851 "ast-types": ["ast-types@0.16.1", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg=="],
852
853 "ast-types-flow": ["ast-types-flow@0.0.8", "", {}, "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ=="],
854
855 "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="],
856
857 "async-retry": ["async-retry@1.3.3", "", { "dependencies": { "retry": "0.13.1" } }, "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw=="],
858
859 "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
860
861 "axe-core": ["axe-core@4.11.1", "", {}, "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A=="],
862
863 "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
864
865 "b4a": ["b4a@1.7.3", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q=="],
866
867 "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
868
869 "bare-events": ["bare-events@2.8.2", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ=="],
870
871 "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
872
873 "baseline-browser-mapping": ["baseline-browser-mapping@2.9.19", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg=="],
874
875 "birpc": ["birpc@2.9.0", "", {}, "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw=="],
876
877 "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="],
878
879 "brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
880
881 "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
882
883 "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
884
885 "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
886
887 "bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],
888
889 "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="],
890
891 "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
892
893 "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
894
895 "call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
896
897 "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
898
899 "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
900
901 "call-me-maybe": ["call-me-maybe@1.0.2", "", {}, "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="],
902
903 "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
904
905 "caniuse-lite": ["caniuse-lite@1.0.30001769", "", {}, "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg=="],
906
907 "chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="],
908
909 "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
910
911 "change-case": ["change-case@5.4.4", "", {}, "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w=="],
912
913 "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="],
914
915 "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
916
917 "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
918
919 "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="],
920
921 "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="],
922
923 "cli-width": ["cli-width@4.1.0", "", {}, "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ=="],
924
925 "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
926
927 "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
928
929 "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
930
931 "code-block-writer": ["code-block-writer@13.0.3", "", {}, "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg=="],
932
933 "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
934
935 "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
936
937 "colorette": ["colorette@1.4.0", "", {}, "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g=="],
938
939 "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="],
940
941 "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
942
943 "content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="],
944
945 "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
946
947 "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
948
949 "convex": ["convex@1.31.7", "", { "dependencies": { "esbuild": "0.27.0", "prettier": "^3.0.0" }, "peerDependencies": { "@auth0/auth0-react": "^2.0.1", "@clerk/clerk-react": "^4.12.8 || ^5.0.0", "react": "^18.0.0 || ^19.0.0-0 || ^19.0.0" }, "optionalPeers": ["@auth0/auth0-react", "@clerk/clerk-react", "react"], "bin": { "convex": "bin/main.js" } }, "sha512-PtNMe1mAIOvA8Yz100QTOaIdgt2rIuWqencVXrb4McdhxBHZ8IJ1eXTnrgCC9HydyilGT1pOn+KNqT14mqn9fQ=="],
950
951 "convex-helpers": ["convex-helpers@0.1.111", "", { "peerDependencies": { "@standard-schema/spec": "^1.0.0", "convex": "^1.25.4", "hono": "^4.0.5", "react": "^17.0.2 || ^18.0.0 || ^19.0.0", "typescript": "^5.5", "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["@standard-schema/spec", "hono", "react", "typescript", "zod"], "bin": { "convex-helpers": "bin.cjs" } }, "sha512-0O59Ohi8HVc3+KULxSC6JHsw8cQJyc8gZ7OAfNRVX7T5Wy6LhPx3l8veYN9avKg7UiPlO7m1eBiQMHKclIyXyQ=="],
952
953 "convex-test": ["convex-test@0.0.41", "", { "peerDependencies": { "convex": "^1.16.4" } }, "sha512-GPHeYFOi70n7UtW0eCEQFVhzl/+m8PvbWkDCbKpHLybI1MrScf4sVpGeM0cC2qmtxiduxa2nLPbehPalhh9oyQ=="],
954
955 "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
956
957 "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="],
958
959 "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="],
960
961 "cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="],
962
963 "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
964
965 "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
966
967 "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
968
969 "damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="],
970
971 "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="],
972
973 "data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="],
974
975 "data-view-byte-length": ["data-view-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ=="],
976
977 "data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="],
978
979 "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
980
981 "dedent": ["dedent@1.7.1", "", { "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, "optionalPeers": ["babel-plugin-macros"] }, "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg=="],
982
983 "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="],
984
985 "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
986
987 "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
988
989 "default-browser": ["default-browser@5.5.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw=="],
990
991 "default-browser-id": ["default-browser-id@5.0.1", "", {}, "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q=="],
992
993 "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="],
994
995 "define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="],
996
997 "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
998
999 "defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
1000
1001 "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
1002
1003 "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
1004
1005 "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
1006
1007 "diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="],
1008
1009 "doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="],
1010
1011 "dompurify": ["dompurify@3.2.7", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw=="],
1012
1013 "dotenv": ["dotenv@17.2.4", "", {}, "sha512-mudtfb4zRB4bVvdj0xRo+e6duH1csJRM8IukBqfTRvHotn9+LBXB8ynAidP9zHqoRC/fsllXgk4kCKlR21fIhw=="],
1014
1015 "dts-resolver": ["dts-resolver@2.1.3", "", { "peerDependencies": { "oxc-resolver": ">=11.0.0" }, "optionalPeers": ["oxc-resolver"] }, "sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw=="],
1016
1017 "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
1018
1019 "eciesjs": ["eciesjs@0.4.17", "", { "dependencies": { "@ecies/ciphers": "^0.2.5", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.7", "@noble/hashes": "^1.8.0" } }, "sha512-TOOURki4G7sD1wDCjj7NfLaXZZ49dFOeEb5y39IXpb8p0hRzVvfvzZHOi5JcT+PpyAbi/Y+lxPb8eTag2WYH8w=="],
1020
1021 "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
1022
1023 "electron-to-chromium": ["electron-to-chromium@1.5.286", "", {}, "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A=="],
1024
1025 "elysia": ["elysia@1.4.22", "", { "dependencies": { "cookie": "^1.1.1", "exact-mirror": "^0.2.6", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-Q90VCb1RVFxnFaRV0FDoSylESQQLWgLHFmWciQJdX9h3b2cSasji9KWEUvaJuy/L9ciAGg4RAhUVfsXHg5K2RQ=="],
1026
1027 "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
1028
1029 "empathic": ["empathic@2.0.0", "", {}, "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA=="],
1030
1031 "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
1032
1033 "enhanced-resolve": ["enhanced-resolve@5.19.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg=="],
1034
1035 "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="],
1036
1037 "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="],
1038
1039 "es-abstract": ["es-abstract@1.24.1", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw=="],
1040
1041 "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
1042
1043 "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
1044
1045 "es-iterator-helpers": ["es-iterator-helpers@1.2.2", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.24.1", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.1.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.3.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.5", "safe-array-concat": "^1.1.3" } }, "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w=="],
1046
1047 "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="],
1048
1049 "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
1050
1051 "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
1052
1053 "es-shim-unscopables": ["es-shim-unscopables@1.1.0", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw=="],
1054
1055 "es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="],
1056
1057 "esbuild": ["esbuild@0.27.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.0", "@esbuild/android-arm": "0.27.0", "@esbuild/android-arm64": "0.27.0", "@esbuild/android-x64": "0.27.0", "@esbuild/darwin-arm64": "0.27.0", "@esbuild/darwin-x64": "0.27.0", "@esbuild/freebsd-arm64": "0.27.0", "@esbuild/freebsd-x64": "0.27.0", "@esbuild/linux-arm": "0.27.0", "@esbuild/linux-arm64": "0.27.0", "@esbuild/linux-ia32": "0.27.0", "@esbuild/linux-loong64": "0.27.0", "@esbuild/linux-mips64el": "0.27.0", "@esbuild/linux-ppc64": "0.27.0", "@esbuild/linux-riscv64": "0.27.0", "@esbuild/linux-s390x": "0.27.0", "@esbuild/linux-x64": "0.27.0", "@esbuild/netbsd-arm64": "0.27.0", "@esbuild/netbsd-x64": "0.27.0", "@esbuild/openbsd-arm64": "0.27.0", "@esbuild/openbsd-x64": "0.27.0", "@esbuild/openharmony-arm64": "0.27.0", "@esbuild/sunos-x64": "0.27.0", "@esbuild/win32-arm64": "0.27.0", "@esbuild/win32-ia32": "0.27.0", "@esbuild/win32-x64": "0.27.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA=="],
1058
1059 "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
1060
1061 "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
1062
1063 "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
1064
1065 "eslint": ["eslint@9.39.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.2", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw=="],
1066
1067 "eslint-config-next": ["eslint-config-next@16.1.6", "", { "dependencies": { "@next/eslint-plugin-next": "16.1.6", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^7.0.0", "globals": "16.4.0", "typescript-eslint": "^8.46.0" }, "peerDependencies": { "eslint": ">=9.0.0", "typescript": ">=3.3.1" }, "optionalPeers": ["typescript"] }, "sha512-vKq40io2B0XtkkNDYyleATwblNt8xuh3FWp8SpSz3pt7P01OkBFlKsJZ2mWt5WsCySlDQLckb1zMY9yE9Qy0LA=="],
1068
1069 "eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.9", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g=="],
1070
1071 "eslint-import-resolver-typescript": ["eslint-import-resolver-typescript@3.10.1", "", { "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.4.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^2.0.0", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.13", "unrs-resolver": "^1.6.2" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", "eslint-plugin-import-x": "*" }, "optionalPeers": ["eslint-plugin-import", "eslint-plugin-import-x"] }, "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ=="],
1072
1073 "eslint-module-utils": ["eslint-module-utils@2.12.1", "", { "dependencies": { "debug": "^3.2.7" } }, "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw=="],
1074
1075 "eslint-plugin-import": ["eslint-plugin-import@2.32.0", "", { "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", "array.prototype.findlastindex": "^1.2.6", "array.prototype.flat": "^1.3.3", "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.12.1", "hasown": "^2.0.2", "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", "object.values": "^1.2.1", "semver": "^6.3.1", "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "peerDependencies": { "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA=="],
1076
1077 "eslint-plugin-jsx-a11y": ["eslint-plugin-jsx-a11y@6.10.2", "", { "dependencies": { "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", "axe-core": "^4.10.0", "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", "string.prototype.includes": "^2.0.1" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q=="],
1078
1079 "eslint-plugin-react": ["eslint-plugin-react@7.37.5", "", { "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA=="],
1080
1081 "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@7.0.1", "", { "dependencies": { "@babel/core": "^7.24.4", "@babel/parser": "^7.24.4", "hermes-parser": "^0.25.1", "zod": "^3.25.0 || ^4.0.0", "zod-validation-error": "^3.5.0 || ^4.0.0" }, "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA=="],
1082
1083 "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
1084
1085 "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
1086
1087 "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
1088
1089 "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
1090
1091 "esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="],
1092
1093 "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
1094
1095 "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
1096
1097 "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
1098
1099 "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
1100
1101 "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
1102
1103 "events-universal": ["events-universal@1.0.1", "", { "dependencies": { "bare-events": "^2.7.0" } }, "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw=="],
1104
1105 "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="],
1106
1107 "eventsource-parser": ["eventsource-parser@3.0.6", "", {}, "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg=="],
1108
1109 "exact-mirror": ["exact-mirror@0.2.6", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-7s059UIx9/tnOKSySzUk5cPGkoILhTE4p6ncf6uIPaQ+9aRBQzQjc9+q85l51+oZ+P6aBxh084pD0CzBQPcFUA=="],
1110
1111 "execa": ["execa@9.6.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.1.1" } }, "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA=="],
1112
1113 "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="],
1114
1115 "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
1116
1117 "express-rate-limit": ["express-rate-limit@8.2.1", "", { "dependencies": { "ip-address": "10.0.1" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g=="],
1118
1119 "fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
1120
1121 "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
1122
1123 "fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],
1124
1125 "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
1126
1127 "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
1128
1129 "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
1130
1131 "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="],
1132
1133 "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
1134
1135 "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
1136
1137 "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="],
1138
1139 "figures": ["figures@6.1.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="],
1140
1141 "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
1142
1143 "file-type": ["file-type@21.3.0", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA=="],
1144
1145 "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
1146
1147 "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="],
1148
1149 "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
1150
1151 "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
1152
1153 "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
1154
1155 "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
1156
1157 "formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="],
1158
1159 "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
1160
1161 "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
1162
1163 "fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="],
1164
1165 "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
1166
1167 "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
1168
1169 "function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="],
1170
1171 "functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
1172
1173 "fuzzysort": ["fuzzysort@3.1.0", "", {}, "sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ=="],
1174
1175 "fzf": ["fzf@0.5.2", "", {}, "sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q=="],
1176
1177 "generator-function": ["generator-function@2.0.1", "", {}, "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g=="],
1178
1179 "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
1180
1181 "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
1182
1183 "get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="],
1184
1185 "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
1186
1187 "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="],
1188
1189 "get-own-enumerable-keys": ["get-own-enumerable-keys@1.0.0", "", {}, "sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA=="],
1190
1191 "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
1192
1193 "get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="],
1194
1195 "get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="],
1196
1197 "get-tsconfig": ["get-tsconfig@4.13.6", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw=="],
1198
1199 "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
1200
1201 "globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="],
1202
1203 "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="],
1204
1205 "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
1206
1207 "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
1208
1209 "graphql": ["graphql@16.12.0", "", {}, "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ=="],
1210
1211 "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="],
1212
1213 "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
1214
1215 "has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="],
1216
1217 "has-proto": ["has-proto@1.2.0", "", { "dependencies": { "dunder-proto": "^1.0.0" } }, "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ=="],
1218
1219 "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
1220
1221 "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
1222
1223 "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
1224
1225 "headers-polyfill": ["headers-polyfill@4.0.3", "", {}, "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ=="],
1226
1227 "hermes-estree": ["hermes-estree@0.25.1", "", {}, "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="],
1228
1229 "hermes-parser": ["hermes-parser@0.25.1", "", { "dependencies": { "hermes-estree": "0.25.1" } }, "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA=="],
1230
1231 "hono": ["hono@4.11.9", "", {}, "sha512-Eaw2YTGM6WOxA6CXbckaEvslr2Ne4NFsKrvc0v97JD5awbmeBLO5w9Ho9L9kmKonrwF9RJlW6BxT1PVv/agBHQ=="],
1232
1233 "hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
1234
1235 "http-errors": ["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" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
1236
1237 "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
1238
1239 "human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="],
1240
1241 "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
1242
1243 "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
1244
1245 "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
1246
1247 "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
1248
1249 "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
1250
1251 "index-to-position": ["index-to-position@1.2.0", "", {}, "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw=="],
1252
1253 "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
1254
1255 "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
1256
1257 "ip-address": ["ip-address@10.0.1", "", {}, "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA=="],
1258
1259 "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
1260
1261 "iron-session": ["iron-session@8.0.4", "", { "dependencies": { "cookie": "^0.7.2", "iron-webcrypto": "^1.2.1", "uncrypto": "^0.1.3" } }, "sha512-9ivNnaKOd08osD0lJ3i6If23GFS2LsxyMU8Gf/uBUEgm8/8CC1hrrCHFDpMo3IFbpBgwoo/eairRsaD3c5itxA=="],
1262
1263 "iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="],
1264
1265 "is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="],
1266
1267 "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="],
1268
1269 "is-async-function": ["is-async-function@2.1.1", "", { "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ=="],
1270
1271 "is-bigint": ["is-bigint@1.1.0", "", { "dependencies": { "has-bigints": "^1.0.2" } }, "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ=="],
1272
1273 "is-boolean-object": ["is-boolean-object@1.2.2", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A=="],
1274
1275 "is-bun-module": ["is-bun-module@2.0.0", "", { "dependencies": { "semver": "^7.7.1" } }, "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ=="],
1276
1277 "is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="],
1278
1279 "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
1280
1281 "is-data-view": ["is-data-view@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" } }, "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw=="],
1282
1283 "is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="],
1284
1285 "is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="],
1286
1287 "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
1288
1289 "is-finalizationregistry": ["is-finalizationregistry@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg=="],
1290
1291 "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
1292
1293 "is-generator-function": ["is-generator-function@1.1.2", "", { "dependencies": { "call-bound": "^1.0.4", "generator-function": "^2.0.0", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA=="],
1294
1295 "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
1296
1297 "is-in-ssh": ["is-in-ssh@1.0.0", "", {}, "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw=="],
1298
1299 "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="],
1300
1301 "is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="],
1302
1303 "is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="],
1304
1305 "is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="],
1306
1307 "is-node-process": ["is-node-process@1.2.0", "", {}, "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw=="],
1308
1309 "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
1310
1311 "is-number-object": ["is-number-object@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw=="],
1312
1313 "is-obj": ["is-obj@3.0.0", "", {}, "sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ=="],
1314
1315 "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="],
1316
1317 "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
1318
1319 "is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="],
1320
1321 "is-regexp": ["is-regexp@3.1.0", "", {}, "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA=="],
1322
1323 "is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="],
1324
1325 "is-shared-array-buffer": ["is-shared-array-buffer@1.0.4", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A=="],
1326
1327 "is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="],
1328
1329 "is-string": ["is-string@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA=="],
1330
1331 "is-symbol": ["is-symbol@1.1.1", "", { "dependencies": { "call-bound": "^1.0.2", "has-symbols": "^1.1.0", "safe-regex-test": "^1.1.0" } }, "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w=="],
1332
1333 "is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="],
1334
1335 "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="],
1336
1337 "is-weakmap": ["is-weakmap@2.0.2", "", {}, "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w=="],
1338
1339 "is-weakref": ["is-weakref@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew=="],
1340
1341 "is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="],
1342
1343 "is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="],
1344
1345 "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
1346
1347 "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
1348
1349 "iterator.prototype": ["iterator.prototype@1.1.5", "", { "dependencies": { "define-data-property": "^1.1.4", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "get-proto": "^1.0.0", "has-symbols": "^1.1.0", "set-function-name": "^2.0.2" } }, "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g=="],
1350
1351 "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
1352
1353 "jose": ["jose@6.1.3", "", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="],
1354
1355 "js-levenshtein": ["js-levenshtein@1.1.6", "", {}, "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g=="],
1356
1357 "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
1358
1359 "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
1360
1361 "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
1362
1363 "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
1364
1365 "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="],
1366
1367 "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
1368
1369 "json-schema-typed": ["json-schema-typed@8.0.2", "", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="],
1370
1371 "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
1372
1373 "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
1374
1375 "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
1376
1377 "jsonlines": ["jsonlines@0.1.1", "", {}, "sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA=="],
1378
1379 "jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="],
1380
1381 "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
1382
1383 "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
1384
1385 "language-subtag-registry": ["language-subtag-registry@0.3.23", "", {}, "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ=="],
1386
1387 "language-tags": ["language-tags@1.0.9", "", { "dependencies": { "language-subtag-registry": "^0.3.20" } }, "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA=="],
1388
1389 "leb": ["leb@1.0.0", "", {}, "sha512-Y3c3QZfvKWHX60BVOQPhLCvVGmDYWyJEiINE3drOog6KCyN2AOwvuQQzlS3uJg1J85kzpILXIUwRXULWavir+w=="],
1390
1391 "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
1392
1393 "lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
1394
1395 "lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="],
1396
1397 "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="],
1398
1399 "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="],
1400
1401 "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="],
1402
1403 "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="],
1404
1405 "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="],
1406
1407 "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="],
1408
1409 "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="],
1410
1411 "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="],
1412
1413 "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="],
1414
1415 "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
1416
1417 "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
1418
1419 "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
1420
1421 "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
1422
1423 "log-symbols": ["log-symbols@6.0.0", "", { "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" } }, "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw=="],
1424
1425 "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
1426
1427 "loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="],
1428
1429 "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
1430
1431 "lucide-react": ["lucide-react@0.563.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA=="],
1432
1433 "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
1434
1435 "marked": ["marked@14.0.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ=="],
1436
1437 "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
1438
1439 "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
1440
1441 "memoirist": ["memoirist@0.4.0", "", {}, "sha512-zxTgA0mSYELa66DimuNQDvyLq36AwDlTuVRbnQtB+VuTcKWm5Qc4z3WkSpgsFWHNhexqkIooqpv4hdcqrX5Nmg=="],
1442
1443 "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="],
1444
1445 "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
1446
1447 "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
1448
1449 "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
1450
1451 "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
1452
1453 "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="],
1454
1455 "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
1456
1457 "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="],
1458
1459 "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
1460
1461 "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
1462
1463 "monaco-editor": ["monaco-editor@0.55.1", "", { "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" } }, "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A=="],
1464
1465 "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
1466
1467 "msw": ["msw@2.12.9", "", { "dependencies": { "@inquirer/confirm": "^5.0.0", "@mswjs/interceptors": "^0.41.2", "@open-draft/deferred-promise": "^2.2.0", "@types/statuses": "^2.0.6", "cookie": "^1.0.2", "graphql": "^16.12.0", "headers-polyfill": "^4.0.2", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", "picocolors": "^1.1.1", "rettime": "^0.10.1", "statuses": "^2.0.2", "strict-event-emitter": "^0.5.1", "tough-cookie": "^6.0.0", "type-fest": "^5.2.0", "until-async": "^3.0.2", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": ">= 4.8.x" }, "optionalPeers": ["typescript"], "bin": { "msw": "cli/index.js" } }, "sha512-NYbi51C6M3dujGmcmuGemu68jy12KqQPoVWGeroKToLGsBgrwG5ErM8WctoIIg49/EV49SEvYM9WSqO4G7kNeQ=="],
1468
1469 "mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="],
1470
1471 "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
1472
1473 "napi-postinstall": ["napi-postinstall@0.3.4", "", { "bin": { "napi-postinstall": "lib/cli.js" } }, "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ=="],
1474
1475 "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
1476
1477 "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
1478
1479 "next": ["next@16.1.6", "", { "dependencies": { "@next/env": "16.1.6", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.6", "@next/swc-darwin-x64": "16.1.6", "@next/swc-linux-arm64-gnu": "16.1.6", "@next/swc-linux-arm64-musl": "16.1.6", "@next/swc-linux-x64-gnu": "16.1.6", "@next/swc-linux-x64-musl": "16.1.6", "@next/swc-win32-arm64-msvc": "16.1.6", "@next/swc-win32-x64-msvc": "16.1.6", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw=="],
1480
1481 "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="],
1482
1483 "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="],
1484
1485 "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
1486
1487 "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
1488
1489 "npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="],
1490
1491 "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
1492
1493 "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
1494
1495 "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="],
1496
1497 "object-treeify": ["object-treeify@1.1.33", "", {}, "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A=="],
1498
1499 "object.assign": ["object.assign@4.1.7", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0", "has-symbols": "^1.1.0", "object-keys": "^1.1.1" } }, "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw=="],
1500
1501 "object.entries": ["object.entries@1.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-object-atoms": "^1.1.1" } }, "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw=="],
1502
1503 "object.fromentries": ["object.fromentries@2.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0" } }, "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ=="],
1504
1505 "object.groupby": ["object.groupby@1.0.3", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2" } }, "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ=="],
1506
1507 "object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="],
1508
1509 "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
1510
1511 "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
1512
1513 "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
1514
1515 "open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="],
1516
1517 "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
1518
1519 "openapi-typescript": ["openapi-typescript@7.10.1", "", { "dependencies": { "@redocly/openapi-core": "^1.34.5", "ansi-colors": "^4.1.3", "change-case": "^5.4.4", "parse-json": "^8.3.0", "supports-color": "^10.2.2", "yargs-parser": "^21.1.1" }, "peerDependencies": { "typescript": "^5.x" }, "bin": { "openapi-typescript": "bin/cli.js" } }, "sha512-rBcU8bjKGGZQT4K2ekSTY2Q5veOQbVG/lTKZ49DeCyT9z62hM2Vj/LLHjDHC9W7LJG8YMHcdXpRZDqC1ojB/lw=="],
1520
1521 "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
1522
1523 "ora": ["ora@8.2.0", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", "cli-spinners": "^2.9.2", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "log-symbols": "^6.0.0", "stdin-discarder": "^0.2.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0" } }, "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw=="],
1524
1525 "os-paths": ["os-paths@4.4.0", "", {}, "sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg=="],
1526
1527 "outvariant": ["outvariant@1.4.3", "", {}, "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA=="],
1528
1529 "own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="],
1530
1531 "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
1532
1533 "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
1534
1535 "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="],
1536
1537 "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
1538
1539 "parse-json": ["parse-json@8.3.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "index-to-position": "^1.1.0", "type-fest": "^4.39.1" } }, "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ=="],
1540
1541 "parse-ms": ["parse-ms@4.0.0", "", {}, "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw=="],
1542
1543 "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
1544
1545 "path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="],
1546
1547 "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
1548
1549 "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
1550
1551 "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
1552
1553 "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="],
1554
1555 "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
1556
1557 "pathval": ["pathval@2.0.1", "", {}, "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ=="],
1558
1559 "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
1560
1561 "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
1562
1563 "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="],
1564
1565 "pluralize": ["pluralize@8.0.0", "", {}, "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA=="],
1566
1567 "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
1568
1569 "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
1570
1571 "postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
1572
1573 "powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="],
1574
1575 "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
1576
1577 "prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
1578
1579 "pretty-ms": ["pretty-ms@9.3.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ=="],
1580
1581 "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
1582
1583 "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
1584
1585 "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
1586
1587 "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
1588
1589 "pvtsutils": ["pvtsutils@1.3.6", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg=="],
1590
1591 "pvutils": ["pvutils@1.1.5", "", {}, "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA=="],
1592
1593 "qs": ["qs@6.14.1", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ=="],
1594
1595 "quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="],
1596
1597 "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
1598
1599 "radix-ui": ["radix-ui@1.4.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-accessible-icon": "1.1.7", "@radix-ui/react-accordion": "1.2.12", "@radix-ui/react-alert-dialog": "1.1.15", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-aspect-ratio": "1.1.7", "@radix-ui/react-avatar": "1.1.10", "@radix-ui/react-checkbox": "1.3.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-context-menu": "2.2.16", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-dropdown-menu": "2.1.16", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-form": "0.1.8", "@radix-ui/react-hover-card": "1.1.15", "@radix-ui/react-label": "2.1.7", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-menubar": "1.1.16", "@radix-ui/react-navigation-menu": "1.2.14", "@radix-ui/react-one-time-password-field": "0.1.8", "@radix-ui/react-password-toggle-field": "0.1.3", "@radix-ui/react-popover": "1.1.15", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-progress": "1.1.7", "@radix-ui/react-radio-group": "1.3.8", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-scroll-area": "1.2.10", "@radix-ui/react-select": "2.2.6", "@radix-ui/react-separator": "1.1.7", "@radix-ui/react-slider": "1.3.6", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-switch": "1.2.6", "@radix-ui/react-tabs": "1.1.13", "@radix-ui/react-toast": "1.2.15", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-toggle-group": "1.1.11", "@radix-ui/react-toolbar": "1.1.11", "@radix-ui/react-tooltip": "1.2.8", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-escape-keydown": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA=="],
1600
1601 "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
1602
1603 "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="],
1604
1605 "react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="],
1606
1607 "react-dom": ["react-dom@19.2.3", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.3" } }, "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg=="],
1608
1609 "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
1610
1611 "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="],
1612
1613 "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="],
1614
1615 "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="],
1616
1617 "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
1618
1619 "recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="],
1620
1621 "reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="],
1622
1623 "regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],
1624
1625 "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
1626
1627 "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
1628
1629 "resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
1630
1631 "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
1632
1633 "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
1634
1635 "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
1636
1637 "retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="],
1638
1639 "rettime": ["rettime@0.10.1", "", {}, "sha512-uyDrIlUEH37cinabq0AX4QbgV4HbFZ/gqoiunWQ1UqBtRvTTytwhNYjE++pO/MjPTZL5KQCf2bEoJ/BJNVQ5Kw=="],
1640
1641 "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
1642
1643 "rolldown": ["rolldown@1.0.0-rc.3", "", { "dependencies": { "@oxc-project/types": "=0.112.0", "@rolldown/pluginutils": "1.0.0-rc.3" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.3", "@rolldown/binding-darwin-arm64": "1.0.0-rc.3", "@rolldown/binding-darwin-x64": "1.0.0-rc.3", "@rolldown/binding-freebsd-x64": "1.0.0-rc.3", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.3", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.3", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.3", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.3", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.3", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.3", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.3", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.3", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.3" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-Po/YZECDOqVXjIXrtC5h++a5NLvKAQNrd9ggrIG3sbDfGO5BqTUsrI6l8zdniKRp3r5Tp/2JTrXqx4GIguFCMw=="],
1644
1645 "rolldown-plugin-dts": ["rolldown-plugin-dts@0.13.14", "", { "dependencies": { "@babel/generator": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/types": "^7.28.1", "ast-kit": "^2.1.1", "birpc": "^2.5.0", "debug": "^4.4.1", "dts-resolver": "^2.1.1", "get-tsconfig": "^4.10.1" }, "peerDependencies": { "@typescript/native-preview": ">=7.0.0-dev.20250601.1", "rolldown": "^1.0.0-beta.9", "typescript": "^5.0.0", "vue-tsc": "^2.2.0 || ^3.0.0" }, "optionalPeers": ["@typescript/native-preview", "typescript", "vue-tsc"] }, "sha512-wjNhHZz9dlN6PTIXyizB6u/mAg1wEFMW9yw7imEVe3CxHSRnNHVyycIX0yDEOVJfDNISLPbkCIPEpFpizy5+PQ=="],
1646
1647 "rollup": ["rollup@4.57.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.1", "@rollup/rollup-android-arm64": "4.57.1", "@rollup/rollup-darwin-arm64": "4.57.1", "@rollup/rollup-darwin-x64": "4.57.1", "@rollup/rollup-freebsd-arm64": "4.57.1", "@rollup/rollup-freebsd-x64": "4.57.1", "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", "@rollup/rollup-linux-arm-musleabihf": "4.57.1", "@rollup/rollup-linux-arm64-gnu": "4.57.1", "@rollup/rollup-linux-arm64-musl": "4.57.1", "@rollup/rollup-linux-loong64-gnu": "4.57.1", "@rollup/rollup-linux-loong64-musl": "4.57.1", "@rollup/rollup-linux-ppc64-gnu": "4.57.1", "@rollup/rollup-linux-ppc64-musl": "4.57.1", "@rollup/rollup-linux-riscv64-gnu": "4.57.1", "@rollup/rollup-linux-riscv64-musl": "4.57.1", "@rollup/rollup-linux-s390x-gnu": "4.57.1", "@rollup/rollup-linux-x64-gnu": "4.57.1", "@rollup/rollup-linux-x64-musl": "4.57.1", "@rollup/rollup-openbsd-x64": "4.57.1", "@rollup/rollup-openharmony-arm64": "4.57.1", "@rollup/rollup-win32-arm64-msvc": "4.57.1", "@rollup/rollup-win32-ia32-msvc": "4.57.1", "@rollup/rollup-win32-x64-gnu": "4.57.1", "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A=="],
1648
1649 "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
1650
1651 "run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="],
1652
1653 "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
1654
1655 "safe-array-concat": ["safe-array-concat@1.1.3", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "has-symbols": "^1.1.0", "isarray": "^2.0.5" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="],
1656
1657 "safe-push-apply": ["safe-push-apply@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" } }, "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA=="],
1658
1659 "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="],
1660
1661 "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
1662
1663 "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
1664
1665 "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
1666
1667 "send": ["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" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="],
1668
1669 "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="],
1670
1671 "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="],
1672
1673 "set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="],
1674
1675 "set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="],
1676
1677 "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
1678
1679 "shadcn": ["shadcn@3.8.4", "", { "dependencies": { "@antfu/ni": "^25.0.0", "@babel/core": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0", "@babel/preset-typescript": "^7.27.1", "@dotenvx/dotenvx": "^1.48.4", "@modelcontextprotocol/sdk": "^1.26.0", "@types/validate-npm-package-name": "^4.0.2", "browserslist": "^4.26.2", "commander": "^14.0.0", "cosmiconfig": "^9.0.0", "dedent": "^1.6.0", "deepmerge": "^4.3.1", "diff": "^8.0.2", "execa": "^9.6.0", "fast-glob": "^3.3.3", "fs-extra": "^11.3.1", "fuzzysort": "^3.1.0", "https-proxy-agent": "^7.0.6", "kleur": "^4.1.5", "msw": "^2.10.4", "node-fetch": "^3.3.2", "open": "^11.0.0", "ora": "^8.2.0", "postcss": "^8.5.6", "postcss-selector-parser": "^7.1.0", "prompts": "^2.4.2", "recast": "^0.23.11", "stringify-object": "^5.0.0", "tailwind-merge": "^3.0.1", "ts-morph": "^26.0.0", "tsconfig-paths": "^4.2.0", "validate-npm-package-name": "^7.0.1", "zod": "^3.24.1", "zod-to-json-schema": "^3.24.6" }, "bin": { "shadcn": "dist/index.js" } }, "sha512-pSad/m1+PGzB0aLsRBV0EkyGg9al1nJqYUuucg6d8v8xZspPZ5/ehGNEp5M4b1KQYqdO5/gGPbkhVbgmXqG9Pw=="],
1680
1681 "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
1682
1683 "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
1684
1685 "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
1686
1687 "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
1688
1689 "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
1690
1691 "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
1692
1693 "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
1694
1695 "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
1696
1697 "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
1698
1699 "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
1700
1701 "sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="],
1702
1703 "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
1704
1705 "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
1706
1707 "stable-hash": ["stable-hash@0.0.5", "", {}, "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA=="],
1708
1709 "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="],
1710
1711 "state-local": ["state-local@1.0.7", "", {}, "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="],
1712
1713 "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
1714
1715 "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="],
1716
1717 "stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="],
1718
1719 "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="],
1720
1721 "streamx": ["streamx@2.23.0", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg=="],
1722
1723 "strict-event-emitter": ["strict-event-emitter@0.5.1", "", {}, "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ=="],
1724
1725 "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
1726
1727 "string.prototype.includes": ["string.prototype.includes@2.0.1", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3" } }, "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg=="],
1728
1729 "string.prototype.matchall": ["string.prototype.matchall@4.0.12", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA=="],
1730
1731 "string.prototype.repeat": ["string.prototype.repeat@1.0.0", "", { "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" } }, "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w=="],
1732
1733 "string.prototype.trim": ["string.prototype.trim@1.2.10", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-object-atoms": "^1.0.0", "has-property-descriptors": "^1.0.2" } }, "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA=="],
1734
1735 "string.prototype.trimend": ["string.prototype.trimend@1.0.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ=="],
1736
1737 "string.prototype.trimstart": ["string.prototype.trimstart@1.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg=="],
1738
1739 "stringify-object": ["stringify-object@5.0.0", "", { "dependencies": { "get-own-enumerable-keys": "^1.0.0", "is-obj": "^3.0.0", "is-regexp": "^3.1.0" } }, "sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg=="],
1740
1741 "strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
1742
1743 "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="],
1744
1745 "strip-final-newline": ["strip-final-newline@4.0.0", "", {}, "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw=="],
1746
1747 "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
1748
1749 "strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="],
1750
1751 "stripe": ["stripe@20.3.1", "", { "peerDependencies": { "@types/node": ">=16" }, "optionalPeers": ["@types/node"] }, "sha512-k990yOT5G5rhX3XluRPw5Y8RLdJDW4dzQ29wWT66piHrbnM2KyamJ1dKgPsw4HzGHRWjDiSSdcI2WdxQUPV3aQ=="],
1752
1753 "strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
1754
1755 "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="],
1756
1757 "supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="],
1758
1759 "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
1760
1761 "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="],
1762
1763 "tailwind-merge": ["tailwind-merge@3.4.0", "", {}, "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g=="],
1764
1765 "tailwindcss": ["tailwindcss@4.1.18", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="],
1766
1767 "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
1768
1769 "tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="],
1770
1771 "text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],
1772
1773 "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
1774
1775 "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="],
1776
1777 "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="],
1778
1779 "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
1780
1781 "tinypool": ["tinypool@1.1.1", "", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="],
1782
1783 "tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="],
1784
1785 "tinyspy": ["tinyspy@4.0.4", "", {}, "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q=="],
1786
1787 "tldts": ["tldts@7.0.22", "", { "dependencies": { "tldts-core": "^7.0.22" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-nqpKFC53CgopKPjT6Wfb6tpIcZXHcI6G37hesvikhx0EmUGPkZrujRyAjgnmp1SHNgpQfKVanZ+KfpANFt2Hxw=="],
1788
1789 "tldts-core": ["tldts-core@7.0.22", "", {}, "sha512-KgbTDC5wzlL6j/x6np6wCnDSMUq4kucHNm00KXPbfNzmllCmtmvtykJHfmgdHntwIeupW04y8s1N/43S1PkQDw=="],
1790
1791 "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
1792
1793 "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
1794
1795 "token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="],
1796
1797 "tough-cookie": ["tough-cookie@6.0.0", "", { "dependencies": { "tldts": "^7.0.5" } }, "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w=="],
1798
1799 "ts-api-utils": ["ts-api-utils@2.4.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA=="],
1800
1801 "ts-morph": ["ts-morph@26.0.0", "", { "dependencies": { "@ts-morph/common": "~0.27.0", "code-block-writer": "^13.0.3" } }, "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug=="],
1802
1803 "tsconfig-paths": ["tsconfig-paths@4.2.0", "", { "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg=="],
1804
1805 "tsdown": ["tsdown@0.12.9", "", { "dependencies": { "ansis": "^4.1.0", "cac": "^6.7.14", "chokidar": "^4.0.3", "debug": "^4.4.1", "diff": "^8.0.2", "empathic": "^2.0.0", "hookable": "^5.5.3", "rolldown": "^1.0.0-beta.19", "rolldown-plugin-dts": "^0.13.12", "semver": "^7.7.2", "tinyexec": "^1.0.1", "tinyglobby": "^0.2.14", "unconfig": "^7.3.2" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "publint": "^0.3.0", "typescript": "^5.0.0", "unplugin-lightningcss": "^0.4.0", "unplugin-unused": "^0.5.0" }, "optionalPeers": ["@arethetypeswrong/core", "publint", "typescript", "unplugin-lightningcss", "unplugin-unused"], "bin": { "tsdown": "dist/run.mjs" } }, "sha512-MfrXm9PIlT3saovtWKf/gCJJ/NQCdE0SiREkdNC+9Qy6UHhdeDPxnkFaBD7xttVUmgp0yUHtGirpoLB+OVLuLA=="],
1806
1807 "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
1808
1809 "tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
1810
1811 "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
1812
1813 "type-fest": ["type-fest@5.4.4", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw=="],
1814
1815 "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
1816
1817 "typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
1818
1819 "typed-array-byte-length": ["typed-array-byte-length@1.0.3", "", { "dependencies": { "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.14" } }, "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg=="],
1820
1821 "typed-array-byte-offset": ["typed-array-byte-offset@1.0.4", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.15", "reflect.getprototypeof": "^1.0.9" } }, "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ=="],
1822
1823 "typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="],
1824
1825 "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
1826
1827 "typescript-eslint": ["typescript-eslint@8.54.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.54.0", "@typescript-eslint/parser": "8.54.0", "@typescript-eslint/typescript-estree": "8.54.0", "@typescript-eslint/utils": "8.54.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ=="],
1828
1829 "uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
1830
1831 "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
1832
1833 "unconfig": ["unconfig@7.4.2", "", { "dependencies": { "@quansync/fs": "^1.0.0", "defu": "^6.1.4", "jiti": "^2.6.1", "quansync": "^1.0.0", "unconfig-core": "7.4.2" } }, "sha512-nrMlWRQ1xdTjSnSUqvYqJzbTBFugoqHobQj58B2bc8qxHKBBHMNNsWQFP3Cd3/JZK907voM2geYPWqD4VK3MPQ=="],
1834
1835 "unconfig-core": ["unconfig-core@7.4.2", "", { "dependencies": { "@quansync/fs": "^1.0.0", "quansync": "^1.0.0" } }, "sha512-VgPCvLWugINbXvMQDf8Jh0mlbvNjNC6eSUziHsBCMpxR05OPrNrvDnyatdMjRgcHaaNsCqz+wjNXxNw1kRLHUg=="],
1836
1837 "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
1838
1839 "undici": ["undici@7.21.0", "", {}, "sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg=="],
1840
1841 "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
1842
1843 "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="],
1844
1845 "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
1846
1847 "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
1848
1849 "unrs-resolver": ["unrs-resolver@1.11.1", "", { "dependencies": { "napi-postinstall": "^0.3.0" }, "optionalDependencies": { "@unrs/resolver-binding-android-arm-eabi": "1.11.1", "@unrs/resolver-binding-android-arm64": "1.11.1", "@unrs/resolver-binding-darwin-arm64": "1.11.1", "@unrs/resolver-binding-darwin-x64": "1.11.1", "@unrs/resolver-binding-freebsd-x64": "1.11.1", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-musl": "1.11.1", "@unrs/resolver-binding-wasm32-wasi": "1.11.1", "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg=="],
1850
1851 "until-async": ["until-async@3.0.2", "", {}, "sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw=="],
1852
1853 "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
1854
1855 "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
1856
1857 "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
1858
1859 "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="],
1860
1861 "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
1862
1863 "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
1864
1865 "validate-npm-package-name": ["validate-npm-package-name@7.0.2", "", {}, "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A=="],
1866
1867 "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
1868
1869 "vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="],
1870
1871 "vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="],
1872
1873 "vitest": ["vitest@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", "@vitest/mocker": "3.2.4", "@vitest/pretty-format": "^3.2.4", "@vitest/runner": "3.2.4", "@vitest/snapshot": "3.2.4", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.4", "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A=="],
1874
1875 "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
1876
1877 "webcrypto-core": ["webcrypto-core@1.8.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.3.13", "@peculiar/json-schema": "^1.1.12", "asn1js": "^3.0.5", "pvtsutils": "^1.3.5", "tslib": "^2.7.0" } }, "sha512-P+x1MvlNCXlKbLSOY4cYrdreqPG5hbzkmawbcXLKN/mf6DZW0SdNNkZ+sjwsqVkI4A4Ko2sPZmkZtCKY58w83A=="],
1878
1879 "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
1880
1881 "which-boxed-primitive": ["which-boxed-primitive@1.1.1", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="],
1882
1883 "which-builtin-type": ["which-builtin-type@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.1.0", "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.1.0", "which-collection": "^1.0.2", "which-typed-array": "^1.1.16" } }, "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q=="],
1884
1885 "which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="],
1886
1887 "which-typed-array": ["which-typed-array@1.1.20", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg=="],
1888
1889 "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="],
1890
1891 "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
1892
1893 "wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="],
1894
1895 "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
1896
1897 "wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="],
1898
1899 "xdg-app-paths": ["xdg-app-paths@5.1.0", "", { "dependencies": { "xdg-portable": "^7.0.0" } }, "sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA=="],
1900
1901 "xdg-portable": ["xdg-portable@7.3.0", "", { "dependencies": { "os-paths": "^4.0.1" } }, "sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw=="],
1902
1903 "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
1904
1905 "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
1906
1907 "yaml-ast-parser": ["yaml-ast-parser@0.0.43", "", {}, "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A=="],
1908
1909 "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
1910
1911 "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
1912
1913 "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
1914
1915 "yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="],
1916
1917 "yoctocolors-cjs": ["yoctocolors-cjs@2.1.3", "", {}, "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw=="],
1918
1919 "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
1920
1921 "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="],
1922
1923 "zod-validation-error": ["zod-validation-error@4.0.2", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ=="],
1924
1925 "@convex-dev/workos/@workos-inc/authkit-react": ["@workos-inc/authkit-react@0.11.0", "", { "dependencies": { "@workos-inc/authkit-js": "0.13.0" }, "peerDependencies": { "react": ">=17" } }, "sha512-67HFSxP4wXC8ECGyvc1yGMwuD5NGkwT2OPt8DavHoKAlO+hRaAlu9wwzqUx1EJrHht0Dcx+l20Byq8Ab0bEhlg=="],
1926
1927 "@dotenvx/dotenvx/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
1928
1929 "@dotenvx/dotenvx/execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
1930
1931 "@dotenvx/dotenvx/which": ["which@4.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="],
1932
1933 "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
1934
1935 "@eslint/eslintrc/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
1936
1937 "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
1938
1939 "@next/eslint-plugin-next/fast-glob": ["fast-glob@3.3.1", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" } }, "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg=="],
1940
1941 "@redocly/openapi-core/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
1942
1943 "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
1944
1945 "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="],
1946
1947 "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
1948
1949 "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
1950
1951 "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
1952
1953 "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
1954
1955 "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
1956
1957 "@ts-morph/common/minimatch": ["minimatch@10.1.2", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.1" } }, "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw=="],
1958
1959 "@types/serve-static/@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="],
1960
1961 "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
1962
1963 "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
1964
1965 "@typescript-eslint/typescript-estree/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
1966
1967 "@vercel/sandbox/zod": ["zod@3.24.4", "", {}, "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg=="],
1968
1969 "@workos-inc/authkit-nextjs/jose": ["jose@5.6.3", "", {}, "sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g=="],
1970
1971 "@workos-inc/node/iron-session": ["iron-session@6.3.1", "", { "dependencies": { "@peculiar/webcrypto": "^1.4.0", "@types/cookie": "^0.5.1", "@types/express": "^4.17.13", "@types/koa": "^2.13.5", "@types/node": "^17.0.41", "cookie": "^0.5.0", "iron-webcrypto": "^0.2.5" }, "peerDependencies": { "express": ">=4", "koa": ">=2", "next": ">=10" }, "optionalPeers": ["express", "koa", "next"] }, "sha512-3UJ7y2vk/WomAtEySmPgM6qtYF1cZ3tXuWX5GsVX4PJXAcs5y/sV9HuSfpjKS6HkTL/OhZcTDWJNLZ7w+Erx3A=="],
1972
1973 "@workos-inc/node/jose": ["jose@5.6.3", "", {}, "sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g=="],
1974
1975 "chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
1976
1977 "cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
1978
1979 "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
1980
1981 "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
1982
1983 "cosmiconfig/parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="],
1984
1985 "eslint/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
1986
1987 "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
1988
1989 "eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
1990
1991 "eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
1992
1993 "eslint-plugin-import/tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
1994
1995 "eslint-plugin-react/resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="],
1996
1997 "express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
1998
1999 "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
2000
2001 "iron-session/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
2002
2003 "is-bun-module/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
2004
2005 "log-symbols/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
2006
2007 "log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="],
2008
2009 "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
2010
2011 "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
2012
2013 "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
2014
2015 "ora/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
2016
2017 "parse-json/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
2018
2019 "prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
2020
2021 "restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
2022
2023 "router/path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="],
2024
2025 "shadcn/zod": ["zod@3.24.4", "", {}, "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg=="],
2026
2027 "sharp/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
2028
2029 "string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
2030
2031 "strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
2032
2033 "tsdown/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
2034
2035 "vitest/tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="],
2036
2037 "wrap-ansi/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
2038
2039 "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
2040
2041 "yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
2042
2043 "@convex-dev/workos/@workos-inc/authkit-react/@workos-inc/authkit-js": ["@workos-inc/authkit-js@0.13.0", "", {}, "sha512-iA0Dt7D1BmY2/1s4oeA36W/aRt8/b5iyH6rP4AlgnjrcH2lUGkBgDXL76NXc0M7repkDQTMcJJ2NhCSo2rcWmg=="],
2044
2045 "@dotenvx/dotenvx/execa/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
2046
2047 "@dotenvx/dotenvx/execa/human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
2048
2049 "@dotenvx/dotenvx/execa/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
2050
2051 "@dotenvx/dotenvx/execa/npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="],
2052
2053 "@dotenvx/dotenvx/execa/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
2054
2055 "@dotenvx/dotenvx/execa/strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="],
2056
2057 "@dotenvx/dotenvx/which/isexe": ["isexe@3.1.4", "", {}, "sha512-jCErc4h4RnTPjFq53G4whhjAMbUAqinGrCrTT4dmMNyi4zTthK+wphqbRLJtL4BN/Mq7Zzltr0m/b1X0m7PGFQ=="],
2058
2059 "@eslint/eslintrc/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
2060
2061 "@next/eslint-plugin-next/fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
2062
2063 "@redocly/openapi-core/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
2064
2065 "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
2066
2067 "@workos-inc/node/iron-session/@types/node": ["@types/node@17.0.45", "", {}, "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="],
2068
2069 "@workos-inc/node/iron-session/cookie": ["cookie@0.5.0", "", {}, "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="],
2070
2071 "@workos-inc/node/iron-session/iron-webcrypto": ["iron-webcrypto@0.2.8", "", { "dependencies": { "buffer": "^6" } }, "sha512-YPdCvjFMOBjXaYuDj5tiHst5CEk6Xw84Jo8Y2+jzhMceclAnb3+vNPP/CTtb5fO2ZEuXEaO4N+w62Vfko757KA=="],
2072
2073 "cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
2074
2075 "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
2076
2077 "eslint-plugin-import/tsconfig-paths/json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="],
2078
2079 "eslint/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
2080
2081 "wrap-ansi/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
2082
2083 "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
2084
2085 "yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
2086
2087 "yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
2088
2089 "yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
2090 }
2091}
executor/convex/database.test.ts+17−0
@@ -103,3 +103,20 @@ test("anonymous bootstrap links guest account membership", async () => { · 102 unmodified lines
103 expect(again.userId).toBe(first.userId);103 expect(again.userId).toBe(first.userId);
104});104});
105 105
106test("bootstrap honors caller-provided session id", async () => {
107 const t = setup();
108
109 const seeded = await t.mutation(api.database.bootstrapAnonymousSession, {
110 sessionId: "assistant-discord-dev",
111 });
112
113 expect(seeded.sessionId).toBe("assistant-discord-dev");
114
115 const again = await t.mutation(api.database.bootstrapAnonymousSession, {
116 sessionId: "assistant-discord-dev",
117 });
118
119 expect(again.sessionId).toBe("assistant-discord-dev");
120 expect(again.workspaceId).toBe(seeded.workspaceId);
121 expect(again.actorId).toBe(seeded.actorId);
122});
executor/convex/database.ts+115−4
@@ -20,7 +20,78 @@ function optionalFromNormalized(value?: string): string | undefined { · 19 unmodified lines
20 return value;20 return value;
21}21}
22 22
23// NOTE: Canonical version lives in apps/server/src/utils.ts.23function slugify(input: string): string {
24 const slug = input
25 .toLowerCase()
26 .replace(/[^a-z0-9]+/g, "-")
27 .replace(/^-+|-+$/g, "");
28 return slug.length > 0 ? slug : "workspace";
29}
30
31async function ensureUniqueOrganizationSlug(ctx: Pick<MutationCtx, "db">, baseName: string): Promise<string> {
32 const baseSlug = slugify(baseName);
33 const existing = await ctx.db
34 .query("organizations")
35 .withIndex("by_slug", (q) => q.eq("slug", baseSlug))
36 .unique();
37 if (!existing) {
38 return baseSlug;
39 }
40
41 for (let i = 0; i < 20; i += 1) {
42 const candidate = `${baseSlug}-${crypto.randomUUID().slice(0, 6)}`;
43 const collision = await ctx.db
44 .query("organizations")
45 .withIndex("by_slug", (q) => q.eq("slug", candidate))
46 .unique();
47 if (!collision) {
48 return candidate;
49 }
50 }
51
52 return `${baseSlug}-${Date.now()}`;
53}
54
55async function upsertOrganizationMembership(
56 ctx: Pick<MutationCtx, "db">,
57 args: {
58 organizationId: Doc<"organizations">["_id"];
59 accountId: Doc<"accounts">["_id"];
60 role: string;
61 status: string;
62 billable: boolean;
63 now: number;
64 },
65) {
66 const existing = await ctx.db
67 .query("organizationMembers")
68 .withIndex("by_org_account", (q) => q.eq("organizationId", args.organizationId).eq("accountId", args.accountId))
69 .unique();
70
71 if (existing) {
72 await ctx.db.patch(existing._id, {
73 role: args.role,
74 status: args.status,
75 billable: args.billable,
76 joinedAt: args.status === "active" ? (existing.joinedAt ?? args.now) : existing.joinedAt,
77 updatedAt: args.now,
78 });
79 return;
80 }
81
82 await ctx.db.insert("organizationMembers", {
83 organizationId: args.organizationId,
84 accountId: args.accountId,
85 role: args.role,
86 status: args.status,
87 billable: args.billable,
88 joinedAt: args.status === "active" ? args.now : undefined,
89 createdAt: args.now,
90 updatedAt: args.now,
91 });
92}
93
94// NOTE: Canonical version lives in convex/lib/utils.ts.
24// Convex can't import from the server, so this is a local copy.95// Convex can't import from the server, so this is a local copy.
25function asRecord(value: unknown): Record<string, unknown> {96function asRecord(value: unknown): Record<string, unknown> {
26 if (value && typeof value === "object" && !Array.isArray(value)) {97 if (value && typeof value === "object" && !Array.isArray(value)) {
@@ -140,12 +211,29 @@ async function ensureAnonymousIdentity( · 113 unmodified lines
140 .withIndex("by_legacy_workspace_id", (q) => q.eq("legacyWorkspaceId", params.workspaceId))211 .withIndex("by_legacy_workspace_id", (q) => q.eq("legacyWorkspaceId", params.workspaceId))
141 .unique();212 .unique();
142 213
214 let organizationId = workspace?.organizationId;
215
216 if (!organizationId) {
217 const organizationName = workspace?.name ?? "Guest Workspace";
218 const organizationSlug = await ensureUniqueOrganizationSlug(ctx, organizationName);
219 organizationId = await ctx.db.insert("organizations", {
220 slug: organizationSlug,
221 name: organizationName,
222 status: "active",
223 createdByAccountId: account._id,
224 createdAt: now,
225 updatedAt: now,
226 });
227 }
228
143 if (!workspace) {229 if (!workspace) {
144 const workspaceId = await ctx.db.insert("workspaces", {230 const workspaceId = await ctx.db.insert("workspaces", {
231 organizationId,
145 legacyWorkspaceId: params.workspaceId,232 legacyWorkspaceId: params.workspaceId,
146 slug: `guest-${params.workspaceId.slice(-8)}`,233 slug: `guest-${params.workspaceId.slice(-8)}`,
147 name: "Guest Workspace",234 name: "Guest Workspace",
148 kind: "personal",235 kind: "personal",
236 visibility: "private",
149 plan: "free",237 plan: "free",
150 createdByAccountId: account._id,238 createdByAccountId: account._id,
151 createdAt: now,239 createdAt: now,
@@ -155,8 +243,30 @@ async function ensureAnonymousIdentity( · 3 unmodified lines
155 if (!workspace) {243 if (!workspace) {
156 throw new Error("Failed to create anonymous workspace");244 throw new Error("Failed to create anonymous workspace");
157 }245 }
246 } else if (!workspace.organizationId) {
247 await ctx.db.patch(workspace._id, {
248 organizationId,
249 updatedAt: now,
250 });
251 workspace = await ctx.db.get(workspace._id);
252 if (!workspace) {
253 throw new Error("Failed to update anonymous workspace organization");
254 }
158 }255 }
159 256
257 if (!organizationId) {
258 throw new Error("Failed to resolve workspace organization");
259 }
260
261 await upsertOrganizationMembership(ctx, {
262 organizationId,
263 accountId: account._id,
264 role: "owner",
265 status: "active",
266 billable: true,
267 now,
268 });
269
160 let user = await ctx.db270 let user = await ctx.db
161 .query("users")271 .query("users")
162 .withIndex("by_workspace_account", (q) => q.eq("workspaceId", workspace._id).eq("accountId", account._id))272 .withIndex("by_workspace_account", (q) => q.eq("workspaceId", workspace._id).eq("accountId", account._id))
@@ -634,9 +744,10 @@ export const bootstrapAnonymousSession = mutation({ · 471 unmodified lines
634 args: { sessionId: v.optional(v.string()) },744 args: { sessionId: v.optional(v.string()) },
635 handler: async (ctx, args) => {745 handler: async (ctx, args) => {
636 const now = Date.now();746 const now = Date.now();
747 const requestedSessionId = normalizeOptional(args.sessionId);
637 748
638 if (args.sessionId) {749 if (requestedSessionId) {
639 const sessionId = args.sessionId;750 const sessionId = requestedSessionId;
640 const existing = await ctx.db751 const existing = await ctx.db
641 .query("anonymousSessions")752 .query("anonymousSessions")
642 .withIndex("by_session_id", (q) => q.eq("sessionId", sessionId))753 .withIndex("by_session_id", (q) => q.eq("sessionId", sessionId))
@@ -667,7 +778,7 @@ export const bootstrapAnonymousSession = mutation({ · 24 unmodified lines
667 }778 }
668 }779 }
669 780
670 const sessionId = `anon_session_${crypto.randomUUID()}`;781 const sessionId = requestedSessionId || `anon_session_${crypto.randomUUID()}`;
671 const workspaceId = `ws_${crypto.randomUUID()}`;782 const workspaceId = `ws_${crypto.randomUUID()}`;
672 const actorId = `anon_${crypto.randomUUID()}`;783 const actorId = `anon_${crypto.randomUUID()}`;
673 const clientId = "web";784 const clientId = "web";
executor/convex/executor-mcp.e2e.test.ts+164−0
@@ -0,0 +1,164 @@
1import { expect, test } from "bun:test";
2import { convexTest } from "convex-test";
3import { Client } from "@modelcontextprotocol/sdk/client/index.js";
4import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5import { api } from "./_generated/api";
6import schema from "./schema";
7
8function setup() {
9 return convexTest(schema, {
10 "./database.ts": () => import("./database"),
11 "./executor.ts": () => import("./executor"),
12 "./executorNode.ts": () => import("./executorNode"),
13 "./http.ts": () => import("./http"),
14 "./auth.ts": () => import("./auth"),
15 "./_generated/api.js": () => import("./_generated/api.js"),
16 });
17}
18
19function createMcpTransport(t: ReturnType<typeof setup>, workspaceId: string, actorId: string, clientId = "e2e") {
20 const url = new URL("https://executor.test/mcp");
21 url.searchParams.set("workspaceId", workspaceId);
22 url.searchParams.set("actorId", actorId);
23 url.searchParams.set("clientId", clientId);
24
25 return new StreamableHTTPClientTransport(url, {
26 fetch: async (input, init) => {
27 const raw = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
28 const parsed = new URL(raw);
29 const path = `${parsed.pathname}${parsed.search}${parsed.hash}`;
30 return await t.fetch(path, init);
31 },
32 });
33}
34
35async function waitForTaskId(t: ReturnType<typeof setup>, workspaceId: string, timeoutMs = 10_000): Promise<string> {
36 const start = Date.now();
37 while (Date.now() - start < timeoutMs) {
38 const tasks = await t.query(api.database.listTasks, { workspaceId });
39 if (tasks.length > 0) {
40 return tasks[0]!.id;
41 }
42 await Bun.sleep(50);
43 }
44
45 throw new Error("Timed out waiting for created task");
46}
47
48async function waitForPendingApproval(
49 t: ReturnType<typeof setup>,
50 workspaceId: string,
51 toolPath: string,
52 timeoutMs = 10_000,
53): Promise<string> {
54 const start = Date.now();
55 while (Date.now() - start < timeoutMs) {
56 const approvals = await t.query(api.database.listPendingApprovals, { workspaceId });
57 const approval = approvals.find((item) => item.toolPath === toolPath);
58 if (approval) {
59 return approval.id;
60 }
61 await Bun.sleep(50);
62 }
63
64 throw new Error(`Timed out waiting for pending approval on ${toolPath}`);
65}
66
67test("MCP run_code survives delayed approval and completes", async () => {
68 const t = setup();
69 const session = await t.mutation(api.database.bootstrapAnonymousSession, {});
70
71 const client = new Client({ name: "executor-e2e", version: "0.0.1" }, { capabilities: {} });
72 const transport = createMcpTransport(t, session.workspaceId, session.actorId, "e2e-approval-delay");
73
74 try {
75 await client.connect(transport);
76
77 const runCode = client.callTool({
78 name: "run_code",
79 arguments: {
80 code: `return await tools.admin.send_announcement({ channel: "general", message: "hello from convex-test" });`,
81 },
82 });
83
84 const taskId = await waitForTaskId(t, session.workspaceId);
85 const runTask = t.action(api.executorNode.runTask, { taskId });
86
87 const approvalId = await waitForPendingApproval(t, session.workspaceId, "admin.send_announcement");
88
89 await Bun.sleep(16_000);
90
91 await t.mutation(api.executor.resolveApproval, {
92 workspaceId: session.workspaceId,
93 approvalId,
94 decision: "approved",
95 reviewerId: "e2e-reviewer",
96 });
97
98 await runTask;
99
100 const result = (await runCode) as {
101 content: Array<{ type: string; text?: string }>;
102 isError?: boolean;
103 };
104 const text = result.content.find((item) => item.type === "text")?.text ?? "";
105
106 expect(result.isError).toBeFalsy();
107 expect(text).toContain("status: completed");
108 expect(text).toContain("hello from convex-test");
109
110 const task = await t.query(api.database.getTask, { taskId });
111 expect(task?.status).toBe("completed");
112 } finally {
113 await transport.close().catch(() => {});
114 await client.close().catch(() => {});
115 }
116}, 60_000);
117
118test("MCP run_code returns denied after approval denial", async () => {
119 const t = setup();
120 const session = await t.mutation(api.database.bootstrapAnonymousSession, {});
121
122 const client = new Client({ name: "executor-e2e", version: "0.0.1" }, { capabilities: {} });
123 const transport = createMcpTransport(t, session.workspaceId, session.actorId, "e2e-deny");
124
125 try {
126 await client.connect(transport);
127
128 const runCode = client.callTool({
129 name: "run_code",
130 arguments: {
131 code: `return await tools.admin.delete_data({ key: "important" });`,
132 },
133 });
134
135 const taskId = await waitForTaskId(t, session.workspaceId);
136 const runTask = t.action(api.executorNode.runTask, { taskId });
137
138 const approvalId = await waitForPendingApproval(t, session.workspaceId, "admin.delete_data");
139 await t.mutation(api.executor.resolveApproval, {
140 workspaceId: session.workspaceId,
141 approvalId,
142 decision: "denied",
143 reviewerId: "e2e-reviewer",
144 reason: "not allowed",
145 });
146
147 await runTask;
148
149 const result = (await runCode) as {
150 content: Array<{ type: string; text?: string }>;
151 isError?: boolean;
152 };
153 const text = result.content.find((item) => item.type === "text")?.text ?? "";
154
155 expect(result.isError).toBe(true);
156 expect(text).toContain("status: denied");
157
158 const task = await t.query(api.database.getTask, { taskId });
159 expect(task?.status).toBe("denied");
160 } finally {
161 await transport.close().catch(() => {});
162 await client.close().catch(() => {});
163 }
164}, 30_000);
executor/convex/executor.ts+2−2
@@ -2,7 +2,7 @@ import { v } from "convex/values"; · 1 unmodified line
2import { api, internal } from "./_generated/api";2import { api, internal } from "./_generated/api";
3import type { MutationCtx } from "./_generated/server";3import type { MutationCtx } from "./_generated/server";
4import { internalMutation, mutation } from "./_generated/server";4import { internalMutation, mutation } from "./_generated/server";
5import type { ApprovalRecord, TaskRecord } from "../apps/server/src/types";5import type { ApprovalRecord, TaskRecord } from "./lib/types";
6 6
7const DEFAULT_TIMEOUT_MS = 15_000;7const DEFAULT_TIMEOUT_MS = 15_000;
8 8
@@ -76,7 +76,7 @@ export const createTask = mutation({ · 67 unmodified lines
76 },76 },
77 });77 });
78 78
79 await ctx.scheduler.runAfter(0, internal.executorNode.runTask, {79 await ctx.scheduler.runAfter(1, internal.executorNode.runTask, {
80 taskId,80 taskId,
81 });81 });
82 82
executor/convex/executorNode.ts+8−8
@@ -3,16 +3,16 @@ · 2 unmodified lines
3import { v } from "convex/values";3import { v } from "convex/values";
4import { api, internal } from "./_generated/api";4import { api, internal } from "./_generated/api";
5import { action, internalAction } from "./_generated/server";5import { action, internalAction } from "./_generated/server";
6import { InProcessExecutionAdapter } from "../apps/server/src/adapters/in-process-execution-adapter";6import { InProcessExecutionAdapter } from "./lib/adapters/in-process-execution-adapter";
7import { APPROVAL_DENIED_PREFIX } from "../apps/server/src/execution-constants";7import { APPROVAL_DENIED_PREFIX } from "./lib/execution-constants";
8import { runCodeWithAdapter } from "../apps/server/src/runtimes/runtime-core";8import { runCodeWithAdapter } from "./lib/runtimes/runtime-core";
9import { createDiscoverTool } from "../apps/server/src/tool-discovery";9import { createDiscoverTool } from "./lib/tool-discovery";
10import {10import {
11 loadExternalTools,11 loadExternalTools,
12 parseGraphqlOperationPaths,12 parseGraphqlOperationPaths,
13 type ExternalToolSourceConfig,13 type ExternalToolSourceConfig,
14} from "../apps/server/src/tool-sources";14} from "./lib/tool-sources";
15import { DEFAULT_TOOLS } from "../apps/server/src/tools";15import { DEFAULT_TOOLS } from "./lib/tools";
16import type {16import type {
17 AccessPolicyRecord,17 AccessPolicyRecord,
18 CredentialScope,18 CredentialScope,
@@ -26,8 +26,8 @@ import type { · 7 unmodified lines
26 ToolDescriptor,26 ToolDescriptor,
27 ToolSourceRecord,27 ToolSourceRecord,
28 ToolRunContext,28 ToolRunContext,
29} from "../apps/server/src/types";29} from "./lib/types";
30import { asPayload, describeError } from "../apps/server/src/utils";30import { asPayload, describeError } from "./lib/utils";
31 31
32function createApprovalId(): string {32function createApprovalId(): string {
33 return `approval_${crypto.randomUUID()}`;33 return `approval_${crypto.randomUUID()}`;
executor/convex/http.ts+2−2
@@ -3,8 +3,8 @@ import { httpRouter } from "convex/server"; · 2 unmodified lines
3import { api, components, internal } from "./_generated/api";3import { api, components, internal } from "./_generated/api";
4import { httpAction } from "./_generated/server";4import { httpAction } from "./_generated/server";
5import { authKit } from "./auth";5import { authKit } from "./auth";
6import { handleMcpRequest, type McpWorkspaceContext } from "../apps/server/src/mcp-server";6import { handleMcpRequest, type McpWorkspaceContext } from "./lib/mcp-server";
7import type { AnonymousContext, TaskRecord, ToolDescriptor } from "../apps/server/src/types";7import type { AnonymousContext, TaskRecord, ToolDescriptor } from "./lib/types";
8 8
9const http = httpRouter();9const http = httpRouter();
10const internalToken = process.env.EXECUTOR_INTERNAL_TOKEN ?? "executor_internal_local_dev_token";10const internalToken = process.env.EXECUTOR_INTERNAL_TOKEN ?? "executor_internal_local_dev_token";
executor/convex/lib/adapters/in-process-execution-adapter.test.tsrenamed from executor/apps/server/src/adapters/in-process-execution-adapter.test.ts+0−0

File renamed without changes.

executor/convex/lib/adapters/in-process-execution-adapter.tsrenamed from executor/apps/server/src/adapters/in-process-execution-adapter.ts+0−0

File renamed without changes.

executor/convex/lib/events.tsrenamed from executor/apps/server/src/events.ts+0−0

File renamed without changes.

executor/convex/lib/execution-constants.tsrenamed from executor/apps/server/src/execution-constants.ts+0−0

File renamed without changes.

executor/convex/lib/mcp-server.test.tsrenamed from executor/apps/server/src/mcp-server.test.ts+0−0

File renamed without changes.

executor/convex/lib/mcp-server.tsrenamed from executor/apps/server/src/mcp-server.ts+27−11
@@ -1,11 +1,14 @@
1import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";1import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";2import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
3import { z } from "zod";3import { z } from "zod";
4import { getTaskTerminalState } from "./service";
5import { generateToolDeclarations, generateToolInventory, typecheckCode } from "./typechecker";4import { generateToolDeclarations, generateToolInventory, typecheckCode } from "./typechecker";
6import type { LiveTaskEvent } from "./events";5import type { LiveTaskEvent } from "./events";
7import type { AnonymousContext, CreateTaskInput, TaskRecord, ToolDescriptor } from "./types";6import type { AnonymousContext, CreateTaskInput, TaskRecord, ToolDescriptor } from "./types";
8 7
8function getTaskTerminalState(status: string): boolean {
9 return status === "completed" || status === "failed" || status === "timed_out" || status === "denied";
10}
11
9// ---------------------------------------------------------------------------12// ---------------------------------------------------------------------------
10// Service interface13// Service interface
11// ---------------------------------------------------------------------------14// ---------------------------------------------------------------------------
@@ -74,37 +77,48 @@ function waitForTerminalTask( · 62 unmodified lines
74 return new Promise((resolve) => {77 return new Promise((resolve) => {
75 let settled = false;78 let settled = false;
76 let unsubscribe: (() => void) | undefined;79 let unsubscribe: (() => void) | undefined;
80 let poll: ReturnType<typeof setInterval> | undefined;
77 81
78 const done = async () => {82 const done = async () => {
79 if (settled) return;83 if (settled) return;
80 settled = true;84 settled = true;
85 if (poll) clearInterval(poll);
81 unsubscribe?.();86 unsubscribe?.();
82 resolve(await service.getTask(taskId, workspaceId));87 resolve(await service.getTask(taskId, workspaceId));
83 };88 };
84 89
85 const timeout = setTimeout(done, waitTimeoutMs);90 const timeout = setTimeout(done, waitTimeoutMs);
86 91
87 // Check if already terminal before subscribing (race condition guard)92 const checkTask = async () => {
88 service.getTask(taskId, workspaceId).then((task) => {
89 if (settled) return;93 if (settled) return;
94 const task = await service.getTask(taskId, workspaceId);
90 if (task && getTaskTerminalState(task.status)) {95 if (task && getTaskTerminalState(task.status)) {
91 clearTimeout(timeout);96 clearTimeout(timeout);
92 settled = true;97 await done();
93 resolve(task);
94 return;
95 }98 }
99 };
100
101 poll = setInterval(() => {
102 void checkTask();
103 }, 400);
96 104
97 // Subscribe for live events105 // Check if already terminal before subscribing (race condition guard)
106 void checkTask();
107
108 // Subscribe for live events when available; polling remains as fallback.
109 try {
98 unsubscribe = service.subscribe(taskId, (event) => {110 unsubscribe = service.subscribe(taskId, (event) => {
99 const type = typeof event.payload === "object" && event.payload111 const type = typeof event.payload === "object" && event.payload
100 ? (event.payload as Record<string, unknown>).status112 ? (event.payload as Record<string, unknown>).status
101 : undefined;113 : undefined;
102 if (typeof type === "string" && getTaskTerminalState(type)) {114 if (typeof type === "string" && getTaskTerminalState(type)) {
103 clearTimeout(timeout);115 clearTimeout(timeout);
104 done();116 void done();
105 }117 }
106 });118 });
107 });119 } catch {
120 // Ignore subscription errors and rely on polling.
121 }
108 });122 });
109}123}
110 124
@@ -146,6 +160,8 @@ function createRunCodeTool( · 35 unmodified lines
146 structuredContent?: Record<string, unknown>;160 structuredContent?: Record<string, unknown>;
147 isError?: boolean;161 isError?: boolean;
148 }> => {162 }> => {
163 const requestedTimeoutMs = input.timeoutMs ?? 300_000;
164
149 // Resolve context: bound context takes priority, then input, then anonymous165 // Resolve context: bound context takes priority, then input, then anonymous
150 let context: { workspaceId: string; actorId: string; clientId?: string; sessionId?: string };166 let context: { workspaceId: string; actorId: string; clientId?: string; sessionId?: string };
151 167
@@ -201,7 +217,7 @@ function createRunCodeTool( · 49 unmodified lines
201 217
202 const created = await service.createTask({218 const created = await service.createTask({
203 code: input.code,219 code: input.code,
204 timeoutMs: input.timeoutMs,220 timeoutMs: requestedTimeoutMs,
205 runtimeId: input.runtimeId,221 runtimeId: input.runtimeId,
206 metadata: input.metadata,222 metadata: input.metadata,
207 workspaceId: context.workspaceId,223 workspaceId: context.workspaceId,
@@ -223,7 +239,7 @@ function createRunCodeTool( · 15 unmodified lines
223 };239 };
224 }240 }
225 241
226 const waitTimeoutMs = input.resultTimeoutMs ?? Math.max((input.timeoutMs ?? created.task.timeoutMs) + 10_000, 15_000);242 const waitTimeoutMs = input.resultTimeoutMs ?? Math.max(requestedTimeoutMs + 30_000, 120_000);
227 const task = await waitForTerminalTask(service, created.task.id, context.workspaceId, waitTimeoutMs);243 const task = await waitForTerminalTask(service, created.task.id, context.workspaceId, waitTimeoutMs);
228 244
229 if (!task) {245 if (!task) {
executor/convex/lib/runtimes/runtime-core.test.tsrenamed from executor/apps/server/src/runtimes/runtime-core.test.ts+0−0

File renamed without changes.

executor/convex/lib/runtimes/runtime-core.tsrenamed from executor/apps/server/src/runtimes/runtime-core.ts+27−1
@@ -10,6 +10,31 @@ import type { · 9 unmodified lines
10 SandboxExecutionResult,10 SandboxExecutionResult,
11} from "../types";11} from "../types";
12 12
13async function transpileForRuntime(code: string): Promise<string> {
14 let ts: typeof import("typescript");
15 try {
16 ts = await import("typescript");
17 } catch {
18 return code;
19 }
20
21 const result = ts.transpileModule(code, {
22 compilerOptions: {
23 target: ts.ScriptTarget.ES2022,
24 module: ts.ModuleKind.ESNext,
25 },
26 reportDiagnostics: true,
27 });
28
29 if (result.diagnostics && result.diagnostics.length > 0) {
30 const first = result.diagnostics[0];
31 const message = ts.flattenDiagnosticMessageText(first.messageText, "\n");
32 throw new Error(`TypeScript transpile error: ${message}`);
33 }
34
35 return result.outputText || code;
36}
37
13function formatArgs(args: unknown[]): string {38function formatArgs(args: unknown[]): string {
14 return args39 return args
15 .map((value) => {40 .map((value) => {
@@ -121,7 +146,8 @@ export async function runCodeWithAdapter( · 105 unmodified lines
121 },146 },
122 });147 });
123 148
124 const runnerScript = new Script(`(async () => {\n"use strict";\n${request.code}\n})()`);149 const executableCode = await transpileForRuntime(request.code);
150 const runnerScript = new Script(`(async () => {\n"use strict";\n${executableCode}\n})()`);
125 151
126 let timeoutHandle: ReturnType<typeof setTimeout> | undefined;152 let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
127 const timeoutPromise = new Promise<never>((_resolve, reject) => {153 const timeoutPromise = new Promise<never>((_resolve, reject) => {
executor/convex/lib/tool-discovery.tsrenamed from executor/apps/server/src/tool-discovery.ts+0−0

File renamed without changes.

executor/convex/lib/tool-sources.test.tsrenamed from executor/apps/server/src/tool-sources.test.ts+0−0

File renamed without changes.

executor/convex/lib/tool-sources.tsrenamed from executor/apps/server/src/tool-sources.ts+407−74
@@ -2,7 +2,7 @@ import SwaggerParser from "@apidevtools/swagger-parser"; · 1 unmodified line
2import { Client } from "@modelcontextprotocol/sdk/client/index.js";2import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";3import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
4import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";4import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5import { astToString, transformSchemaObject } from "openapi-typescript";5import openapiTS, { astToString } from "openapi-typescript";
6import type { ToolApprovalMode, ToolCredentialSpec, ToolDefinition } from "./types";6import type { ToolApprovalMode, ToolCredentialSpec, ToolDefinition } from "./types";
7import { asRecord } from "./utils";7import { asRecord } from "./utils";
8 8
@@ -61,50 +61,349 @@ function sanitizeSegment(value: string): string { · 52 unmodified lines
61 return cleaned.length > 0 ? cleaned : "default";61 return cleaned.length > 0 ? cleaned : "default";
62}62}
63 63
64// openapi-typescript context for standalone schema conversion64// ── Type generation from OpenAPI specs ──────────────────────────────────────
65function makeTransformCtx() {65//
66 return {66// We use `openapiTS(spec)` — the same thing as `npx openapi-typescript` — to
67 additionalProperties: false,67// generate a full .d.ts from the spec. This handles $ref resolution, circular
68 alphabetize: false,68// references, discriminators, etc. correctly by emitting named type aliases
69 arrayLength: false,69// instead of inlining everything.
70 defaultNonNullable: true,70//
71 discriminators: { refsHandled: [] as string[], objects: {} as Record<string, unknown> },71// From the generated output we extract per-operation type strings. The output
72 emptyObjectsUnknown: false,72// has a predictable structure:
73 enum: false,73//
74 enumValues: false,74// export interface operations {
75 excludeDeprecated: false,75// operationId: {
76 exportType: false,76// parameters: { query: { ... }; path: { ... }; ... };
77 immutable: false,77// requestBody?: { content: { "application/json": { ... } } };
78 indentLv: 0,78// responses: { 200: { content: { "application/json": { ... } } } };
79 pathParamsAsTypes: false,79// };
80 postTransform: undefined,80// }
81 propertiesRequiredByDefault: false,81//
82 redoc: undefined,82// We parse this with TypeScript's compiler API to extract the parameter,
83 silent: true,83// request body, and response types per operation.
84 resolve(_ref: string) { return undefined as unknown; },84
85 };85/**
86 * Generate TypeScript types for an entire OpenAPI spec using openapi-typescript.
87 * Returns a map of operationId → { argsType, returnsType } strings.
88 *
89 * Falls back to the hand-rolled type hint generator on failure (e.g. Swagger 2.0
90 * specs, broken $refs).
91 */
92async function generateOpenApiTypes(
93 spec: string | Record<string, unknown>,
94): Promise<ExtractedTypes | null> {
95 try {
96 const input = typeof spec === "string" ? new URL(spec) : (spec as never);
97 const ast = await openapiTS(input, { silent: true });
98 const dts = astToString(ast);
99 return extractOperationTypes(dts);
100 } catch (error) {
101 const msg = error instanceof Error ? error.message : String(error);
102 console.warn(`[executor] openapi-typescript failed, using fallback types: ${msg}`);
103 return null;
104 }
105}
106
107/** Result of extracting types from a generated .d.ts */
108interface ExtractedTypes {
109 /** Per-operation type strings (operationId → args/returns) */
110 operations: Map<string, { argsType: string; returnsType: string }>;
111 /**
112 * Schema type aliases referenced by operations. These need to be included
113 * in the typechecker context for the operation types to be valid.
114 * e.g. `{ "Account": "{ id: string; type: string; ... }" }`
115 */
116 schemas: Map<string, string>;
86}117}
87 118
88/**119/**
89 * Convert a JSON Schema to a TypeScript type string using openapi-typescript.120 * Parse the generated .d.ts to extract per-operation args/returns type strings.
90 * Handles allOf, oneOf, enums, nullable, additionalProperties, etc.121 * Resolves `components["schemas"]["X"]` references into named type aliases
91 * Falls back to the simple hand-rolled version on error.122 * so the extracted types are self-contained.
92 */123 */
93function jsonSchemaToTypeString(schema: unknown): string {124function extractOperationTypes(dts: string): ExtractedTypes {
94 if (!schema || typeof schema !== "object") return "unknown";125 let ts: typeof import("typescript");
95 try {126 try {
96 const node = transformSchemaObject(schema as never, {127 ts = require("typescript");
97 path: "#",
98 ctx: makeTransformCtx() as never,
99 });
100 const result = astToString(node).trim();
101 return result || "unknown";
102 } catch {128 } catch {
103 return jsonSchemaTypeHintFallback(schema);129 return { operations: new Map(), schemas: new Map() };
104 }130 }
131
132 const sourceFile = ts.createSourceFile("openapi.d.ts", dts, ts.ScriptTarget.ESNext, true);
133 const operations = new Map<string, { argsType: string; returnsType: string }>();
134
135 // Find the `operations` interface
136 let operationsInterface: import("typescript").InterfaceDeclaration | undefined;
137 for (const stmt of sourceFile.statements) {
138 if (ts.isInterfaceDeclaration(stmt) && stmt.name.text === "operations") {
139 operationsInterface = stmt;
140 break;
141 }
142 }
143 if (!operationsInterface) return { operations, schemas: new Map() };
144
145 // Extract raw per-operation types (may contain components["schemas"]["..."] refs)
146 for (const member of operationsInterface.members) {
147 if (!ts.isPropertySignature(member) || !member.name) continue;
148 const operationId = ts.isStringLiteral(member.name)
149 ? member.name.text
150 : ts.isIdentifier(member.name)
151 ? member.name.text
152 : undefined;
153 if (!operationId || !member.type || !ts.isTypeLiteralNode(member.type)) continue;
154
155 const opType = member.type;
156 const argsType = extractArgsType(ts, opType, sourceFile);
157 const returnsType = extractReturnsType(ts, opType, sourceFile);
158
159 operations.set(operationId, { argsType, returnsType });
160 }
161
162 // Collect all referenced schema names from the operation type strings
163 const referencedSchemas = new Set<string>();
164 const refPattern = /components\["schemas"\]\["([^"]+)"\]/g;
165 for (const { argsType, returnsType } of operations.values()) {
166 for (const match of argsType.matchAll(refPattern)) referencedSchemas.add(match[1]!);
167 for (const match of returnsType.matchAll(refPattern)) referencedSchemas.add(match[1]!);
168 }
169
170 // Build schema lookup from the components interface in the .d.ts
171 const schemaTypeMap = new Map<string, string>();
172 if (referencedSchemas.size > 0) {
173 const schemasNode = findComponentsSchemas(ts, sourceFile);
174 if (schemasNode) {
175 // First pass: extract all schema type texts (we need them for transitive refs)
176 const allSchemaTexts = new Map<string, string>();
177 for (const m of schemasNode.members) {
178 if (!ts.isPropertySignature(m) || !m.name || !m.type) continue;
179 const name = ts.isIdentifier(m.name) ? m.name.text : ts.isStringLiteral(m.name) ? m.name.text : undefined;
180 if (!name) continue;
181 allSchemaTexts.set(name, m.type.getText(sourceFile).replace(/\s+/g, " ").trim());
182 }
183
184 // Resolve referenced schemas (one level deep — resolve transitive refs too)
185 const toResolve = new Set(referencedSchemas);
186 const resolved = new Set<string>();
187 while (toResolve.size > 0) {
188 const next = toResolve.values().next().value!;
189 toResolve.delete(next);
190 if (resolved.has(next)) continue;
191 resolved.add(next);
192
193 const typeText = allSchemaTexts.get(next);
194 if (!typeText) continue;
195
196 schemaTypeMap.set(next, typeText);
197
198 // Find transitive refs in this schema — but cap total schemas to avoid blowup
199 if (resolved.size < 200) {
200 for (const match of typeText.matchAll(refPattern)) {
201 if (!resolved.has(match[1]!)) toResolve.add(match[1]!);
202 }
203 }
204 }
205 }
206 }
207
208 // Replace components["schemas"]["X"] with the schema name as a type alias
209 // in all operation type strings, and collect the needed schema definitions
210 const schemas = new Map<string, string>();
211 const schemaNameMap = new Map<string, string>(); // "checkout.session" → "CheckoutSession"
212
213 for (const schemaName of schemaTypeMap.keys()) {
214 // Convert schema name to a valid TS identifier: "checkout.session" → "CheckoutSession"
215 const tsName = schemaName
216 .split(/[._-]/)
217 .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
218 .join("");
219 schemaNameMap.set(schemaName, tsName);
220 }
221
222 // Replace refs in schema definitions themselves (transitive refs)
223 for (const [schemaName, typeText] of schemaTypeMap) {
224 const tsName = schemaNameMap.get(schemaName)!;
225 let resolved = typeText;
226 for (const [refName, refTsName] of schemaNameMap) {
227 resolved = resolved.replaceAll(`components["schemas"]["${refName}"]`, refTsName);
228 }
229 // Any remaining unresolved refs → unknown
230 resolved = resolved.replace(refPattern, "unknown");
231 schemas.set(tsName, resolved);
232 }
233
234 // Replace refs in operation type strings
235 for (const [opId, types] of operations) {
236 let { argsType, returnsType } = types;
237 for (const [refName, refTsName] of schemaNameMap) {
238 argsType = argsType.replaceAll(`components["schemas"]["${refName}"]`, refTsName);
239 returnsType = returnsType.replaceAll(`components["schemas"]["${refName}"]`, refTsName);
240 }
241 // Any remaining unresolved refs → unknown
242 argsType = argsType.replace(refPattern, "unknown");
243 returnsType = returnsType.replace(refPattern, "unknown");
244 operations.set(opId, { argsType, returnsType });
245 }
246
247 // Also resolve components["parameters"]["X"] refs to unknown (less common)
248 const paramRefPattern = /components\["parameters"\]\["[^"]+"\]/g;
249 for (const [opId, types] of operations) {
250 operations.set(opId, {
251 argsType: types.argsType.replace(paramRefPattern, "unknown"),
252 returnsType: types.returnsType.replace(paramRefPattern, "unknown"),
253 });
254 }
255
256 return { operations, schemas };
105}257}
106 258
107/** Simple fallback for when openapi-typescript can't handle the schema */259/** Find the components.schemas type literal in the .d.ts AST */
260function findComponentsSchemas(
261 ts: typeof import("typescript"),
262 sourceFile: import("typescript").SourceFile,
263): import("typescript").TypeLiteralNode | undefined {
264 for (const stmt of sourceFile.statements) {
265 if (!ts.isInterfaceDeclaration(stmt) || stmt.name.text !== "components") continue;
266 for (const member of stmt.members) {
267 if (!ts.isPropertySignature(member) || !member.name) continue;
268 const name = ts.isIdentifier(member.name) ? member.name.text : undefined;
269 if (name === "schemas" && member.type && ts.isTypeLiteralNode(member.type)) {
270 return member.type;
271 }
272 }
273 }
274 return undefined;
275}
276
277function extractArgsType(
278 ts: typeof import("typescript"),
279 opType: import("typescript").TypeLiteralNode,
280 sourceFile: import("typescript").SourceFile,
281): string {
282 const parts: string[] = [];
283
284 // Extract parameters (query, path, header)
285 const paramsMember = findMember(ts, opType, "parameters");
286 if (paramsMember?.type && ts.isTypeLiteralNode(paramsMember.type)) {
287 for (const locationMember of paramsMember.type.members) {
288 if (!ts.isPropertySignature(locationMember) || !locationMember.name) continue;
289 const locName = ts.isIdentifier(locationMember.name) ? locationMember.name.text : "";
290 if (!["query", "path", "header"].includes(locName)) continue;
291 if (!locationMember.type || !ts.isTypeLiteralNode(locationMember.type)) continue;
292
293 for (const param of locationMember.type.members) {
294 if (!ts.isPropertySignature(param) || !param.name || !param.type) continue;
295 const paramName = ts.isIdentifier(param.name)
296 ? param.name.text
297 : ts.isStringLiteral(param.name)
298 ? param.name.text
299 : undefined;
300 if (!paramName) continue;
301 const optional = param.questionToken ? "?" : "";
302 const typeText = param.type.getText(sourceFile).replace(/\s+/g, " ").trim();
303 parts.push(`${paramName}${optional}: ${typeText}`);
304 }
305 }
306 }
307
308 // Extract requestBody content
309 const bodyMember = findMember(ts, opType, "requestBody");
310 if (bodyMember?.type) {
311 const bodyTypeNode = ts.isTypeLiteralNode(bodyMember.type) ? bodyMember.type : null;
312 if (bodyTypeNode) {
313 const contentMember = findMember(ts, bodyTypeNode, "content");
314 if (contentMember?.type && ts.isTypeLiteralNode(contentMember.type)) {
315 // Look for application/json or */* or first content type
316 for (const ct of contentMember.type.members) {
317 if (!ts.isPropertySignature(ct) || !ct.name || !ct.type) continue;
318 const ctName = ts.isStringLiteral(ct.name) ? ct.name.text : ts.isIdentifier(ct.name) ? ct.name.text : "";
319 if (ctName === "application/json" || ctName === "*/*") {
320 // The body type — try to merge its properties into the args
321 if (ts.isTypeLiteralNode(ct.type)) {
322 for (const bodyProp of ct.type.members) {
323 if (!ts.isPropertySignature(bodyProp) || !bodyProp.name || !bodyProp.type) continue;
324 const propName = ts.isIdentifier(bodyProp.name)
325 ? bodyProp.name.text
326 : ts.isStringLiteral(bodyProp.name)
327 ? bodyProp.name.text
328 : undefined;
329 if (!propName) continue;
330 const optional = bodyProp.questionToken ? "?" : "";
331 const typeText = bodyProp.type.getText(sourceFile).replace(/\s+/g, " ").trim();
332 parts.push(`${propName}${optional}: ${typeText}`);
333 }
334 } else {
335 // Non-literal body type (e.g. components["schemas"]["..."]) — inline as `body`
336 const typeText = ct.type.getText(sourceFile).replace(/\s+/g, " ").trim();
337 if (typeText && typeText !== "never") {
338 parts.push(`body: ${typeText}`);
339 }
340 }
341 break;
342 }
343 }
344 }
345 }
346 }
347
348 if (parts.length === 0) return "Record<string, unknown>";
349 return `{ ${parts.join("; ")} }`;
350}
351
352function extractReturnsType(
353 ts: typeof import("typescript"),
354 opType: import("typescript").TypeLiteralNode,
355 sourceFile: import("typescript").SourceFile,
356): string {
357 const responsesMember = findMember(ts, opType, "responses");
358 if (!responsesMember?.type || !ts.isTypeLiteralNode(responsesMember.type)) return "unknown";
359
360 // Find the first 2xx response
361 for (const resp of responsesMember.type.members) {
362 if (!ts.isPropertySignature(resp) || !resp.name || !resp.type) continue;
363 const status = ts.isNumericLiteral(resp.name)
364 ? resp.name.text
365 : ts.isStringLiteral(resp.name)
366 ? resp.name.text
367 : ts.isIdentifier(resp.name)
368 ? resp.name.text
369 : "";
370 if (!status.startsWith("2")) continue;
371 if (!ts.isTypeLiteralNode(resp.type)) continue;
372
373 const contentMember = findMember(ts, resp.type, "content");
374 if (!contentMember?.type || !ts.isTypeLiteralNode(contentMember.type)) continue;
375
376 for (const ct of contentMember.type.members) {
377 if (!ts.isPropertySignature(ct) || !ct.name || !ct.type) continue;
378 const ctName = ts.isStringLiteral(ct.name) ? ct.name.text : ts.isIdentifier(ct.name) ? ct.name.text : "";
379 if (ctName === "application/json" || ctName === "*/*") {
380 const typeText = ct.type.getText(sourceFile).replace(/\s+/g, " ").trim();
381 return typeText || "unknown";
382 }
383 }
384 }
385
386 return "unknown";
387}
388
389function findMember(
390 ts: typeof import("typescript"),
391 typeLiteral: import("typescript").TypeLiteralNode,
392 name: string,
393): import("typescript").PropertySignature | undefined {
394 for (const member of typeLiteral.members) {
395 if (!ts.isPropertySignature(member) || !member.name) continue;
396 const memberName = ts.isIdentifier(member.name)
397 ? member.name.text
398 : ts.isStringLiteral(member.name)
399 ? member.name.text
400 : undefined;
401 if (memberName === name) return member;
402 }
403 return undefined;
404}
405
406/** Simple depth-limited type hint generator for schemas (used as fallback) */
108function jsonSchemaTypeHintFallback(schema: unknown, depth = 0): string {407function jsonSchemaTypeHintFallback(schema: unknown, depth = 0): string {
109 if (!schema || typeof schema !== "object") return "unknown";408 if (!schema || typeof schema !== "object") return "unknown";
110 if (depth > 4) return "unknown";409 if (depth > 4) return "unknown";
@@ -231,7 +530,7 @@ async function loadMcpTools(config: McpToolSourceConfig): Promise<ToolDefinition · 120 unmodified lines
231 approval: config.overrides?.[toolName]?.approval ?? config.defaultApproval ?? "auto",530 approval: config.overrides?.[toolName]?.approval ?? config.defaultApproval ?? "auto",
232 description: String(tool.description ?? `MCP tool ${toolName}`),531 description: String(tool.description ?? `MCP tool ${toolName}`),
233 metadata: {532 metadata: {
234 argsType: jsonSchemaToTypeString(inputSchema),533 argsType: jsonSchemaTypeHintFallback(inputSchema),
235 returnsType: "unknown",534 returnsType: "unknown",
236 },535 },
237 run: async (input: unknown) => {536 run: async (input: unknown) => {
@@ -342,10 +641,16 @@ function buildOpenApiUrl( · 104 unmodified lines
342}641}
343 642
344async function loadOpenApiTools(config: OpenApiToolSourceConfig): Promise<ToolDefinition[]> {643async function loadOpenApiTools(config: OpenApiToolSourceConfig): Promise<ToolDefinition[]> {
345 const api = (await (SwaggerParser as unknown as {644 // Run two things concurrently:
346 dereference(spec: unknown): Promise<unknown>;645 // 1. Parse the spec structure (bundle resolves external $refs but keeps internal ones)
347 }).dereference(config.spec)) as Record<string, unknown>;646 // 2. Generate proper TypeScript types via openapiTS (handles circular refs correctly)
348 const servers = Array.isArray(api.servers) ? (api.servers as Array<{ url?: unknown }>) : [];647 const [bundled, typeMap] = await Promise.all([
648 (SwaggerParser as unknown as { bundle(spec: unknown): Promise<unknown> }).bundle(config.spec)
649 .then((api) => api as Record<string, unknown>),
650 generateOpenApiTypes(config.spec),
651 ]);
652
653 const servers = Array.isArray(bundled.servers) ? (bundled.servers as Array<{ url?: unknown }>) : [];
349 const baseUrl = config.baseUrl ?? String(servers[0]?.url ?? "");654 const baseUrl = config.baseUrl ?? String(servers[0]?.url ?? "");
350 if (!baseUrl) {655 if (!baseUrl) {
351 throw new Error(`OpenAPI source ${config.name} has no base URL (set baseUrl)`);656 throw new Error(`OpenAPI source ${config.name} has no base URL (set baseUrl)`);
@@ -354,9 +659,16 @@ async function loadOpenApiTools(config: OpenApiToolSourceConfig): Promise<ToolDe · 2 unmodified lines
354 const authHeaders = buildStaticAuthHeaders(config.auth);659 const authHeaders = buildStaticAuthHeaders(config.auth);
355 const sourceKey = `openapi:${config.name}`;660 const sourceKey = `openapi:${config.name}`;
356 const credentialSpec = buildCredentialSpec(sourceKey, config.auth);661 const credentialSpec = buildCredentialSpec(sourceKey, config.auth);
357 const paths = asRecord(api.paths);662 const paths = asRecord(bundled.paths);
358 const tools: ToolDefinition[] = [];663 const tools: ToolDefinition[] = [];
359 664
665 // Schema type aliases referenced by operations — stored on the first tool only
666 // to avoid duplicating hundreds of KB across every tool from this source.
667 const schemaTypes = typeMap?.schemas.size
668 ? Object.fromEntries(typeMap.schemas)
669 : undefined;
670 let schemaTypesEmitted = false;
671
360 const methods = ["get", "post", "put", "delete", "patch", "head", "options"] as const;672 const methods = ["get", "post", "put", "delete", "patch", "head", "options"] as const;
361 const readMethods = new Set(["get", "head", "options"]);673 const readMethods = new Set(["get", "head", "options"]);
362 674
@@ -386,38 +698,52 @@ async function loadOpenApiTools(config: OpenApiToolSourceConfig): Promise<ToolDe · 23 unmodified lines
386 schema: asRecord(entry.schema),698 schema: asRecord(entry.schema),
387 }));699 }));
388 700
389 const requestBody = asRecord(operation.requestBody);701 // Use openapiTS-generated types if available, otherwise fall back to schema hints
390 const requestBodyContent = asRecord(requestBody.content);702 const generatedTypes = typeMap?.operations.get(operationIdRaw);
391 const requestBodySchema = asRecord(703 let argsType: string;
392 asRecord(requestBodyContent["application/json"])["schema"] ??704 let returnsType: string;
393 asRecord(requestBodyContent["*/*"])["schema"],705
394 );706 if (generatedTypes) {
395 707 argsType = generatedTypes.argsType;
396 const responses = asRecord(operation.responses);708 returnsType = generatedTypes.returnsType;
397 let responseSchema: Record<string, unknown> = {};709 } else {
398 for (const [status, responseValue] of Object.entries(responses)) {710 // Fallback: build types from the bundled schema using the depth-limited hint generator
399 if (!status.startsWith("2")) continue;711 const requestBody = asRecord(operation.requestBody);
400 const responseContent = asRecord(asRecord(responseValue).content);712 const requestBodyContent = asRecord(requestBody.content);
401 responseSchema = asRecord(713 const requestBodySchema = asRecord(
402 asRecord(responseContent["application/json"])["schema"] ??714 asRecord(requestBodyContent["application/json"])["schema"] ??
403 asRecord(responseContent["*/*"])["schema"],715 asRecord(requestBodyContent["*/*"])["schema"],
404 );716 );
405 if (Object.keys(responseSchema).length > 0) break;
406 }
407 717
408 const combinedSchema: JsonSchema = {718 const responses = asRecord(operation.responses);
409 type: "object",719 let responseSchema: Record<string, unknown> = {};
410 properties: {720 for (const [status, responseValue] of Object.entries(responses)) {
411 ...Object.fromEntries(parameters.map((param) => [param.name, param.schema])),721 if (!status.startsWith("2")) continue;
412 ...asRecord(requestBodySchema.properties),722 const responseContent = asRecord(asRecord(responseValue).content);
413 },723 responseSchema = asRecord(
414 required: [724 asRecord(responseContent["application/json"])["schema"] ??
415 ...parameters.filter((param) => param.required).map((param) => param.name),725 asRecord(responseContent["*/*"])["schema"],
416 ...((Array.isArray(requestBodySchema.required)726 );
417 ? requestBodySchema.required.filter((item): item is string => typeof item === "string")727 if (Object.keys(responseSchema).length > 0) break;
418 : []) as string[]),728 }
419 ],729
420 };730 const combinedSchema: JsonSchema = {
731 type: "object",
732 properties: {
733 ...Object.fromEntries(parameters.map((param) => [param.name, param.schema])),
734 ...asRecord(requestBodySchema.properties),
735 },
736 required: [
737 ...parameters.filter((param) => param.required).map((param) => param.name),
738 ...((Array.isArray(requestBodySchema.required)
739 ? requestBodySchema.required.filter((item): item is string => typeof item === "string")
740 : []) as string[]),
741 ],
742 };
743
744 argsType = jsonSchemaTypeHintFallback(combinedSchema);
745 returnsType = jsonSchemaTypeHintFallback(responseSchema);
746 }
421 747
422 const approval = config.overrides?.[operationIdRaw]?.approval748 const approval = config.overrides?.[operationIdRaw]?.approval
423 ?? (readMethods.has(method)749 ?? (readMethods.has(method)
@@ -430,8 +756,10 @@ async function loadOpenApiTools(config: OpenApiToolSourceConfig): Promise<ToolDe · 6 unmodified lines
430 approval,756 approval,
431 description: String(operation.summary ?? operation.description ?? `${method.toUpperCase()} ${pathTemplate}`),757 description: String(operation.summary ?? operation.description ?? `${method.toUpperCase()} ${pathTemplate}`),
432 metadata: {758 metadata: {
433 argsType: jsonSchemaToTypeString(combinedSchema),759 argsType,
434 returnsType: jsonSchemaToTypeString(responseSchema),760 returnsType,
761 // Only attach schemas to the first tool to avoid duplicating hundreds of KB
762 ...(schemaTypes && !schemaTypesEmitted ? { schemaTypes } : {}),
435 },763 },
436 credential: credentialSpec,764 credential: credentialSpec,
437 run: async (input: unknown, context) => {765 run: async (input: unknown, context) => {
@@ -461,6 +789,11 @@ async function loadOpenApiTools(config: OpenApiToolSourceConfig): Promise<ToolDe · 23 unmodified lines
461 return await response.text();789 return await response.text();
462 },790 },
463 });791 });
792
793 // Mark schemas as emitted so subsequent tools from this source don't duplicate them
794 if (schemaTypes && !schemaTypesEmitted) {
795 schemaTypesEmitted = true;
796 }
464 }797 }
465 }798 }
466 799
executor/convex/lib/tools.tsrenamed from executor/apps/server/src/tools.ts+0−0

File renamed without changes.

executor/convex/lib/typechecker.test.tsrenamed from executor/apps/server/src/typechecker.test.ts+95−0
@@ -248,3 +248,98 @@ return { sum: sum.result, sent: announcement.sent, time: time.unix }; · 247 unmodified lines
248 expect(result.ok).toBe(true);248 expect(result.ok).toBe(true);
249 });249 });
250});250});
251
252// ---------------------------------------------------------------------------
253// schemaTypes integration — verifies that schema type aliases are emitted and
254// correctly used by the typechecker
255// ---------------------------------------------------------------------------
256
257describe("typecheckCode with schemaTypes", () => {
258 const CUSTOMER_SCHEMA_TOOL: ToolDescriptor = {
259 path: "stripe.customers.create",
260 description: "Create a customer",
261 approval: "auto",
262 argsType: "{ name: string; email: string }",
263 returnsType: "Customer",
264 // Only the first tool from a source carries schemaTypes
265 schemaTypes: {
266 Customer: "{ id: string; name: string; email: string; subscriptions: Subscription[] }",
267 Subscription: "{ id: string; status: string; plan: Plan }",
268 Plan: "{ id: string; amount: number; currency: string }",
269 },
270 };
271
272 const CUSTOMER_GET_TOOL: ToolDescriptor = {
273 path: "stripe.customers.get",
274 description: "Get a customer",
275 approval: "auto",
276 argsType: "{ id: string }",
277 returnsType: "Customer",
278 // Subsequent tools do NOT carry schemaTypes (deduplication)
279 };
280
281 const STRIPE_TOOLS = [CUSTOMER_SCHEMA_TOOL, CUSTOMER_GET_TOOL];
282
283 test("schema types are emitted in declarations", () => {
284 const result = generateToolDeclarations(STRIPE_TOOLS);
285 expect(result).toContain("type Customer =");
286 expect(result).toContain("type Subscription =");
287 expect(result).toContain("type Plan =");
288 // Declarations should come before the tools declaration
289 const schemaIdx = result.indexOf("type Customer =");
290 const toolsIdx = result.indexOf("declare const tools:");
291 expect(schemaIdx).toBeLessThan(toolsIdx);
292 });
293
294 test("code using schema return types typechecks correctly", () => {
295 const decl = generateToolDeclarations(STRIPE_TOOLS);
296 const result = typecheckCode(
297 `const customer = await tools.stripe.customers.create({ name: "John", email: "john@test.com" });
298 const id: string = customer.id;
299 const subs: Subscription[] = customer.subscriptions;
300 const plan: Plan = subs[0].plan;
301 return plan.amount;`,
302 decl,
303 );
304 expect(result.ok).toBe(true);
305 expect(result.errors).toHaveLength(0);
306 });
307
308 test("wrong property access on schema type produces errors", () => {
309 const decl = generateToolDeclarations(STRIPE_TOOLS);
310 const result = typecheckCode(
311 `const customer = await tools.stripe.customers.get({ id: "cus_123" });
312 return customer.nonexistent_field;`,
313 decl,
314 );
315 expect(result.ok).toBe(false);
316 expect(result.errors.some((e) => e.includes("nonexistent_field"))).toBe(true);
317 });
318
319 test("transitive schema types are available (Subscription, Plan)", () => {
320 const decl = generateToolDeclarations(STRIPE_TOOLS);
321 const result = typecheckCode(
322 `const customer = await tools.stripe.customers.get({ id: "cus_123" });
323 const sub = customer.subscriptions[0];
324 const status: string = sub.status;
325 const amount: number = sub.plan.amount;
326 const currency: string = sub.plan.currency;
327 return { status, amount, currency };`,
328 decl,
329 );
330 expect(result.ok).toBe(true);
331 expect(result.errors).toHaveLength(0);
332 });
333
334 test("wrong type on schema property produces errors", () => {
335 const decl = generateToolDeclarations(STRIPE_TOOLS);
336 const result = typecheckCode(
337 `const customer = await tools.stripe.customers.get({ id: "cus_123" });
338 const amount: string = customer.subscriptions[0].plan.amount;`,
339 decl,
340 );
341 expect(result.ok).toBe(false);
342 // amount is number, assigning to string should fail
343 expect(result.errors.some((e) => e.includes("number") || e.includes("string"))).toBe(true);
344 });
345});
executor/convex/lib/typechecker.tsrenamed from executor/apps/server/src/typechecker.ts+20−1
@@ -21,6 +21,18 @@ import type { ToolDescriptor } from "./types"; · 20 unmodified lines
21 * and nested into a type tree.21 * and nested into a type tree.
22 */22 */
23export function generateToolDeclarations(tools: ToolDescriptor[]): string {23export function generateToolDeclarations(tools: ToolDescriptor[]): string {
24 // Collect all schema type aliases from all tools (deduplicated by name)
25 const allSchemas = new Map<string, string>();
26 for (const tool of tools) {
27 if (tool.schemaTypes) {
28 for (const [name, type] of Object.entries(tool.schemaTypes)) {
29 if (!allSchemas.has(name)) {
30 allSchemas.set(name, type);
31 }
32 }
33 }
34 }
35
24 // Build a nested tree from flat tool paths36 // Build a nested tree from flat tool paths
25 interface TreeNode {37 interface TreeNode {
26 children: Map<string, TreeNode>;38 children: Map<string, TreeNode>;
@@ -63,7 +75,14 @@ export function generateToolDeclarations(tools: ToolDescriptor[]): string { · 36 unmodified lines
63 return lines.join("\n");75 return lines.join("\n");
64 }76 }
65 77
66 return `declare const tools: {\n${renderNode(root, 1)}\n};`;78 // Emit schema type aliases before the tools declaration so they're in scope
79 const schemaLines: string[] = [];
80 for (const [name, type] of allSchemas) {
81 schemaLines.push(`type ${name} = ${type};`);
82 }
83
84 const schemaBlock = schemaLines.length > 0 ? schemaLines.join("\n") + "\n" : "";
85 return `${schemaBlock}declare const tools: {\n${renderNode(root, 1)}\n};`;
67}86}
68 87
69/**88/**
executor/convex/lib/types.tsrenamed from executor/apps/server/src/types.ts+2−0
@@ -109,6 +109,8 @@ export interface ToolRunContext { · 108 unmodified lines
109export interface ToolTypeMetadata {109export interface ToolTypeMetadata {
110 argsType?: string;110 argsType?: string;
111 returnsType?: string;111 returnsType?: string;
112 /** Schema type aliases needed by argsType/returnsType (e.g. `{ "Account": "{ id: string; ... }" }`) */
113 schemaTypes?: Record<string, string>;
112}114}
113 115
114export interface ToolDefinition {116export interface ToolDefinition {
executor/convex/lib/utils.tsrenamed from executor/apps/server/src/utils.ts+0−0

File renamed without changes.

executor/convex/schema.ts+2−0
@@ -40,6 +40,7 @@ export default defineSchema({ · 39 unmodified lines
40 .index("by_slug", ["slug"]),40 .index("by_slug", ["slug"]),
41 41
42 organizations: defineTable({42 organizations: defineTable({
43 workosOrgId: v.optional(v.string()),
43 slug: v.string(),44 slug: v.string(),
44 name: v.string(),45 name: v.string(),
45 status: v.string(),46 status: v.string(),
@@ -47,6 +48,7 @@ export default defineSchema({ · 1 unmodified line
47 createdAt: v.number(),48 createdAt: v.number(),
48 updatedAt: v.number(),49 updatedAt: v.number(),
49 })50 })
51 .index("by_workos_org_id", ["workosOrgId"])
50 .index("by_slug", ["slug"])52 .index("by_slug", ["slug"])
51 .index("by_status_created", ["status", "createdAt"]),53 .index("by_status_created", ["status", "createdAt"]),
52 54
executor/package.json+3−4
@@ -7,12 +7,11 @@ · 6 unmodified lines
7 "packages/*"7 "packages/*"
8 ],8 ],
9 "scripts": {9 "scripts": {
10 "dev": "bun run --cwd apps/server dev",10 "dev": "bun run dev:convex",
11 "dev:worker": "bun run --cwd apps/server worker",
12 "dev:convex": "bunx convex dev",11 "dev:convex": "bunx convex dev",
13 "dev:web": "bun run --cwd apps/web dev",12 "dev:web": "bun run --cwd apps/web dev",
14 "dev:all": "bun run dev:convex & bun run dev & bun run dev:worker & bun run dev:web",13 "dev:all": "bun run dev:convex & bun run dev:web",
15 "start": "bun run --cwd apps/server start",14 "start": "bun run dev:convex",
16 "convex:codegen": "bunx convex codegen",15 "convex:codegen": "bunx convex codegen",
17 "test": "bun test",16 "test": "bun test",
18 "typecheck": "bunx tsc --noEmit -p tsconfig.json"17 "typecheck": "bunx tsc --noEmit -p tsconfig.json"
executor/packages/contracts/src/index.ts+2−0
@@ -108,6 +108,8 @@ export interface ToolDescriptor { · 107 unmodified lines
108 source?: string;108 source?: string;
109 argsType?: string;109 argsType?: string;
110 returnsType?: string;110 returnsType?: string;
111 /** Schema type aliases needed by argsType/returnsType (shared across tools from same source) */
112 schemaTypes?: Record<string, string>;
111}113}
112 114
113export interface AnonymousContext {115export interface AnonymousContext {