From 11950d2a39b4d2626212926992fc604e308adccc Mon Sep 17 00:00:00 2001 From: Franklin Date: Tue, 3 Feb 2026 21:17:44 -0500 Subject: [PATCH] adding compute example --- docs/deploy/computesdk.mdx | 214 +++++++++++++++++++ docs/docs.json | 1 + examples/computesdk/package.json | 19 ++ examples/computesdk/src/computesdk.ts | 156 ++++++++++++++ examples/computesdk/tests/computesdk.test.ts | 39 ++++ examples/computesdk/tsconfig.json | 16 ++ pnpm-lock.yaml | 194 +++++++++++++++-- 7 files changed, 616 insertions(+), 23 deletions(-) create mode 100644 docs/deploy/computesdk.mdx create mode 100644 examples/computesdk/package.json create mode 100644 examples/computesdk/src/computesdk.ts create mode 100644 examples/computesdk/tests/computesdk.test.ts create mode 100644 examples/computesdk/tsconfig.json diff --git a/docs/deploy/computesdk.mdx b/docs/deploy/computesdk.mdx new file mode 100644 index 0000000..5e07da0 --- /dev/null +++ b/docs/deploy/computesdk.mdx @@ -0,0 +1,214 @@ +--- +title: "ComputeSDK" +description: "Deploy the daemon using ComputeSDK's provider-agnostic sandbox API." +--- + +[ComputeSDK](https://computesdk.com) provides a unified interface for managing sandboxes across multiple providers. Write once, deploy anywhere—switch providers by changing environment variables. + +## Prerequisites + +- `COMPUTESDK_API_KEY` from [console.computesdk.com](https://console.computesdk.com) +- Provider API key (one of: `E2B_API_KEY`, `DAYTONA_API_KEY`, `VERCEL_TOKEN`, `MODAL_TOKEN_ID` + `MODAL_TOKEN_SECRET`, `BLAXEL_API_KEY`, `CSB_API_KEY`) +- `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` for the coding agents + +## TypeScript Example + +```typescript +import { + compute, + detectProvider, + getMissingEnvVars, + getProviderConfigFromEnv, + isProviderAuthComplete, + isValidProvider, + PROVIDER_NAMES, + type ExplicitComputeConfig, + type ProviderName, +} from "computesdk"; +import { SandboxAgent } from "sandbox-agent"; + +const PORT = 3000; +const REQUEST_TIMEOUT_MS = + Number.parseInt(process.env.COMPUTESDK_TIMEOUT_MS || "", 10) || 120_000; + +/** + * Detects and validates the provider to use. + * Priority: COMPUTESDK_PROVIDER env var > auto-detection from API keys + */ +function resolveProvider(): ProviderName { + const providerOverride = process.env.COMPUTESDK_PROVIDER; + + if (providerOverride) { + if (!isValidProvider(providerOverride)) { + throw new Error( + `Unsupported provider "${providerOverride}". Supported: ${PROVIDER_NAMES.join(", ")}` + ); + } + if (!isProviderAuthComplete(providerOverride)) { + const missing = getMissingEnvVars(providerOverride); + throw new Error( + `Missing credentials for "${providerOverride}". Set: ${missing.join(", ")}` + ); + } + return providerOverride as ProviderName; + } + + const detected = detectProvider(); + if (!detected) { + throw new Error( + `No provider credentials found. Set one of: ${PROVIDER_NAMES.map((p) => getMissingEnvVars(p).join(", ")).join(" | ")}` + ); + } + return detected as ProviderName; +} + +function configureComputeSDK(): void { + const provider = resolveProvider(); + + const config: ExplicitComputeConfig = { + provider, + computesdkApiKey: process.env.COMPUTESDK_API_KEY, + requestTimeoutMs: REQUEST_TIMEOUT_MS, + }; + + // Add provider-specific config from environment + const providerConfig = getProviderConfigFromEnv(provider); + if (Object.keys(providerConfig).length > 0) { + (config as any)[provider] = providerConfig; + } + + compute.setConfig(config); +} + +configureComputeSDK(); + +// Build environment variables to pass to 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 +const sandbox = await compute.sandbox.create({ + envs: Object.keys(envs).length > 0 ? envs : undefined, +}); + +// Helper to run commands with error handling +const run = async (cmd: string, options?: { background?: boolean }) => { + const result = await sandbox.runCommand(cmd, options); + if (typeof result?.exitCode === "number" && result.exitCode !== 0) { + throw new Error(`Command failed: ${cmd} (exit ${result.exitCode})\n${result.stderr || ""}`); + } + return result; +}; + +// Install sandbox-agent +await run("curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh"); + +// Install agents conditionally based on available API keys +if (envs.ANTHROPIC_API_KEY) { + await run("sandbox-agent install-agent claude"); +} +if (envs.OPENAI_API_KEY) { + await run("sandbox-agent install-agent codex"); +} + +// Start the server in the background +await run(`sandbox-agent server --no-token --host 0.0.0.0 --port ${PORT}`, { background: true }); + +// Get the public URL for the sandbox +const baseUrl = await sandbox.getUrl({ port: PORT }); + +// Wait for server to be ready +const deadline = Date.now() + REQUEST_TIMEOUT_MS; +while (Date.now() < deadline) { + try { + const response = await fetch(`${baseUrl}/v1/health`); + if (response.ok) { + const data = await response.json(); + if (data?.status === "ok") break; + } + } catch { + // Server not ready yet + } + await new Promise((r) => setTimeout(r, 500)); +} + +// Connect to the server +const client = await SandboxAgent.connect({ baseUrl }); + +// Detect which agent to use based on available API keys +const agent = envs.ANTHROPIC_API_KEY ? "claude" : "codex"; + +// Create a session and start coding +await client.createSession("my-session", { agent }); + +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.destroy(); +``` + +## Supported Providers + +ComputeSDK auto-detects your provider from environment variables: + +| Provider | Environment Variables | +|----------|----------------------| +| E2B | `E2B_API_KEY` | +| Daytona | `DAYTONA_API_KEY` | +| Vercel | `VERCEL_TOKEN` or `VERCEL_OIDC_TOKEN` | +| Modal | `MODAL_TOKEN_ID` + `MODAL_TOKEN_SECRET` | +| Blaxel | `BLAXEL_API_KEY` | +| CodeSandbox | `CSB_API_KEY` | + +## Notes + +- **Provider resolution order**: `COMPUTESDK_PROVIDER` env var takes priority, otherwise auto-detection from API keys. +- **Conditional agent installation**: Only agents with available API keys are installed, reducing setup time. +- **Command error handling**: The example validates exit codes and throws on failures for easier debugging. +- `sandbox.runCommand(..., { background: true })` keeps the server running while your app continues. +- `sandbox.getUrl({ port })` returns a public URL for the sandbox port. +- Always destroy the sandbox when you are done to avoid leaking resources. +- If sandbox creation times out, set `COMPUTESDK_TIMEOUT_MS` to a higher value (default: 120000ms). + +## Explicit Provider Selection + +To force a specific provider instead of auto-detection, set the `COMPUTESDK_PROVIDER` environment variable: + +```bash +export COMPUTESDK_PROVIDER=e2b +``` + +Or configure programmatically using `getProviderConfigFromEnv()`: + +```typescript +import { compute, getProviderConfigFromEnv, type ExplicitComputeConfig } from "computesdk"; + +const config: ExplicitComputeConfig = { + provider: "e2b", + computesdkApiKey: process.env.COMPUTESDK_API_KEY, + requestTimeoutMs: 120_000, +}; + +// Automatically populate provider-specific config from environment +const providerConfig = getProviderConfigFromEnv("e2b"); +if (Object.keys(providerConfig).length > 0) { + (config as any).e2b = providerConfig; +} + +compute.setConfig(config); +``` + +## Direct Mode (No ComputeSDK API Key) + +To bypass the ComputeSDK gateway and use provider SDKs directly, see the provider-specific examples: + +- [E2B](/deploy/e2b) +- [Daytona](/deploy/daytona) +- [Vercel](/deploy/vercel) diff --git a/docs/docs.json b/docs/docs.json index 164c902..89dd714 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -57,6 +57,7 @@ "icon": "server", "pages": [ "deploy/local", + "deploy/computesdk", "deploy/e2b", "deploy/daytona", "deploy/vercel", diff --git a/examples/computesdk/package.json b/examples/computesdk/package.json new file mode 100644 index 0000000..c801516 --- /dev/null +++ b/examples/computesdk/package.json @@ -0,0 +1,19 @@ +{ + "name": "@sandbox-agent/example-computesdk", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/computesdk.ts", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@sandbox-agent/example-shared": "workspace:*", + "computesdk": "latest" + }, + "devDependencies": { + "@types/node": "latest", + "tsx": "latest", + "typescript": "latest", + "vitest": "^3.0.0" + } +} diff --git a/examples/computesdk/src/computesdk.ts b/examples/computesdk/src/computesdk.ts new file mode 100644 index 0000000..b21dd53 --- /dev/null +++ b/examples/computesdk/src/computesdk.ts @@ -0,0 +1,156 @@ +import { + compute, + detectProvider, + getMissingEnvVars, + getProviderConfigFromEnv, + isProviderAuthComplete, + isValidProvider, + PROVIDER_NAMES, + type ExplicitComputeConfig, + type ProviderName, +} from "computesdk"; +import { runPrompt, waitForHealth } from "@sandbox-agent/example-shared"; +import { fileURLToPath } from "node:url"; +import { resolve } from "node:path"; + +const PORT = 3000; +const REQUEST_TIMEOUT_MS = + Number.parseInt(process.env.COMPUTESDK_TIMEOUT_MS || "", 10) || 120_000; + +/** + * Detects and validates the provider to use. + * Priority: COMPUTESDK_PROVIDER env var > auto-detection from API keys + */ +function resolveProvider(): ProviderName { + const providerOverride = process.env.COMPUTESDK_PROVIDER; + + if (providerOverride) { + if (!isValidProvider(providerOverride)) { + throw new Error( + `Unsupported ComputeSDK provider "${providerOverride}". Supported providers: ${PROVIDER_NAMES.join(", ")}` + ); + } + if (!isProviderAuthComplete(providerOverride)) { + const missing = getMissingEnvVars(providerOverride); + throw new Error( + `Missing credentials for provider "${providerOverride}". Set: ${missing.join(", ")}` + ); + } + console.log(`Using ComputeSDK provider: ${providerOverride} (explicit)`); + return providerOverride as ProviderName; + } + + const detected = detectProvider(); + if (!detected) { + throw new Error( + `No provider credentials found. Set one of: ${PROVIDER_NAMES.map((p) => getMissingEnvVars(p).join(", ")).join(" | ")}` + ); + } + console.log(`Using ComputeSDK provider: ${detected} (auto-detected)`); + return detected as ProviderName; +} + +function configureComputeSDK(): void { + const provider = resolveProvider(); + + const config: ExplicitComputeConfig = { + provider, + computesdkApiKey: process.env.COMPUTESDK_API_KEY, + requestTimeoutMs: REQUEST_TIMEOUT_MS, + }; + + const providerConfig = getProviderConfigFromEnv(provider); + if (Object.keys(providerConfig).length > 0) { + const configWithProvider = + config as ExplicitComputeConfig & Record>; + configWithProvider[provider] = providerConfig; + } + + compute.setConfig(config); +} + +configureComputeSDK(); + +const buildEnv = (): Record => { + const env: Record = {}; + if (process.env.ANTHROPIC_API_KEY) env.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; + if (process.env.OPENAI_API_KEY) env.OPENAI_API_KEY = process.env.OPENAI_API_KEY; + return env; +}; + +export async function setupComputeSdkSandboxAgent(): Promise<{ + baseUrl: string; + cleanup: () => Promise; +}> { + const env = buildEnv(); + + console.log("Creating ComputeSDK sandbox..."); + const sandbox = await compute.sandbox.create({ + envs: Object.keys(env).length > 0 ? env : undefined, + }); + + const run = async (cmd: string, options?: { background?: boolean }) => { + const result = await sandbox.runCommand(cmd, options); + if (typeof result?.exitCode === "number" && result.exitCode !== 0) { + throw new Error(`Command failed: ${cmd} (exit ${result.exitCode})\n${result.stderr || ""}`); + } + return result; + }; + + console.log("Installing sandbox-agent..."); + await run("curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh"); + + if (env.ANTHROPIC_API_KEY) { + console.log("Installing Claude agent..."); + await run("sandbox-agent install-agent claude"); + } + + if (env.OPENAI_API_KEY) { + console.log("Installing Codex agent..."); + await run("sandbox-agent install-agent codex"); + } + + console.log("Starting server..."); + await run(`sandbox-agent server --no-token --host 0.0.0.0 --port ${PORT}`, { background: true }); + + const baseUrl = await sandbox.getUrl({ port: PORT }); + + console.log("Waiting for server..."); + await waitForHealth({ baseUrl }); + + const cleanup = async () => { + try { + await sandbox.destroy(); + } catch (error) { + console.warn("Cleanup failed:", error instanceof Error ? error.message : error); + } + }; + + return { baseUrl, cleanup }; +} + +export async function runComputeSdkExample(): Promise { + const { baseUrl, cleanup } = await setupComputeSdkSandboxAgent(); + + const handleExit = async () => { + await cleanup(); + process.exit(0); + }; + + process.once("SIGINT", handleExit); + process.once("SIGTERM", handleExit); + + await runPrompt(baseUrl); + await cleanup(); +} + +const isDirectRun = Boolean( + process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url) +); + +if (isDirectRun) { + runComputeSdkExample().catch((error) => { + console.error(error instanceof Error ? error.message : error); + process.exit(1); + }); +} diff --git a/examples/computesdk/tests/computesdk.test.ts b/examples/computesdk/tests/computesdk.test.ts new file mode 100644 index 0000000..9d023a9 --- /dev/null +++ b/examples/computesdk/tests/computesdk.test.ts @@ -0,0 +1,39 @@ +import { describe, it, expect } from "vitest"; +import { buildHeaders } from "@sandbox-agent/example-shared"; +import { setupComputeSdkSandboxAgent } from "../src/computesdk.ts"; + +const hasModal = Boolean(process.env.MODAL_TOKEN_ID && process.env.MODAL_TOKEN_SECRET); +const hasVercel = Boolean(process.env.VERCEL_TOKEN || process.env.VERCEL_OIDC_TOKEN); +const hasProviderKey = Boolean( + process.env.BLAXEL_API_KEY || + process.env.CSB_API_KEY || + process.env.DAYTONA_API_KEY || + process.env.E2B_API_KEY || + hasModal || + hasVercel +); + +const shouldRun = Boolean(process.env.COMPUTESDK_API_KEY) && hasProviderKey; +const timeoutMs = Number.parseInt(process.env.SANDBOX_TEST_TIMEOUT_MS || "", 10) || 300_000; + +const testFn = shouldRun ? it : it.skip; + +describe("computesdk example", () => { + testFn( + "starts sandbox-agent and responds to /v1/health", + async () => { + const { baseUrl, cleanup } = await setupComputeSdkSandboxAgent(); + try { + const response = await fetch(`${baseUrl}/v1/health`, { + headers: buildHeaders({}), + }); + expect(response.ok).toBe(true); + const data = await response.json(); + expect(data.status).toBe("ok"); + } finally { + await cleanup(); + } + }, + timeoutMs + ); +}); diff --git a/examples/computesdk/tsconfig.json b/examples/computesdk/tsconfig.json new file mode 100644 index 0000000..96ba2fd --- /dev/null +++ b/examples/computesdk/tsconfig.json @@ -0,0 +1,16 @@ +{ + "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 9aea712..09ec9bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,7 +17,7 @@ importers: version: 2.7.6 vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@25.2.2)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@25.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) examples/cloudflare: dependencies: @@ -62,6 +62,28 @@ importers: specifier: latest version: 4.63.0(@cloudflare/workers-types@4.20260207.0) + examples/computesdk: + dependencies: + '@sandbox-agent/example-shared': + specifier: workspace:* + version: link:../shared + computesdk: + specifier: latest + version: 2.2.0 + devDependencies: + '@types/node': + specifier: latest + version: 25.2.3 + 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.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + examples/daytona: dependencies: '@daytonaio/sdk': @@ -311,7 +333,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.2.2)) + version: 4.7.0(vite@5.4.21(@types/node@25.2.3)) sandbox-agent: specifier: workspace:* version: link:../../../sdks/typescript @@ -320,19 +342,19 @@ importers: version: 5.9.3 vite: specifier: ^5.4.7 - version: 5.4.21(@types/node@25.2.2) + version: 5.4.21(@types/node@25.2.3) frontend/packages/website: dependencies: '@astrojs/react': specifier: ^4.2.0 - version: 4.4.2(@types/node@25.2.2)(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(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.2.3)(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(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.2.2)(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.2.3)(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.2.2)(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.2.3)(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) @@ -480,7 +502,7 @@ importers: devDependencies: vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@25.2.2)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@25.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) sdks/cli-shared: devDependencies: @@ -528,7 +550,7 @@ importers: devDependencies: vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@25.2.2)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@25.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) sdks/gigacode/platforms/darwin-arm64: {} @@ -951,6 +973,9 @@ packages: '@cloudflare/workers-types@4.20260207.0': resolution: {integrity: sha512-PSxgnAOK0EtTytlY7/+gJcsQJYg0Qo7KlOMSC/wiBE+pBqKjuKdd1ZgM+NvpPNqZAjWV5jqAMTTNYEmgk27gYw==} + '@computesdk/cmd@0.4.1': + resolution: {integrity: sha512-hhcYrwMnOpRSwWma3gkUeAVsDFG56nURwSaQx8vCepv0IuUv39bK4mMkgszolnUQrVjBDdW7b3lV+l5B2S8fRA==} + '@connectrpc/connect-web@2.0.0-rc.3': resolution: {integrity: sha512-w88P8Lsn5CCsA7MFRl2e6oLY4J/5toiNtJns/YJrlyQaWOy3RO8pDgkz+iIkG98RPMhj2thuBvsd3Cn4DKKCkw==} peerDependencies: @@ -2540,6 +2565,9 @@ packages: '@types/node@25.2.2': resolution: {integrity: sha512-BkmoP5/FhRYek5izySdkOneRyXYN35I860MFAGupTdebyE66uZaR+bXLHq8k4DirE5DwQi3NuhvRU1jqTVwUrQ==} + '@types/node@25.2.3': + resolution: {integrity: sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==} + '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} @@ -2920,6 +2948,9 @@ packages: compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + computesdk@2.2.0: + resolution: {integrity: sha512-gAAL8vMLkYUFH138OwbebTG9AYMh4RudhRvYboJvRdc9NQAafVHfvZtPwg4YVKPB3VpsfK5m9pkgv60Xr2cE1g==} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -5144,15 +5175,15 @@ snapshots: dependencies: prismjs: 1.30.0 - '@astrojs/react@4.4.2(@types/node@25.2.2)(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(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.2.3)(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(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': 18.3.27 '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@vitejs/plugin-react': 4.7.0(vite@6.4.1(@types/node@25.2.2)(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.2.3)(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.2.2)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@25.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -5167,9 +5198,9 @@ snapshots: - tsx - yaml - '@astrojs/tailwind@6.0.2(astro@5.16.15(@types/node@25.2.2)(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.2.3)(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.2.2)(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.2.3)(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) @@ -5884,6 +5915,8 @@ snapshots: '@cloudflare/workers-types@4.20260207.0': {} + '@computesdk/cmd@0.4.1': {} + '@connectrpc/connect-web@2.0.0-rc.3(@bufbuild/protobuf@2.11.0)(@connectrpc/connect@2.0.0-rc.3(@bufbuild/protobuf@2.11.0))': dependencies: '@bufbuild/protobuf': 2.11.0 @@ -7118,7 +7151,7 @@ snapshots: '@types/docker-modem@3.0.6': dependencies: - '@types/node': 25.2.2 + '@types/node': 24.10.9 '@types/ssh2': 1.15.5 '@types/dockerode@4.0.1': @@ -7161,6 +7194,10 @@ snapshots: dependencies: undici-types: 7.16.0 + '@types/node@25.2.3': + dependencies: + undici-types: 7.16.0 + '@types/prop-types@15.7.15': {} '@types/react-dom@18.3.7(@types/react@18.3.27)': @@ -7199,7 +7236,7 @@ snapshots: - bare-abort-controller - react-native-b4a - '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@25.2.2))': + '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@25.2.3))': dependencies: '@babel/core': 7.28.6 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.6) @@ -7207,7 +7244,7 @@ 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.2.2) + vite: 5.4.21(@types/node@25.2.3) transitivePeerDependencies: - supports-color @@ -7223,6 +7260,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.2.3)(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) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.6) + '@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.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + '@vitest/expect@3.2.4': dependencies: '@types/chai': 5.2.3 @@ -7239,6 +7288,14 @@ snapshots: optionalDependencies: vite: 5.4.21(@types/node@25.2.2) + '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@25.2.3))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 5.4.21(@types/node@25.2.3) + '@vitest/pretty-format@3.2.4': dependencies: tinyrainbow: 2.0.0 @@ -7320,7 +7377,7 @@ snapshots: assertion-error@2.0.1: {} - astro@5.16.15(@types/node@25.2.2)(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.2.3)(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 @@ -7377,8 +7434,8 @@ snapshots: unist-util-visit: 5.1.0 unstorage: 1.17.4 vfile: 6.0.3 - vite: 6.4.1(@types/node@25.2.2)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) - vitefu: 1.1.1(vite@6.4.1(@types/node@25.2.2)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)) + vite: 6.4.1(@types/node@25.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + vitefu: 1.1.1(vite@6.4.1(@types/node@25.2.3)(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 @@ -7665,6 +7722,10 @@ snapshots: compare-versions@6.1.1: {} + computesdk@2.2.0: + dependencies: + '@computesdk/cmd': 0.4.1 + confbox@0.1.8: {} consola@3.4.2: {} @@ -9180,7 +9241,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 25.2.2 + '@types/node': 24.10.9 long: 5.3.2 proxy-addr@2.0.7: @@ -10013,6 +10074,27 @@ snapshots: - tsx - yaml + vite-node@3.2.4(@types/node@25.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 6.4.1(@types/node@25.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vite@5.4.21(@types/node@22.19.7): dependencies: esbuild: 0.21.5 @@ -10031,6 +10113,15 @@ snapshots: '@types/node': 25.2.2 fsevents: 2.3.3 + vite@5.4.21(@types/node@25.2.3): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.6 + rollup: 4.56.0 + optionalDependencies: + '@types/node': 25.2.3 + fsevents: 2.3.3 + vite@6.4.1(@types/node@22.19.7)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.25.12 @@ -10061,15 +10152,30 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - vitefu@1.1.1(vite@6.4.1(@types/node@25.2.2)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)): + vite@6.4.1(@types/node@25.2.3)(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) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.56.0 + tinyglobby: 0.2.15 optionalDependencies: - vite: 6.4.1(@types/node@25.2.2)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + '@types/node': 25.2.3 + 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.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)): + optionalDependencies: + vite: 6.4.1(@types/node@25.2.3)(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)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.2.2)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.2.3)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -10149,6 +10255,48 @@ snapshots: - tsx - yaml + vitest@3.2.4(@types/debug@4.1.12)(@types/node@25.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + '@types/chai': 5.2.3 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.2.3)) + '@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.2.3) + vite-node: 3.2.4(@types/node@25.2.3)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 25.2.3 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vscode-languageserver-textdocument@1.0.12: {} vscode-languageserver-types@3.17.5: {}