From b29e2e1f8ecda26a6688eb724e81369c18d00a68 Mon Sep 17 00:00:00 2001 From: kisernl Date: Tue, 3 Feb 2026 10:54:56 -0600 Subject: [PATCH 1/6] initial commit --- .gitignore | 2 + docs/deploy/computesdk.mdx | 111 ++++++++++++ examples/computesdk/package.json | 21 +++ examples/computesdk/src/computesdk.ts | 81 +++++++++ examples/computesdk/tests/computesdk.test.ts | 28 +++ examples/computesdk/tsconfig.json | 16 ++ pnpm-lock.yaml | 177 ++++++++++++++++--- 7 files changed, 407 insertions(+), 29 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/.gitignore b/.gitignore index e983e764..3dc15836 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ Cargo.lock # CLI binaries (downloaded during npm publish) sdks/cli/platforms/*/bin/ + +computesdk.txt \ No newline at end of file diff --git a/docs/deploy/computesdk.mdx b/docs/deploy/computesdk.mdx new file mode 100644 index 00000000..d1ba9a47 --- /dev/null +++ b/docs/deploy/computesdk.mdx @@ -0,0 +1,111 @@ +--- +title: "ComputeSDK" +description: "Deploy the daemon inside a ComputeSDK sandbox." +--- + +## Overview + +ComputeSDK is a meta-SDK that provides a unified interface across multiple sandbox providers (E2B, Vercel, Modal, Railway, Daytona, and more). You can switch providers by changing environment variables without modifying your code. + +## Prerequisites + +- `COMPUTESDK_API_KEY` environment variable (get one at [console.computesdk.com](https://console.computesdk.com/register)) +- A provider API key (e.g., `E2B_API_KEY`, `VERCEL_TOKEN`, `DAYTONA_API_KEY`) +- `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` for the coding agents + +## TypeScript Example + +```typescript +import { compute } from "computesdk"; +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 (auto-detects provider from environment variables) +const sandbox = await compute.sandbox.create(); + +// Install sandbox-agent +await sandbox.runCommand( + "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh" +); + +// Install agents before starting the server +await sandbox.runCommand("sandbox-agent install-agent claude"); +await sandbox.runCommand("sandbox-agent install-agent codex"); + +// Start the server in the background +await sandbox.runCommand( + `ANTHROPIC_API_KEY=${envs.ANTHROPIC_API_KEY || ""} OPENAI_API_KEY=${envs.OPENAI_API_KEY || ""} sandbox-agent server --no-token --host 0.0.0.0 --port 3000`, + { background: true } +); + +// Connect to the server +const baseUrl = await sandbox.getUrl({ port: 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.destroy(); +``` + +## Provider Flexibility + +ComputeSDK automatically detects your provider based on environment variables. To switch providers, simply change which API key you set: + +```bash +# Use E2B +export E2B_API_KEY=your_e2b_key + +# Or use Vercel +export VERCEL_TOKEN=your_vercel_token +export VERCEL_TEAM_ID=your_team_id +export VERCEL_PROJECT_ID=your_project_id + +# Or use Daytona +export DAYTONA_API_KEY=your_daytona_key + +# And always set ComputeSDK key +export COMPUTESDK_API_KEY=your_computesdk_key +``` + +Your code stays the same regardless of which provider you choose. + +## Supported Providers + +ComputeSDK supports the following providers: +- E2B +- Vercel +- Daytona +- Modal +- Railway +- Render +- Blaxel +- Namespace + +See the [ComputeSDK documentation](https://computesdk.com/docs) for provider-specific setup instructions. diff --git a/examples/computesdk/package.json b/examples/computesdk/package.json new file mode 100644 index 00000000..6d337b96 --- /dev/null +++ b/examples/computesdk/package.json @@ -0,0 +1,21 @@ +{ + "name": "@sandbox-agent/example-computesdk", + "private": true, + "type": "module", + "scripts": { + "start": "tsx src/computesdk.ts", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "computesdk": "latest", + "dotenv": "^16.0.0", + "@sandbox-agent/example-shared": "workspace:*", + "sandbox-agent": "workspace:*" + }, + "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 00000000..e846a9db --- /dev/null +++ b/examples/computesdk/src/computesdk.ts @@ -0,0 +1,81 @@ +import "dotenv/config"; +import { compute } from "computesdk"; +import { runPrompt, waitForHealth } from "@sandbox-agent/example-shared"; + +export async function setupComputeSDKSandboxAgent() { + 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; + + console.log("Creating ComputeSDK sandbox..."); + const sandbox = await compute.sandbox.create({ envs }); + + const run = async (cmd: string) => { + const result = await sandbox.runCommand(cmd); + if (result.exitCode !== 0) throw new Error(`Command failed: ${cmd}\n${result.stderr}`); + return result; + }; + + console.log("Installing sandbox-agent..."); + // Install to ~/.local/bin for sandboxes without sudo + await run("mkdir -p ~/.local/bin"); + await run("curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | BIN_DIR=~/.local/bin sh"); + + console.log("Installing agents..."); + await run("~/.local/bin/sandbox-agent install-agent claude"); + await run("~/.local/bin/sandbox-agent install-agent codex"); + + console.log("Starting server..."); + await sandbox.runCommand("~/.local/bin/sandbox-agent server --no-token --host 0.0.0.0 --port 3000", { + background: true, + env: envs, + }); + + const baseUrl = await sandbox.getUrl({ port: 3000 }); + + console.log("Waiting for server..."); + await waitForHealth({ baseUrl }); + + const cleanup = async () => { + await sandbox.destroy(); + }; + + return { baseUrl, token: undefined, cleanup }; +} + +// Run interactively when executed directly +const isMain = import.meta.url === `file://${process.argv[1]}`; +if (isMain) { + const { baseUrl, cleanup } = await setupComputeSDKSandboxAgent(); + + let isCleaningUp = false; + const exitCleanup = async () => { + if (isCleaningUp) return; + isCleaningUp = true; + console.log("\nDestroying sandbox..."); + try { + await cleanup(); + console.log("Sandbox destroyed."); + } catch (err) { + console.error("Failed to destroy sandbox:", err); + } + process.exit(0); + }; + + process.on("SIGINT", () => { + void exitCleanup(); + }); + process.on("SIGTERM", () => { + void exitCleanup(); + }); + + try { + await runPrompt(baseUrl); + } catch (err: unknown) { + // Ignore AbortError from Ctrl+C + if (err instanceof Error && err.name !== "AbortError") { + console.error("Error:", err.message); + } + } + await exitCleanup(); +} diff --git a/examples/computesdk/tests/computesdk.test.ts b/examples/computesdk/tests/computesdk.test.ts new file mode 100644 index 00000000..8d418d8d --- /dev/null +++ b/examples/computesdk/tests/computesdk.test.ts @@ -0,0 +1,28 @@ +import { describe, it, expect } from "vitest"; +import { buildHeaders } from "@sandbox-agent/example-shared"; +import { setupComputeSDKSandboxAgent } from "../src/computesdk.ts"; + +const shouldRun = Boolean(process.env.COMPUTESDK_API_KEY); +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, token, cleanup } = await setupComputeSDKSandboxAgent(); + 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/computesdk/tsconfig.json b/examples/computesdk/tsconfig.json new file mode 100644 index 00000000..96ba2fdb --- /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 f384d735..31a5c0e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,35 @@ importers: version: 2.7.6 vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@25.1.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@25.2.0) + + examples/computesdk: + dependencies: + '@sandbox-agent/example-shared': + specifier: workspace:* + version: link:../shared + computesdk: + specifier: latest + version: 2.0.2 + dotenv: + specifier: ^16.0.0 + version: 16.6.1 + sandbox-agent: + specifier: workspace:* + version: link:../../sdks/typescript + devDependencies: + '@types/node': + specifier: latest + version: 25.2.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.2.0) examples/daytona: dependencies: @@ -142,7 +170,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.1.0)) + version: 4.7.0(vite@5.4.21(@types/node@25.2.0)) sandbox-agent: specifier: workspace:* version: link:../../../sdks/typescript @@ -151,19 +179,19 @@ importers: version: 5.9.3 vite: specifier: ^5.4.7 - version: 5.4.21(@types/node@25.1.0) + version: 5.4.21(@types/node@25.2.0) frontend/packages/website: dependencies: '@astrojs/react': specifier: ^4.2.0 - 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) + version: 4.4.2(@types/node@25.2.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.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)) + version: 6.0.2(astro@5.16.15(@types/node@25.2.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.1.0)(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.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) @@ -304,7 +332,7 @@ importers: devDependencies: vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@25.1.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@25.2.0) sdks/cli/platforms/darwin-arm64: {} @@ -657,6 +685,9 @@ packages: resolution: {integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==} engines: {node: '>=18'} + '@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: @@ -1898,6 +1929,9 @@ packages: '@types/node@25.1.0': resolution: {integrity: sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==} + '@types/node@25.2.0': + resolution: {integrity: sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==} + '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} @@ -2260,6 +2294,9 @@ packages: compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + computesdk@2.0.2: + resolution: {integrity: sha512-VvxvzCSo/gW0BRF6wdMuvw6Fhw4uB9o13v/fv8kIm+qDjs/7iugsyfNk716SzFJA3MwN6awK4VvKuoAUXqU7eA==} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -2393,6 +2430,10 @@ packages: domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + dotenv@17.2.3: resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} engines: {node: '>=12'} @@ -4223,15 +4264,15 @@ snapshots: dependencies: prismjs: 1.30.0 - '@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)': + '@astrojs/react@4.4.2(@types/node@25.2.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.1.0)(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.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.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@25.2.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -4246,9 +4287,9 @@ snapshots: - tsx - yaml - '@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))': + '@astrojs/tailwind@6.0.2(astro@5.16.15(@types/node@25.2.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.1.0)(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.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) @@ -4932,6 +4973,8 @@ snapshots: dependencies: fontkitten: 1.0.2 + '@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 @@ -5966,7 +6009,7 @@ snapshots: '@types/dockerode@4.0.1': dependencies: '@types/docker-modem': 3.0.6 - '@types/node': 25.0.10 + '@types/node': 24.10.9 '@types/ssh2': 1.15.5 '@types/estree@1.0.8': {} @@ -6007,6 +6050,10 @@ snapshots: dependencies: undici-types: 7.16.0 + '@types/node@25.2.0': + dependencies: + undici-types: 7.16.0 + '@types/prop-types@15.7.15': {} '@types/react-dom@18.3.7(@types/react@18.3.27)': @@ -6053,7 +6100,7 @@ snapshots: - bare-abort-controller - react-native-b4a - '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@25.1.0))': + '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@25.2.0))': dependencies: '@babel/core': 7.28.6 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.6) @@ -6061,11 +6108,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.1.0) + vite: 5.4.21(@types/node@25.2.0) transitivePeerDependencies: - supports-color - '@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))': + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.2.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) @@ -6073,7 +6120,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.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@25.2.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -6085,13 +6132,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@25.1.0))': + '@vitest/mocker@3.2.4(vite@5.4.21(@types/node@25.2.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.1.0) + vite: 5.4.21(@types/node@25.2.0) '@vitest/pretty-format@3.2.4': dependencies: @@ -6158,7 +6205,7 @@ snapshots: assertion-error@2.0.1: {} - 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): + astro@5.16.15(@types/node@25.2.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 @@ -6215,8 +6262,8 @@ snapshots: unist-util-visit: 5.1.0 unstorage: 1.17.4 vfile: 6.0.3 - 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)) + vite: 6.4.1(@types/node@25.2.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + vitefu: 1.1.1(vite@6.4.1(@types/node@25.2.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 @@ -6482,6 +6529,10 @@ snapshots: compare-versions@6.1.1: {} + computesdk@2.0.2: + dependencies: + '@computesdk/cmd': 0.4.1 + confbox@0.1.8: {} consola@3.4.2: {} @@ -6617,6 +6668,8 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 + dotenv@16.6.1: {} + dotenv@17.2.3: {} dset@3.1.4: {} @@ -8551,6 +8604,24 @@ snapshots: - supports-color - terser + vite-node@3.2.4(@types/node@25.2.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.2.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 @@ -8578,7 +8649,16 @@ snapshots: '@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): + vite@5.4.21(@types/node@25.2.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.6 + rollup: 4.56.0 + optionalDependencies: + '@types/node': 25.2.0 + fsevents: 2.3.3 + + vite@6.4.1(@types/node@25.2.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) @@ -8587,21 +8667,21 @@ snapshots: rollup: 4.56.0 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.1.0 + '@types/node': 25.2.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.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.2.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2)): optionalDependencies: - vite: 6.4.1(@types/node@25.1.0)(jiti@1.21.7)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@25.2.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.1.0)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.2.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -8640,7 +8720,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.1.0)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.2.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -8679,7 +8759,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.1.0)) + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.2.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -8714,6 +8794,45 @@ snapshots: - supports-color - terser + vitest@3.2.4(@types/debug@4.1.12)(@types/node@25.2.0): + dependencies: + '@types/chai': 5.2.3 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@5.4.21(@types/node@25.2.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.2.0) + vite-node: 3.2.4(@types/node@25.2.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 25.2.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: {} From 920f0098aef9555d90b1887b1d8d4793e7062ef7 Mon Sep 17 00:00:00 2001 From: kisernl Date: Wed, 4 Feb 2026 20:07:32 -0500 Subject: [PATCH 2/6] feat: add in computesdk server --- examples/computesdk/src/computesdk.ts | 87 ++++++++++++++++++++------- 1 file changed, 66 insertions(+), 21 deletions(-) diff --git a/examples/computesdk/src/computesdk.ts b/examples/computesdk/src/computesdk.ts index e846a9db..b1f01572 100644 --- a/examples/computesdk/src/computesdk.ts +++ b/examples/computesdk/src/computesdk.ts @@ -1,6 +1,6 @@ import "dotenv/config"; import { compute } from "computesdk"; -import { runPrompt, waitForHealth } from "@sandbox-agent/example-shared"; +import { runPrompt } from "@sandbox-agent/example-shared"; export async function setupComputeSDKSandboxAgent() { const envs: Record = {}; @@ -10,31 +10,76 @@ export async function setupComputeSDKSandboxAgent() { console.log("Creating ComputeSDK sandbox..."); const sandbox = await compute.sandbox.create({ envs }); - const run = async (cmd: string) => { - const result = await sandbox.runCommand(cmd); - if (result.exitCode !== 0) throw new Error(`Command failed: ${cmd}\n${result.stderr}`); - return result; - }; + console.log("Starting sandbox-agent server..."); + const server = await sandbox.server.start({ + slug: "sandbox-agent", + // Install commands run first (blocking) + install: + "mkdir -p ~/.local/bin && " + + "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | BIN_DIR=~/.local/bin sh && " + + "~/.local/bin/sandbox-agent install-agent claude && " + + "~/.local/bin/sandbox-agent install-agent codex", + // Start command runs after install completes + start: "~/.local/bin/sandbox-agent server --no-token --host 0.0.0.0 --port 3000", + port: 3000, + environment: envs, + // Built-in health check - status becomes 'ready' only after this passes + health_check: { + path: "/v1/health", + interval_ms: 2000, + timeout_ms: 5000, + delay_ms: 3000, + }, + restart_policy: "on-failure", + max_restarts: 3, + }); - console.log("Installing sandbox-agent..."); - // Install to ~/.local/bin for sandboxes without sudo - await run("mkdir -p ~/.local/bin"); - await run("curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | BIN_DIR=~/.local/bin sh"); + // Wait for server to be ready or running with URL + console.log("Waiting for server to be ready..."); + let currentServer = server; + let baseUrl: string | undefined; + const maxAttempts = 60; + let attempts = 0; - console.log("Installing agents..."); - await run("~/.local/bin/sandbox-agent install-agent claude"); - await run("~/.local/bin/sandbox-agent install-agent codex"); + while (attempts < maxAttempts) { + await new Promise((r) => setTimeout(r, 1000)); + currentServer = await sandbox.server.retrieve("sandbox-agent"); + console.log(`Server status: ${currentServer.status}, url: ${currentServer.url || "not available"}`); - console.log("Starting server..."); - await sandbox.runCommand("~/.local/bin/sandbox-agent server --no-token --host 0.0.0.0 --port 3000", { - background: true, - env: envs, - }); + // If we have a URL and status is running or ready, try to use it + if (currentServer.url && (currentServer.status === "running" || currentServer.status === "ready")) { + baseUrl = currentServer.url; + // Try a manual health check + try { + const healthResp = await fetch(`${baseUrl}/v1/health`, { signal: AbortSignal.timeout(5000) }); + if (healthResp.ok) { + console.log("Health check passed!"); + break; + } + } catch { + // Health check failed, keep waiting + } + } + + // Check for failure states + if (currentServer.status === "failed" || currentServer.status === "stopped") { + const logs = await sandbox.server.logs("sandbox-agent"); + console.error("Server logs:", logs.logs); + throw new Error(`Server failed to start: ${currentServer.status}`); + } - const baseUrl = await sandbox.getUrl({ port: 3000 }); + attempts++; + } - console.log("Waiting for server..."); - await waitForHealth({ baseUrl }); + if (!baseUrl) { + // Fallback: try to get URL directly from sandbox + baseUrl = await sandbox.getUrl({ port: 3000 }); + console.log(`Using fallback URL: ${baseUrl}`); + } + + if (!baseUrl) { + throw new Error("Could not obtain server URL"); + } const cleanup = async () => { await sandbox.destroy(); From 57859ca2fd8975513e8a7d0e978e0b693754cb26 Mon Sep 17 00:00:00 2001 From: Garrison Snelling Date: Thu, 5 Feb 2026 10:12:00 -0600 Subject: [PATCH 3/6] refactor: simplify computesdk example to match e2b pattern --- .gitignore | 2 +- docs/deploy/computesdk.mdx | 46 +++++------ examples/computesdk/src/computesdk.ts | 115 +++++++------------------- 3 files changed, 51 insertions(+), 112 deletions(-) diff --git a/.gitignore b/.gitignore index 3dc15836..77e99be2 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,4 @@ Cargo.lock # CLI binaries (downloaded during npm publish) sdks/cli/platforms/*/bin/ -computesdk.txt \ No newline at end of file +computesdk.txt diff --git a/docs/deploy/computesdk.mdx b/docs/deploy/computesdk.mdx index d1ba9a47..fd6fd5c4 100644 --- a/docs/deploy/computesdk.mdx +++ b/docs/deploy/computesdk.mdx @@ -24,37 +24,33 @@ 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 (auto-detects provider from environment variables) -const sandbox = await compute.sandbox.create(); - -// Install sandbox-agent -await sandbox.runCommand( - "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh" -); - -// Install agents before starting the server -await sandbox.runCommand("sandbox-agent install-agent claude"); -await sandbox.runCommand("sandbox-agent install-agent codex"); - -// Start the server in the background -await sandbox.runCommand( - `ANTHROPIC_API_KEY=${envs.ANTHROPIC_API_KEY || ""} OPENAI_API_KEY=${envs.OPENAI_API_KEY || ""} sandbox-agent server --no-token --host 0.0.0.0 --port 3000`, - { background: true } -); +// Create sandbox with sandbox-agent server pre-configured +const sandbox = await compute.sandbox.create({ + envs, + servers: [ + { + slug: "sandbox-agent", + install: + "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh && " + + "sandbox-agent install-agent claude && " + + "sandbox-agent install-agent codex", + start: "sandbox-agent server --no-token --host 0.0.0.0 --port 3000", + port: 3000, + environment: envs, + health_check: { + path: "/v1/health", + interval_ms: 2000, + }, + }, + ], +}); // Connect to the server const baseUrl = await sandbox.getUrl({ port: 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)); - } -} +await client.waitForHealth(); // Create a session and start coding await client.createSession("my-session", { diff --git a/examples/computesdk/src/computesdk.ts b/examples/computesdk/src/computesdk.ts index b1f01572..3139e293 100644 --- a/examples/computesdk/src/computesdk.ts +++ b/examples/computesdk/src/computesdk.ts @@ -1,6 +1,6 @@ import "dotenv/config"; import { compute } from "computesdk"; -import { runPrompt } from "@sandbox-agent/example-shared"; +import { runPrompt, waitForHealth } from "@sandbox-agent/example-shared"; export async function setupComputeSDKSandboxAgent() { const envs: Record = {}; @@ -8,78 +8,34 @@ export async function setupComputeSDKSandboxAgent() { if (process.env.OPENAI_API_KEY) envs.OPENAI_API_KEY = process.env.OPENAI_API_KEY; console.log("Creating ComputeSDK sandbox..."); - const sandbox = await compute.sandbox.create({ envs }); - - console.log("Starting sandbox-agent server..."); - const server = await sandbox.server.start({ - slug: "sandbox-agent", - // Install commands run first (blocking) - install: - "mkdir -p ~/.local/bin && " + - "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | BIN_DIR=~/.local/bin sh && " + - "~/.local/bin/sandbox-agent install-agent claude && " + - "~/.local/bin/sandbox-agent install-agent codex", - // Start command runs after install completes - start: "~/.local/bin/sandbox-agent server --no-token --host 0.0.0.0 --port 3000", - port: 3000, - environment: envs, - // Built-in health check - status becomes 'ready' only after this passes - health_check: { - path: "/v1/health", - interval_ms: 2000, - timeout_ms: 5000, - delay_ms: 3000, - }, - restart_policy: "on-failure", - max_restarts: 3, + const sandbox = await compute.sandbox.create({ + envs, + servers: [ + { + slug: "sandbox-agent", + install: + "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh && " + + "sandbox-agent install-agent claude && " + + "sandbox-agent install-agent codex", + start: "sandbox-agent server --no-token --host 0.0.0.0 --port 3000", + port: 3000, + environment: envs, + health_check: { + path: "/v1/health", + interval_ms: 2000, + timeout_ms: 5000, + delay_ms: 3000, + }, + restart_policy: "on-failure", + max_restarts: 3, + }, + ], }); - // Wait for server to be ready or running with URL - console.log("Waiting for server to be ready..."); - let currentServer = server; - let baseUrl: string | undefined; - const maxAttempts = 60; - let attempts = 0; - - while (attempts < maxAttempts) { - await new Promise((r) => setTimeout(r, 1000)); - currentServer = await sandbox.server.retrieve("sandbox-agent"); - console.log(`Server status: ${currentServer.status}, url: ${currentServer.url || "not available"}`); - - // If we have a URL and status is running or ready, try to use it - if (currentServer.url && (currentServer.status === "running" || currentServer.status === "ready")) { - baseUrl = currentServer.url; - // Try a manual health check - try { - const healthResp = await fetch(`${baseUrl}/v1/health`, { signal: AbortSignal.timeout(5000) }); - if (healthResp.ok) { - console.log("Health check passed!"); - break; - } - } catch { - // Health check failed, keep waiting - } - } - - // Check for failure states - if (currentServer.status === "failed" || currentServer.status === "stopped") { - const logs = await sandbox.server.logs("sandbox-agent"); - console.error("Server logs:", logs.logs); - throw new Error(`Server failed to start: ${currentServer.status}`); - } - - attempts++; - } - - if (!baseUrl) { - // Fallback: try to get URL directly from sandbox - baseUrl = await sandbox.getUrl({ port: 3000 }); - console.log(`Using fallback URL: ${baseUrl}`); - } + const baseUrl = await sandbox.getUrl({ port: 3000 }); - if (!baseUrl) { - throw new Error("Could not obtain server URL"); - } + console.log("Waiting for server..."); + await waitForHealth({ baseUrl }); const cleanup = async () => { await sandbox.destroy(); @@ -93,31 +49,18 @@ const isMain = import.meta.url === `file://${process.argv[1]}`; if (isMain) { const { baseUrl, cleanup } = await setupComputeSDKSandboxAgent(); - let isCleaningUp = false; const exitCleanup = async () => { - if (isCleaningUp) return; - isCleaningUp = true; console.log("\nDestroying sandbox..."); - try { - await cleanup(); - console.log("Sandbox destroyed."); - } catch (err) { - console.error("Failed to destroy sandbox:", err); - } + await cleanup(); process.exit(0); }; - process.on("SIGINT", () => { - void exitCleanup(); - }); - process.on("SIGTERM", () => { - void exitCleanup(); - }); + process.on("SIGINT", () => void exitCleanup()); + process.on("SIGTERM", () => void exitCleanup()); try { await runPrompt(baseUrl); } catch (err: unknown) { - // Ignore AbortError from Ctrl+C if (err instanceof Error && err.name !== "AbortError") { console.error("Error:", err.message); } From e0bf814854d753c0d8974f32803cdc1ddcac8ee8 Mon Sep 17 00:00:00 2001 From: Garrison Snelling Date: Thu, 5 Feb 2026 10:19:35 -0600 Subject: [PATCH 4/6] refactor: match e2b example structure exactly --- examples/computesdk/src/computesdk.ts | 106 ++++++++++---------------- 1 file changed, 42 insertions(+), 64 deletions(-) diff --git a/examples/computesdk/src/computesdk.ts b/examples/computesdk/src/computesdk.ts index 3139e293..1d9e2dd6 100644 --- a/examples/computesdk/src/computesdk.ts +++ b/examples/computesdk/src/computesdk.ts @@ -2,68 +2,46 @@ import "dotenv/config"; import { compute } from "computesdk"; import { runPrompt, waitForHealth } from "@sandbox-agent/example-shared"; -export async function setupComputeSDKSandboxAgent() { - 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; - - console.log("Creating ComputeSDK sandbox..."); - const sandbox = await compute.sandbox.create({ - envs, - servers: [ - { - slug: "sandbox-agent", - install: - "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh && " + - "sandbox-agent install-agent claude && " + - "sandbox-agent install-agent codex", - start: "sandbox-agent server --no-token --host 0.0.0.0 --port 3000", - port: 3000, - environment: envs, - health_check: { - path: "/v1/health", - interval_ms: 2000, - timeout_ms: 5000, - delay_ms: 3000, - }, - restart_policy: "on-failure", - max_restarts: 3, +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; + +console.log("Creating ComputeSDK sandbox..."); +const sandbox = await compute.sandbox.create({ + envs, + servers: [ + { + slug: "sandbox-agent", + install: + "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh && " + + "sandbox-agent install-agent claude && " + + "sandbox-agent install-agent codex", + start: "sandbox-agent server --no-token --host 0.0.0.0 --port 3000", + port: 3000, + environment: envs, + health_check: { + path: "/v1/health", + interval_ms: 2000, + timeout_ms: 5000, + delay_ms: 3000, }, - ], - }); - - const baseUrl = await sandbox.getUrl({ port: 3000 }); - - console.log("Waiting for server..."); - await waitForHealth({ baseUrl }); - - const cleanup = async () => { - await sandbox.destroy(); - }; - - return { baseUrl, token: undefined, cleanup }; -} - -// Run interactively when executed directly -const isMain = import.meta.url === `file://${process.argv[1]}`; -if (isMain) { - const { baseUrl, cleanup } = await setupComputeSDKSandboxAgent(); - - const exitCleanup = async () => { - console.log("\nDestroying sandbox..."); - await cleanup(); - process.exit(0); - }; - - process.on("SIGINT", () => void exitCleanup()); - process.on("SIGTERM", () => void exitCleanup()); - - try { - await runPrompt(baseUrl); - } catch (err: unknown) { - if (err instanceof Error && err.name !== "AbortError") { - console.error("Error:", err.message); - } - } - await exitCleanup(); -} + restart_policy: "on-failure", + max_restarts: 3, + }, + ], +}); + +const baseUrl = await sandbox.getUrl({ port: 3000 }); + +console.log("Waiting for server..."); +await waitForHealth({ baseUrl }); + +const cleanup = async () => { + await sandbox.destroy(); + process.exit(0); +}; +process.once("SIGINT", cleanup); +process.once("SIGTERM", cleanup); + +await runPrompt(baseUrl); +await cleanup(); From 2b1b763b519a6d87d027d228a90c20b920c0eb85 Mon Sep 17 00:00:00 2001 From: Garrison Snelling Date: Thu, 5 Feb 2026 10:20:44 -0600 Subject: [PATCH 5/6] chore: reset .gitignore to main --- .gitignore | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.gitignore b/.gitignore index 77e99be2..50db9728 100644 --- a/.gitignore +++ b/.gitignore @@ -39,8 +39,3 @@ npm-debug.log* # Rust Cargo.lock **/*.rs.bk - -# CLI binaries (downloaded during npm publish) -sdks/cli/platforms/*/bin/ - -computesdk.txt From e3c63bd2da5272a55f036e2e1092374101540b28 Mon Sep 17 00:00:00 2001 From: kisernl Date: Wed, 11 Feb 2026 11:53:58 -0600 Subject: [PATCH 6/6] fix: add sandbox-agent to PATH in computesdk example --- examples/computesdk/package.json | 2 +- examples/computesdk/src/computesdk.ts | 4 +++- pnpm-lock.yaml | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/examples/computesdk/package.json b/examples/computesdk/package.json index 6d337b96..1447dcf5 100644 --- a/examples/computesdk/package.json +++ b/examples/computesdk/package.json @@ -7,7 +7,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "computesdk": "latest", + "computesdk": "^2.2.0", "dotenv": "^16.0.0", "@sandbox-agent/example-shared": "workspace:*", "sandbox-agent": "workspace:*" diff --git a/examples/computesdk/src/computesdk.ts b/examples/computesdk/src/computesdk.ts index 1d9e2dd6..9120fc96 100644 --- a/examples/computesdk/src/computesdk.ts +++ b/examples/computesdk/src/computesdk.ts @@ -13,10 +13,12 @@ const sandbox = await compute.sandbox.create({ { slug: "sandbox-agent", install: + "export BIN_DIR=$HOME/.local/bin && " + "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh && " + + "export PATH=$BIN_DIR:$PATH && " + "sandbox-agent install-agent claude && " + "sandbox-agent install-agent codex", - start: "sandbox-agent server --no-token --host 0.0.0.0 --port 3000", + start: "export PATH=$HOME/.local/bin:$PATH && sandbox-agent server --no-token --host 0.0.0.0 --port 3000", port: 3000, environment: envs, health_check: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 31a5c0e7..b00efc21 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,8 +21,8 @@ importers: specifier: workspace:* version: link:../shared computesdk: - specifier: latest - version: 2.0.2 + specifier: ^2.2.0 + version: 2.2.0 dotenv: specifier: ^16.0.0 version: 16.6.1 @@ -2294,8 +2294,8 @@ packages: compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} - computesdk@2.0.2: - resolution: {integrity: sha512-VvxvzCSo/gW0BRF6wdMuvw6Fhw4uB9o13v/fv8kIm+qDjs/7iugsyfNk716SzFJA3MwN6awK4VvKuoAUXqU7eA==} + computesdk@2.2.0: + resolution: {integrity: sha512-gAAL8vMLkYUFH138OwbebTG9AYMh4RudhRvYboJvRdc9NQAafVHfvZtPwg4YVKPB3VpsfK5m9pkgv60Xr2cE1g==} confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -6529,7 +6529,7 @@ snapshots: compare-versions@6.1.1: {} - computesdk@2.0.2: + computesdk@2.2.0: dependencies: '@computesdk/cmd': 0.4.1