From 63cef16adf502ebadf5bf4e78725d886d57973d3 Mon Sep 17 00:00:00 2001 From: Maky <65879341+makyinmars@users.noreply.github.com> Date: Mon, 2 Feb 2026 02:05:38 -0500 Subject: [PATCH] adding vercel sandbox with examples and docs (#47) --- docs/deploy/index.mdx | 3 + docs/deploy/vercel.mdx | 91 +++++++++ docs/docs.json | 1 + examples/vercel/package.json | 20 ++ examples/vercel/src/vercel.ts | 87 ++++++++ examples/vercel/tests/vercel.test.ts | 28 +++ examples/vercel/tsconfig.json | 24 +++ pnpm-lock.yaml | 292 ++++++++++++++++++++++++--- 8 files changed, 517 insertions(+), 29 deletions(-) create mode 100644 docs/deploy/vercel.mdx create mode 100644 examples/vercel/package.json create mode 100644 examples/vercel/src/vercel.ts create mode 100644 examples/vercel/tests/vercel.test.ts create mode 100644 examples/vercel/tsconfig.json diff --git a/docs/deploy/index.mdx b/docs/deploy/index.mdx index 8b29c30..90c9226 100644 --- a/docs/deploy/index.mdx +++ b/docs/deploy/index.mdx @@ -12,6 +12,9 @@ icon: "server" Deploy inside an E2B sandbox with network access. + + Deploy inside a Vercel Sandbox with port forwarding. + Run in a Daytona workspace with port forwarding. diff --git a/docs/deploy/vercel.mdx b/docs/deploy/vercel.mdx new file mode 100644 index 0000000..be2bec0 --- /dev/null +++ b/docs/deploy/vercel.mdx @@ -0,0 +1,91 @@ +--- +title: "Vercel" +description: "Deploy the daemon inside a Vercel Sandbox." +--- + +## Prerequisites + +- `VERCEL_OIDC_TOKEN` or `VERCEL_ACCESS_TOKEN` environment variable +- `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` for the coding agents + +## TypeScript Example + +```typescript +import { Sandbox } from "@vercel/sandbox"; +import { SandboxAgent } from "sandbox-agent"; + +// Pass API keys to the sandbox +const envs: Record = {}; +if (process.env.ANTHROPIC_API_KEY) envs.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; +if (process.env.OPENAI_API_KEY) envs.OPENAI_API_KEY = process.env.OPENAI_API_KEY; + +// Create sandbox with port 3000 exposed +const sandbox = await Sandbox.create({ + runtime: "node24", + ports: [3000], +}); + +// Helper to run commands +const run = async (cmd: string, args: string[] = []) => { + const result = await sandbox.runCommand({ cmd, args, env: envs }); + if (result.exitCode !== 0) { + throw new Error(`Command failed: ${cmd} ${args.join(" ")}`); + } + return result; +}; + +// Install sandbox-agent +await run("sh", ["-c", "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh"]); + +// Install agents before starting the server +await run("sandbox-agent", ["install-agent", "claude"]); +await run("sandbox-agent", ["install-agent", "codex"]); + +// Start the server in the background +await sandbox.runCommand({ + cmd: "sandbox-agent", + args: ["server", "--no-token", "--host", "0.0.0.0", "--port", "3000"], + env: envs, + detached: true, +}); + +// Connect to the server +const baseUrl = sandbox.domain(3000); +const client = await SandboxAgent.connect({ baseUrl }); + +// Wait for server to be ready +for (let i = 0; i < 30; i++) { + try { + await client.getHealth(); + break; + } catch { + await new Promise((r) => setTimeout(r, 1000)); + } +} + +// Create a session and start coding +await client.createSession("my-session", { + agent: "claude", + permissionMode: "default", +}); + +await client.postMessage("my-session", { + message: "Summarize this repository", +}); + +for await (const event of client.streamEvents("my-session")) { + console.log(event.type, event.data); +} + +// Cleanup +await sandbox.stop(); +``` + +## Authentication + +Vercel Sandboxes support two authentication methods: + +- **OIDC Token**: Set `VERCEL_OIDC_TOKEN` (recommended for CI/CD) +- **Access Token**: Set `VERCEL_ACCESS_TOKEN` (for local development, run `vercel env pull`) + +See [Vercel Sandbox docs](https://vercel.com/docs/functions/sandbox) for details. diff --git a/docs/docs.json b/docs/docs.json index 0a67364..b54e31e 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -49,6 +49,7 @@ "deploy/index", "deploy/local", "deploy/e2b", + "deploy/vercel", "deploy/daytona", "deploy/docker" ] diff --git a/examples/vercel/package.json b/examples/vercel/package.json new file mode 100644 index 0000000..9f0569d --- /dev/null +++ b/examples/vercel/package.json @@ -0,0 +1,20 @@ +{ + "name": "@sandbox-agent/example-vercel", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/vercel.ts", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@vercel/sandbox": "latest", + "@sandbox-agent/example-shared": "workspace:*", + "sandbox-agent": "workspace:*" + }, + "devDependencies": { + "@types/node": "latest", + "tsx": "latest", + "typescript": "latest", + "vitest": "^3.0.0" + } +} diff --git a/examples/vercel/src/vercel.ts b/examples/vercel/src/vercel.ts new file mode 100644 index 0000000..4135ba8 --- /dev/null +++ b/examples/vercel/src/vercel.ts @@ -0,0 +1,87 @@ +import { Sandbox } from "@vercel/sandbox"; +import { logInspectorUrl, runPrompt, waitForHealth } from "@sandbox-agent/example-shared"; + +export async function setupVercelSandboxAgent(): Promise<{ + baseUrl: string; + token?: string; + cleanup: () => Promise; +}> { + // Build env vars for agent API keys + const envs: Record = {}; + if (process.env.ANTHROPIC_API_KEY) envs.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; + if (process.env.OPENAI_API_KEY) envs.OPENAI_API_KEY = process.env.OPENAI_API_KEY; + + // Create sandbox with port 3000 exposed + const sandbox = await Sandbox.create({ + runtime: "node24", + ports: [3000], + }); + + // Helper to run commands and check exit code + const run = async (cmd: string, args: string[] = []) => { + const result = await sandbox.runCommand({ cmd, args, env: envs }); + if (result.exitCode !== 0) { + const stderr = await result.stderr(); + throw new Error(`Command failed: ${cmd} ${args.join(" ")}\n${stderr}`); + } + return result; + }; + + console.log("Installing sandbox-agent..."); + await run("sh", ["-c", "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh"]); + + console.log("Installing agents..."); + await run("sandbox-agent", ["install-agent", "claude"]); + await run("sandbox-agent", ["install-agent", "codex"]); + + console.log("Starting server..."); + await sandbox.runCommand({ + cmd: "sandbox-agent", + args: ["server", "--no-token", "--host", "0.0.0.0", "--port", "3000"], + env: envs, + detached: true, + }); + + const baseUrl = sandbox.domain(3000); + + console.log("Waiting for server..."); + await waitForHealth({ baseUrl }); + + const cleanup = async () => { + console.log("Cleaning up..."); + await sandbox.stop(); + }; + + return { baseUrl, cleanup }; +} + +// Run interactively if executed directly +const isMainModule = import.meta.url === `file://${process.argv[1]}`; +if (isMainModule) { + // Check for Vercel auth + if (!process.env.VERCEL_OIDC_TOKEN && !process.env.VERCEL_ACCESS_TOKEN) { + throw new Error("Vercel authentication required. Run 'vercel env pull' or set VERCEL_ACCESS_TOKEN"); + } + + if (!process.env.OPENAI_API_KEY && !process.env.ANTHROPIC_API_KEY) { + throw new Error("OPENAI_API_KEY or ANTHROPIC_API_KEY required"); + } + + const { baseUrl, cleanup } = await setupVercelSandboxAgent(); + logInspectorUrl({ baseUrl }); + + process.once("SIGINT", async () => { + await cleanup(); + process.exit(0); + }); + process.once("SIGTERM", async () => { + await cleanup(); + process.exit(0); + }); + + await runPrompt({ + baseUrl, + autoApprovePermissions: process.env.AUTO_APPROVE_PERMISSIONS === "true", + }); + await cleanup(); +} diff --git a/examples/vercel/tests/vercel.test.ts b/examples/vercel/tests/vercel.test.ts new file mode 100644 index 0000000..dd6de67 --- /dev/null +++ b/examples/vercel/tests/vercel.test.ts @@ -0,0 +1,28 @@ +import { describe, it, expect } from "vitest"; +import { buildHeaders } from "@sandbox-agent/example-shared"; +import { setupVercelSandboxAgent } from "../src/vercel.ts"; + +const shouldRun = Boolean(process.env.VERCEL_OIDC_TOKEN || process.env.VERCEL_ACCESS_TOKEN); +const timeoutMs = Number.parseInt(process.env.SANDBOX_TEST_TIMEOUT_MS || "", 10) || 300_000; + +const testFn = shouldRun ? it : it.skip; + +describe("vercel example", () => { + testFn( + "starts sandbox-agent and responds to /v1/health", + async () => { + const { baseUrl, token, cleanup } = await setupVercelSandboxAgent(); + try { + const response = await fetch(`${baseUrl}/v1/health`, { + headers: buildHeaders({ token }), + }); + expect(response.ok).toBe(true); + const data = await response.json(); + expect(data.status).toBe("ok"); + } finally { + await cleanup(); + } + }, + timeoutMs + ); +}); diff --git a/examples/vercel/tsconfig.json b/examples/vercel/tsconfig.json new file mode 100644 index 0000000..ad92bfa --- /dev/null +++ b/examples/vercel/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": [ + "ES2022", + "DOM" + ], + "module": "ESNext", + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "noEmit": true, + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "**/*.test.ts" + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cfd55b1..f384d73 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: version: 2.7.6 vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@25.0.10) + version: 3.2.4(@types/debug@4.1.12)(@types/node@25.1.0) examples/daytona: dependencies: @@ -97,6 +97,31 @@ importers: specifier: latest version: 5.9.3 + examples/vercel: + dependencies: + '@sandbox-agent/example-shared': + specifier: workspace:* + version: link:../shared + '@vercel/sandbox': + specifier: latest + version: 1.4.1 + sandbox-agent: + specifier: workspace:* + version: link:../../sdks/typescript + devDependencies: + '@types/node': + specifier: latest + version: 25.1.0 + tsx: + specifier: latest + version: 4.21.0 + typescript: + specifier: latest + version: 5.9.3 + vitest: + specifier: ^3.0.0 + version: 3.2.4(@types/debug@4.1.12)(@types/node@25.1.0) + frontend/packages/inspector: dependencies: lucide-react: @@ -117,7 +142,7 @@ importers: version: 18.3.7(@types/react@18.3.27) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.7.0(vite@5.4.21(@types/node@25.0.10)) + version: 4.7.0(vite@5.4.21(@types/node@25.1.0)) sandbox-agent: specifier: workspace:* version: link:../../../sdks/typescript @@ -126,19 +151,19 @@ importers: version: 5.9.3 vite: specifier: ^5.4.7 - version: 5.4.21(@types/node@25.0.10) + version: 5.4.21(@types/node@25.1.0) frontend/packages/website: dependencies: '@astrojs/react': specifier: ^4.2.0 - version: 4.4.2(@types/node@25.0.10)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(jiti@1.21.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tsx@4.21.0)(yaml@2.8.2) + version: 4.4.2(@types/node@25.1.0)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(jiti@1.21.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tsx@4.21.0)(yaml@2.8.2) '@astrojs/tailwind': specifier: ^6.0.0 - version: 6.0.2(astro@5.16.15(@types/node@25.0.10)(jiti@1.21.7)(rollup@4.56.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) + version: 6.0.2(astro@5.16.15(@types/node@25.1.0)(jiti@1.21.7)(rollup@4.56.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) astro: specifier: ^5.1.0 - version: 5.16.15(@types/node@25.0.10)(jiti@1.21.7)(rollup@4.56.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + version: 5.16.15(@types/node@25.1.0)(jiti@1.21.7)(rollup@4.56.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) framer-motion: specifier: ^12.0.0 version: 12.29.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -279,7 +304,7 @@ importers: devDependencies: vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@25.0.10) + version: 3.2.4(@types/debug@4.1.12)(@types/node@25.1.0) sdks/cli/platforms/darwin-arm64: {} @@ -1870,6 +1895,9 @@ packages: '@types/node@25.0.10': resolution: {integrity: sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==} + '@types/node@25.1.0': + resolution: {integrity: sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==} + '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} @@ -1901,6 +1929,13 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@vercel/oidc@3.1.0': + resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} + engines: {node: '>= 20'} + + '@vercel/sandbox@1.4.1': + resolution: {integrity: sha512-5jaNLv6QJ0112ZFhCv9hQDCV3IYogpbEn5LzMcY5E8TZsf5tF0avat2tBe7McOJvgVs0SDkuzjvGjUMKtTkjrA==} + '@vitejs/plugin-react@4.7.0': resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -1996,6 +2031,9 @@ packages: engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} hasBin: true + async-retry@1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -2013,12 +2051,28 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} + b4a@1.7.3: + resolution: {integrity: sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bare-events@2.8.2: + resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + base-64@1.0.0: resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} @@ -2439,6 +2493,9 @@ packages: eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -2458,6 +2515,9 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -2766,6 +2826,9 @@ packages: engines: {node: '>=6'} hasBin: true + jsonlines@0.1.1: + resolution: {integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==} + kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -3104,6 +3167,10 @@ packages: resolution: {integrity: sha512-c/hfooPx+RBIOPM09GSxABOZhYPblDoyaGhqBkD/59vtpN21jEuWKDlM0KYTvqJVlSYjKs0tBcIdeXKChlSPtw==} hasBin: true + os-paths@4.4.0: + resolution: {integrity: sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg==} + engines: {node: '>= 6.0'} + p-limit@6.2.0: resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} engines: {node: '>=18'} @@ -3384,6 +3451,10 @@ packages: retext@9.0.0: resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -3489,6 +3560,9 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + streamx@2.23.0: + resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -3555,6 +3629,9 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} @@ -3565,6 +3642,9 @@ packages: engines: {node: '>=18'} deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me + text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -4024,6 +4104,14 @@ packages: utf-8-validate: optional: true + xdg-app-paths@5.1.0: + resolution: {integrity: sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA==} + engines: {node: '>=6'} + + xdg-portable@7.3.0: + resolution: {integrity: sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==} + engines: {node: '>= 6.0'} + xxhash-wasm@1.1.0: resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} @@ -4077,6 +4165,9 @@ packages: typescript: ^4.9.4 || ^5.0.2 zod: ^3 + zod@3.24.4: + resolution: {integrity: sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==} + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -4132,15 +4223,15 @@ snapshots: dependencies: prismjs: 1.30.0 - '@astrojs/react@4.4.2(@types/node@25.0.10)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(jiti@1.21.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tsx@4.21.0)(yaml@2.8.2)': + '@astrojs/react@4.4.2(@types/node@25.1.0)(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(jiti@1.21.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tsx@4.21.0)(yaml@2.8.2)': dependencies: '@types/react': 19.2.10 '@types/react-dom': 19.2.3(@types/react@19.2.10) - '@vitejs/plugin-react': 4.7.0(vite@6.4.1(@types/node@25.0.10)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) + '@vitejs/plugin-react': 4.7.0(vite@6.4.1(@types/node@25.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) ultrahtml: 1.6.0 - vite: 6.4.1(@types/node@25.0.10)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@25.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -4155,9 +4246,9 @@ snapshots: - tsx - yaml - '@astrojs/tailwind@6.0.2(astro@5.16.15(@types/node@25.0.10)(jiti@1.21.7)(rollup@4.56.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2))': + '@astrojs/tailwind@6.0.2(astro@5.16.15(@types/node@25.1.0)(jiti@1.21.7)(rollup@4.56.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2))': dependencies: - astro: 5.16.15(@types/node@25.0.10)(jiti@1.21.7)(rollup@4.56.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + astro: 5.16.15(@types/node@25.1.0)(jiti@1.21.7)(rollup@4.56.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) autoprefixer: 10.4.23(postcss@8.5.6) postcss: 8.5.6 postcss-load-config: 4.0.2(postcss@8.5.6) @@ -5869,7 +5960,7 @@ snapshots: '@types/docker-modem@3.0.6': dependencies: - '@types/node': 25.0.10 + '@types/node': 24.10.9 '@types/ssh2': 1.15.5 '@types/dockerode@4.0.1': @@ -5912,6 +6003,10 @@ snapshots: dependencies: undici-types: 7.16.0 + '@types/node@25.1.0': + dependencies: + undici-types: 7.16.0 + '@types/prop-types@15.7.15': {} '@types/react-dom@18.3.7(@types/react@18.3.27)': @@ -5941,7 +6036,24 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@25.0.10))': + '@vercel/oidc@3.1.0': {} + + '@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.19.1 + xdg-app-paths: 5.1.0 + zod: 3.24.4 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@25.1.0))': dependencies: '@babel/core': 7.28.6 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.6) @@ -5949,11 +6061,11 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 5.4.21(@types/node@25.0.10) + vite: 5.4.21(@types/node@25.1.0) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.0.10)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@babel/core': 7.28.6 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.6) @@ -5961,7 +6073,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.4.1(@types/node@25.0.10)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@25.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -5973,13 +6085,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@25.0.10))': + '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@25.1.0))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 5.4.21(@types/node@25.0.10) + vite: 5.4.21(@types/node@25.1.0) '@vitest/pretty-format@3.2.4': dependencies: @@ -6046,7 +6158,7 @@ snapshots: assertion-error@2.0.1: {} - astro@5.16.15(@types/node@25.0.10)(jiti@1.21.7)(rollup@4.56.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): + astro@5.16.15(@types/node@25.1.0)(jiti@1.21.7)(rollup@4.56.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): dependencies: '@astrojs/compiler': 2.13.0 '@astrojs/internal-helpers': 0.7.5 @@ -6103,8 +6215,8 @@ snapshots: unist-util-visit: 5.1.0 unstorage: 1.17.4 vfile: 6.0.3 - vite: 6.4.1(@types/node@25.0.10)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) - vitefu: 1.1.1(vite@6.4.1(@types/node@25.0.10)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) + vite: 6.4.1(@types/node@25.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + vitefu: 1.1.1(vite@6.4.1(@types/node@25.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) xxhash-wasm: 1.1.0 yargs-parser: 21.1.1 yocto-spinner: 0.2.3 @@ -6148,6 +6260,10 @@ snapshots: - uploadthing - yaml + async-retry@1.3.3: + dependencies: + retry: 0.13.1 + asynckit@0.4.0: {} autoprefixer@10.4.23(postcss@8.5.6): @@ -6169,10 +6285,14 @@ snapshots: axobject-query@4.1.0: {} + b4a@1.7.3: {} + bail@2.0.2: {} balanced-match@1.0.2: {} + bare-events@2.8.2: {} + base-64@1.0.0: {} base64-js@1.5.1: {} @@ -6658,6 +6778,12 @@ snapshots: eventemitter3@5.0.4: {} + events-universal@1.0.1: + dependencies: + bare-events: 2.8.2 + transitivePeerDependencies: + - bare-abort-controller + events@3.3.0: {} execa@8.0.1: @@ -6680,6 +6806,8 @@ snapshots: extend@3.0.2: {} + fast-fifo@1.3.2: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -7021,6 +7149,8 @@ snapshots: json5@2.2.3: {} + jsonlines@0.1.1: {} + kleur@3.0.3: {} lilconfig@3.1.3: {} @@ -7525,6 +7655,8 @@ snapshots: undici: 5.29.0 yargs-parser: 21.1.1 + os-paths@4.4.0: {} + p-limit@6.2.0: dependencies: yocto-queue: 1.2.2 @@ -7671,7 +7803,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 25.0.10 + '@types/node': 24.10.9 long: 5.3.2 proxy-from-env@1.1.0: {} @@ -7835,6 +7967,8 @@ snapshots: retext-stringify: 4.0.0 unified: 11.0.5 + retry@0.13.1: {} + reusify@1.1.0: {} rollup@4.56.0: @@ -7976,6 +8110,15 @@ snapshots: streamsearch@1.1.0: {} + streamx@2.23.0: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.3 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -8086,6 +8229,15 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + tar-stream@3.1.7: + dependencies: + b4a: 1.7.3 + fast-fifo: 1.3.2 + streamx: 2.23.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + tar@6.2.1: dependencies: chownr: 2.0.0 @@ -8103,6 +8255,12 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 + text-decoder@1.2.3: + dependencies: + b4a: 1.7.3 + transitivePeerDependencies: + - react-native-b4a + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -8375,6 +8533,24 @@ snapshots: - supports-color - terser + vite-node@3.2.4(@types/node@25.1.0): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 5.4.21(@types/node@25.1.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite@5.4.21(@types/node@22.19.7): dependencies: esbuild: 0.21.5 @@ -8393,7 +8569,16 @@ snapshots: '@types/node': 25.0.10 fsevents: 2.3.3 - vite@6.4.1(@types/node@25.0.10)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2): + vite@5.4.21(@types/node@25.1.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.6 + rollup: 4.56.0 + optionalDependencies: + '@types/node': 25.1.0 + fsevents: 2.3.3 + + vite@6.4.1(@types/node@25.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -8402,21 +8587,21 @@ snapshots: rollup: 4.56.0 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.0.10 + '@types/node': 25.1.0 fsevents: 2.3.3 jiti: 1.21.7 tsx: 4.21.0 yaml: 2.8.2 - vitefu@1.1.1(vite@6.4.1(@types/node@25.0.10)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)): + vitefu@1.1.1(vite@6.4.1(@types/node@25.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)): optionalDependencies: - vite: 6.4.1(@types/node@25.0.10)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@25.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.7): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.0.10)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.1.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -8455,7 +8640,7 @@ snapshots: dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.0.10)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.1.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -8490,6 +8675,45 @@ snapshots: - supports-color - terser + vitest@3.2.4(@types/debug@4.1.12)(@types/node@25.1.0): + dependencies: + '@types/chai': 5.2.3 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.1.0)) + '@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.3.3 + debug: 4.4.3 + expect-type: 1.3.0 + magic-string: 0.30.21 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 5.4.21(@types/node@25.1.0) + vite-node: 3.2.4(@types/node@25.1.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 25.1.0 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vscode-languageserver-textdocument@1.0.12: {} vscode-languageserver-types@3.17.5: {} @@ -8539,6 +8763,14 @@ snapshots: ws@8.19.0: {} + xdg-app-paths@5.1.0: + dependencies: + xdg-portable: 7.3.0 + + xdg-portable@7.3.0: + dependencies: + os-paths: 4.4.0 + xxhash-wasm@1.1.0: {} y18n@5.0.8: {} @@ -8580,6 +8812,8 @@ snapshots: typescript: 5.9.3 zod: 3.25.76 + zod@3.24.4: {} + zod@3.25.76: {} zwitch@2.0.4: {}