### Setup Environment File Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/examples/basic/README.md Copy the example environment file before editing it with your credentials. ```bash cp .env.example .env # edit .env with your actual keys ``` -------------------------------- ### Install and Run Development Server Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/collaborative-terminal/README.md Installs project dependencies and starts the local development server. Access the application at http://localhost:5173. ```bash npm install npm run dev ``` -------------------------------- ### Run Development Server Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/websocket-tunnel/README.md Starts the local development server for the WebSocket tunnel example. Navigate to the example directory first. ```bash cd examples/websocket-tunnel npm run dev ``` -------------------------------- ### Clone and Setup Repository Source: https://github.com/cloudflare/sandbox-sdk/blob/main/CONTRIBUTING.md Initial steps to clone the repository and install dependencies. ```bash git clone https://github.com/YOUR-USERNAME/sandbox-sdk.git cd sandbox-sdk ``` ```bash npm install ``` ```bash npm run build ``` ```bash npm test ``` -------------------------------- ### Install Dependencies and Run Development Server Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/authentication/README.md Installs project dependencies and starts the development server. Ensure you have added your secrets to the .dev.vars file. ```bash cp .dev.vars.example .dev.vars # Add your secrets npm install npm run dev ``` -------------------------------- ### Run Locally Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/code-interpreter/README.md Navigate to the example directory and start the development server using npm. ```bash cd examples/code-interpreter npm run dev ``` -------------------------------- ### Local Development Setup Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/worker/README.md Commands to set up the development environment locally. This includes installing dependencies, copying environment variables, and starting the development server. ```sh npm ci cp .dev.vars.example .dev.vars # Edit .dev.vars and set SANDBOX_API_KEY (generate one with: openssl rand -hex 32) npm run dev ``` -------------------------------- ### Project Setup and Build Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/code-interpreter/README.md Install dependencies and build the project from the root directory using npm. ```bash npm install npm run build ``` -------------------------------- ### Local Development Setup Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/codex-app-server/README.md Steps to set up the project for local development, including copying environment variables and installing dependencies. ```bash cp .dev.vars.example .dev.vars # add your OPENAI_API_KEY npm install npm run dev ``` -------------------------------- ### Basic Dockerfile Setup Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/STANDALONE_BINARY.md Use this Dockerfile to install the 'file' utility and copy the sandbox binary into your image. This is suitable for most glibc-based images. ```dockerfile FROM node:24-slim # Required: install 'file' for SDK file operations RUN apt-get update && apt-get install -y --no-install-recommends file \ && rm -rf /var/lib/apt/lists/* COPY --from=cloudflare/sandbox:latest /container-server/sandbox /sandbox ENTRYPOINT ["/sandbox"] CMD ["/your-startup-script.sh"] # Optional: runs after server starts ``` -------------------------------- ### Copy Environment File Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/harness/README.md Copy the example environment file to start configuring the harness. Fill in all required values in the new .env file. ```bash cp .env.example .env # Fill in all values in .env ``` -------------------------------- ### Install Dependencies and Build Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/websocket-tunnel/README.md Installs project dependencies and builds the application. Run this from the project root. ```bash npm install npm run build ``` -------------------------------- ### Start Workspace Chat Servers Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/examples/workspace-chat/README.md Quickly start both the backend and frontend servers for the workspace chat application. This command handles prerequisite checks and dependency installation. ```bash cp backend/.env.example backend/.env # edit backend/.env with your actual keys script/start ``` -------------------------------- ### Run Frontend Server Manually Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/examples/workspace-chat/README.md Manually start the React frontend development server. This command installs Node.js dependencies and starts the Vite dev server. ```bash cd frontend npm install npm run dev # http://localhost:5173 ``` -------------------------------- ### Start Development Server Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/openai-agents/README.md Launch the local development environment. ```bash npm start ``` -------------------------------- ### Install and Build Sandbox SDK Source: https://github.com/cloudflare/sandbox-sdk/blob/main/README.md Clone the repository, install Node.js dependencies, run tests, and build the project. ```bash git clone https://github.com/cloudflare/sandbox-sdk cd sandbox-sdk npm install npm test npm run build npm run check ``` -------------------------------- ### Start Vite Development Server Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/vite-sandbox/README.md Run this command to start the host Vite development server. ```bash npm start ``` -------------------------------- ### Install and Build Cloudflare Sandbox SDK Source: https://github.com/cloudflare/sandbox-sdk/blob/main/packages/sandbox/README.md Clone the repository, install dependencies, run tests, build the project, and perform type checking and linting for the Cloudflare Sandbox SDK. ```bash git clone https://github.com/cloudflare/sandbox-sdk cd sandbox-sdk npm install npm test npm run build npm run check ``` -------------------------------- ### Alpine/musl Dockerfile Setup Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/STANDALONE_BINARY.md For Alpine or musl-based images, use the '-musl' image variant or copy the musl binary. Ensure all necessary dependencies like bash, file, git, libstdc++, libgcc, s3fs-fuse, and fuse are installed. ```dockerfile FROM docker.io/cloudflare/sandbox:latest-musl ``` ```dockerfile FROM alpine:3.21 # libstdc++ and libgcc are required by the Bun runtime embedded in the binary # s3fs-fuse and fuse are needed for mountBucket() support RUN apk add --no-cache bash file git libstdc++ libgcc s3fs-fuse fuse COPY --from=docker.io/cloudflare/sandbox:latest-musl /container-server/sandbox /sandbox ENTRYPOINT ["/sandbox"] ``` -------------------------------- ### Run Development Server Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/minimal/README.md Commands to start the local development environment. ```bash cd examples/minimal # if you're not already here npm run dev ``` -------------------------------- ### Sandbox SDK Worker Example Source: https://github.com/cloudflare/sandbox-sdk/blob/main/README.md A comprehensive TypeScript example demonstrating how to integrate the Sandbox SDK into a Cloudflare Worker. It includes setup for proxying, executing commands, and file operations. ```typescript import { getSandbox, proxyToSandbox, type Sandbox } from '@cloudflare/sandbox'; export { Sandbox } from '@cloudflare/sandbox'; type Env = { Sandbox: DurableObjectNamespace; }; export default { async fetch(request: Request, env: Env): Promise { // Required for preview URLs const proxyResponse = await proxyToSandbox(request, env); if (proxyResponse) return proxyResponse; const url = new URL(request.url); const sandbox = getSandbox(env.Sandbox, 'my-sandbox'); // Execute Python code if (url.pathname === '/run') { const result = await sandbox.exec('python3 -c "print(2 + 2)"'); return Response.json({ output: result.stdout, success: result.success }); } // Work with files if (url.pathname === '/file') { await sandbox.writeFile('/workspace/hello.txt', 'Hello, Sandbox!'); const file = await sandbox.readFile('/workspace/hello.txt'); return Response.json({ content: file.content }); } return new Response('Try /run or /file'); } }; ``` -------------------------------- ### Start Session and Initiate WebSocket Connection Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/codex-app-server/public/index.html Handles the process of starting a new session, storing session and repository details, and initiating the WebSocket connection. ```javascript function startSession() { const name = sfSession.value.trim(); if (!name) return; sessionName = name; repoUrl = sfRepo.value.trim(); localStorage.setItem('codex-session', name); localStorage.setItem('codex-repo', repoUrl); sfStatus.textContent = ''; sfStatus.className = 'status-line'; sfConnect.disabled = true; connect(); } ``` -------------------------------- ### Develop Cloudflare Sandbox Worker Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/AGENTS.md Navigate to the worker directory and install dependencies, then start the development server. ```sh cd worker npm ci npm run dev ``` -------------------------------- ### Install Dependencies Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/git-repo-per-sandbox/README.md Installs the necessary Node.js dependencies for the project. ```bash npm install ``` -------------------------------- ### Example Usage in a Shell Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/s3-mount/README.md This example shows how to interact with the mounted S3 bucket from within the worker's sandbox shell. Reads and writes directly hit the S3 bucket. ```bash POST /api/session xterm.js opens a WebSocket to /ws/terminal/:sandboxId `mountBucket()` drops a one-liner into `~/.bashrc`, so the shell lands you in `/mnt/s3` — every read/write you do is hitting the bucket directly. When you `exit` the shell (or close the tab), the page calls `POST /api/session/:sandboxId/cleanup` to unmount the bucket. The next click on Start spins up a brand-new sandbox. ``` -------------------------------- ### Copy Dev Variables Example Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/opencode/README.md Copy the example development variables file and edit it with your Anthropic API key. ```bash cp .dev.vars.example .dev.vars # Edit .dev.vars with your ANTHROPIC_API_KEY ``` -------------------------------- ### Setup Time Machine Project Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/time-machine/README.md Commands to set up the R2 bucket, enable local development flow, and run the project. ```bash wrangler r2 bucket create time-machine-snapshots cp .dev.vars.example .dev.vars npm install npm run dev ``` -------------------------------- ### Setup AWS Resources for Sandbox Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/s3-mount/README.md This script automates the creation of necessary AWS resources: an S3 bucket, an IAM role with S3 access, and an IAM user with permissions to assume that role. It simplifies the initial setup for mounting an S3 bucket with the Cloudflare Sandbox. ```bash #!/bin/bash # Exit immediately if a command exits with a non-zero status. set -e # --- Configuration --- # Default values, can be overridden by environment variables BUCKET_NAME=${BUCKET_NAME:-"sandbox-bucket-$(openssl rand -hex 4)"} ROLE_NAME=${ROLE_NAME:-"sandbox-role-$(openssl rand -hex 4)"} USER_NAME=${USER_NAME:-"sandbox-user-$(openssl rand -hex 4)"} REGION=${AWS_DEFAULT_REGION:-"us-east-1"} # --- Helper Functions --- log() { echo "[INFO] $1" } error() { echo "[ERROR] $1" >&2 exit 1 } # --- AWS CLI Checks --- log "Checking for AWS CLI..." if ! command -v aws &> /dev/null; then error "AWS CLI not found. Please install and configure it." fi log "Checking AWS credentials..." if ! aws sts get-caller-identity --query Arn --output text &> /dev/null; then error "AWS credentials not configured. Please configure them (e.g., run 'aws configure')." fi # --- Resource Creation --- # 1. Create S3 Bucket log "Creating S3 bucket: $BUCKET_NAME in region $REGION..." if aws s3api head-bucket --bucket "$BUCKET_NAME" --region "$REGION" 2>/dev/null; then log "Bucket '$BUCKET_NAME' already exists." else aws s3api create-bucket --bucket "$BUCKET_NAME" --region "$REGION" # Enable versioning for the bucket aws s3api put-bucket-versioning --bucket "$BUCKET_NAME" --versioning-configuration Status=Enabled log "Bucket '$BUCKET_NAME' created." fi # 2. Create IAM Role for the container log "Creating IAM role: $ROLE_NAME..." if aws iam get-role --role-name "$ROLE_NAME" --query 'Role.Arn' --output text &> /dev/null; then log "Role '$ROLE_NAME' already exists." else # Trust policy allowing EC2 instances (or Cloudflare Workers in this context) to assume this role TRUST_POLICY=$(cat < /dev/null; then log "User '$USER_NAME' already exists." else aws iam create-user --user-name "$USER_NAME" log "User '$USER_NAME' created." # Create access key for the user log "Creating access key for user '$USER_NAME'..." ACCESS_KEY_ID=$(aws iam create-access-key --user-name "$USER_NAME" --query 'AccessKey.AccessKeyId' --output text) SECRET_ACCESS_KEY=$(aws iam create-access-key --user-name "$USER_NAME" --query 'AccessKey.SecretAccessKey' --output text) log "Access key created for user '$USER_NAME'." # Attach policy to the user to allow assuming the role log "Attaching policy to user '$USER_NAME' to allow assuming role '$ROLE_NAME'..." POLICY_ARN=$(aws iam create-policy --policy-name "${USER_NAME}-assume-role-policy" --policy-document "$(cat < { startBtn.disabled = true; startBtn.textContent = 'Starting…'; setStatus(''); try { await runSession(); setStatus('Session ended.'); } catch (err) { console.error(err); setStatus(err.message ?? String(err), true); } finally { showLanding(); } }); ``` -------------------------------- ### Vitest Test Scenario Example Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/PERF_TESTING.md Example of writing a new performance test scenario using Vitest. It demonstrates setting up a PerfSandboxManager and MetricsCollector, creating sandboxes, timing operations, and asserting results. Ensure workerUrl is defined in the environment. ```typescript import { describe, test, beforeAll, afterAll } from 'vitest'; import { PerfSandboxManager } from '../helpers/perf-sandbox-manager'; import { MetricsCollector } from '../helpers/metrics-collector'; describe('My Scenario', () => { let manager: PerfSandboxManager; let metrics: MetricsCollector; beforeAll(async () => { manager = new PerfSandboxManager(workerUrl); metrics = new MetricsCollector('my-scenario'); }); afterAll(async () => { await manager.destroyAll(); metrics.printReport(); }); test('should measure something', async () => { const sandbox = await manager.createSandbox(); const latency = await metrics.timeAsync('operation', async () => { return sandbox.execute('echo test'); }); expect(latency).toBeLessThan(5000); }); }); ``` -------------------------------- ### Commit Message Example Source: https://github.com/cloudflare/sandbox-sdk/blob/main/CONTRIBUTING.md Standard format for commit messages following the 7 rules. ```text Add session isolation for concurrent executions Previously, multiple concurrent exec() calls would interfere with each other's working directories and environment variables. This adds proper session management to isolate execution contexts. ``` -------------------------------- ### Expose Jupyter Port in Sandbox Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/JUPYTER_NOTEBOOKS.md Example of using the Sandbox SDK to expose the Jupyter port to a preview URL. ```typescript import { getSandbox } from '@cloudflare/sandbox'; export default { async fetch(request, env) { const sandbox = getSandbox(env.Sandbox, 'jupyter-env'); // Expose Jupyter port const preview = await sandbox.exposePort(8888, { name: 'jupyter' }); return new Response(`Jupyter available at: ${preview.url}`); } }; ``` -------------------------------- ### Startup Script for Jupyter Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/JUPYTER_NOTEBOOKS.md Shell script to launch the Jupyter server in the background before starting the main container service. ```bash #!/bin/bash # Start Jupyter in background jupyter server --config=/root/.jupyter/jupyter_config.py & # Start the main sandbox service exec /container-server/startup.sh ``` -------------------------------- ### Cloudflare Worker Example with Sandbox Adapters Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/OPENAI_AGENTS.md A complete Cloudflare Worker implementation demonstrating the integration of Sandbox Shell and Editor adapters for agent execution. ```typescript import { getSandbox } from '@cloudflare/sandbox'; import { Shell, Editor } from '@cloudflare/sandbox/openai'; import { Agent, applyPatchTool, run, shellTool } from '@openai/agents'; async function handleRunRequest(request: Request, env: Env): Promise { try { const { input } = await request.json(); if (!input || typeof input !== 'string') { return new Response( JSON.stringify({ error: 'Missing or invalid input field' }), { status: 400, headers: { 'Content-Type': 'application/json' } } ); } // Get sandbox instance (reused for both shell and editor) const sandbox = getSandbox(env.Sandbox, 'workspace-session'); // Create adapters const shell = new Shell(sandbox); const editor = new Editor(sandbox, '/workspace'); // Create agent with tools const agent = new Agent({ name: 'Sandbox Studio', model: 'gpt-4', instructions: ` You can execute shell commands and edit files in the workspace. Use shell commands to inspect the repository and the apply_patch tool to create, update, or delete files. Keep responses concise and include command output when helpful. `, tools: [ shellTool({ shell, needsApproval: false }), applyPatchTool({ editor, needsApproval: false }) ] }); // Run the agent const result = await run(agent, input); // Format response with sorted results const response = { naturalResponse: result.finalOutput || null, commandResults: shell.results.sort((a, b) => a.timestamp - b.timestamp), fileOperations: editor.results.sort((a, b) => a.timestamp - b.timestamp) }; return new Response(JSON.stringify(response), { headers: { 'Content-Type': 'application/json' } }); } catch (error) { return new Response( JSON.stringify({ error: error instanceof Error ? error.message : 'Internal server error', naturalResponse: 'An error occurred while processing your request.', commandResults: [], fileOperations: [] }), { status: 500, headers: { 'Content-Type': 'application/json' } } ); } } export default { async fetch(request: Request, env: Env): Promise { const url = new URL(request.url); if (url.pathname === '/run' && request.method === 'POST') { return handleRunRequest(request, env); } return new Response('Not found', { status: 404 }); } }; ``` -------------------------------- ### Sending a POST Request to the Worker Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/claude-code/README.md This example demonstrates how to send a POST request to the worker endpoint with a repository URL and a task description. The response will contain logs and the diff. ```bash curl -X POST http://localhost:8787/ \ -H 'Content-Type: application/json' \ -d '{"repo": "https://github.com/owner/repo", "task": "fix the typo in README.md"}' ``` -------------------------------- ### Example Usage: Execute Specific Code Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/code-interpreter/README.md Use curl to send a prompt with explicit Python code to be executed via the /run endpoint. ```bash # Execute specific code curl -X POST http://localhost:8787/run \ -H "Content-Type: application/json" \ -d '{"input": "Execute this Python: print(sum(range(1, 101)))"}' ``` -------------------------------- ### Start and Monitor a Long-Lived Process Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/SESSION_EXECUTION_DEEP_DIVE.md Use startProcess to execute a command in the background, stream logs via an async iterator, and terminate the process when finished. ```typescript const server = await sandbox.startProcess('npm run dev'); // Stream logs while server runs for await (const event of server.streamLogs()) { console.log(event.data); // See output in real-time } // Kill it later (along with all child processes) await server.kill(); ``` -------------------------------- ### Client-side Terminal Setup with SandboxAddon Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/collaborative-terminal/README.md Configures the xterm.js terminal on the client-side using SandboxAddon to manage WebSocket connections, terminal resizing, and reconnection to the sandbox. ```typescript import { SandboxAddon } from '@cloudflare/sandbox/xterm'; const sandboxAddon = new SandboxAddon({ getWebSocketUrl: ({ origin, sessionId }) => `${origin}/ws/terminal/${sessionId}`, onStateChange: (state) => setState(state) }); terminal.loadAddon(sandboxAddon); sandboxAddon.connect({ sandboxId: sessionId, sessionId }); ``` -------------------------------- ### Example Usage: Simple Calculation Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/code-interpreter/README.md Use curl to send a prompt requesting a simple Python calculation, like a factorial, to the /run endpoint. ```bash # Simple calculation curl -X POST http://localhost:8787/run \ -H "Content-Type: application/json" \ -d '{"input": "Calculate 5 factorial using Python"}' ``` -------------------------------- ### Resume Harness from Previous Run Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/harness/README.md Resume a previously interrupted harness run, skipping initial setup phases and focusing on verification. Requires a saved session state. ```bash ./script/start --resume ``` -------------------------------- ### Execute Command and Get Result Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/SESSION_EXECUTION_DEEP_DIVE.md Use this to run a command and retrieve its standard output, standard error, and exit code. Ensure the sandbox is initialized before use. ```typescript const result = await sandbox.exec('pip install pandas && python train.py'); console.log(result.stdout, result.exitCode); ``` -------------------------------- ### Run Integration Tests Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/codex-app-server/README.md Executes the integration test script. This script starts a local development server, waits for it to be ready, and then runs a comprehensive test suite over WebSockets to validate the full Codex flow. ```bash npm test ``` -------------------------------- ### Deployment Steps Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/codex-app-server/README.md Commands to deploy the application to production, including setting secrets and running the deployment script. ```bash wrangler secret put OPENAI_API_KEY npm run deploy ``` -------------------------------- ### Create New Sandbox Project Source: https://github.com/cloudflare/sandbox-sdk/blob/main/README.md Use this command to create a new project with the minimal Sandbox SDK template. Navigate into the project directory afterwards. ```bash npm create cloudflare@latest -- my-sandbox --template=cloudflare/sandbox-sdk/examples/minimal cd my-sandbox ``` -------------------------------- ### Running the Sandbox Test Harness Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/harness/AGENTS.md Commands to set up and run the test harness. Ensure to fill in credentials in the .env file before execution. The --resume flag allows for resuming a previous session. ```bash cp .env.example .env # Fill in credentials ./script/start # full run (phases 1-7 + pause + resume verification) ./script/start --resume # resume from existing session_state.json ``` -------------------------------- ### Build All Packages Source: https://github.com/cloudflare/sandbox-sdk/blob/main/AGENTS.md Use this command to build all packages in the repository, leveraging turbo for efficient builds. Use `build:clean` to force a rebuild without using the cache. ```bash npm run build # Build all packages (uses turbo) npm run build:clean # Force rebuild without cache ``` -------------------------------- ### Initialize Jupyter Environment Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/JUPYTER_NOTEBOOKS.md Creates sample data and a starter notebook file within the sandbox workspace before exposing the interface. ```typescript // Create sample data files for analysis await sandbox.writeFile( '/workspace/sample_data.csv', ` date,sales,marketing_spend 2024-01-01,1200,450 2024-01-02,980,520 2024-01-03,1100,480 2024-01-04,1350,600 2024-01-05,1050,400 ` ); // Create a starter notebook await sandbox.writeFile( '/workspace/analysis.ipynb', JSON.stringify({ cells: [ { cell_type: 'code', execution_count: null, metadata: {}, outputs: [], source: [ 'import pandas as pd\nimport matplotlib.pyplot as plt\n\n# Load the sample data\ndf = pd.read_csv(\'sample_data.csv\')\nprint("Data loaded successfully!")\ndf.head()' ] } ], metadata: { kernelspec: { display_name: 'Python 3', language: 'python', name: 'python3' } }, nbformat: 4, nbformat_minor: 4 }) ); // Expose Jupyter interface const preview = await sandbox.exposePort(8888); console.log(`Jupyter notebook interface: ${preview.url}`); console.log(`Open analysis.ipynb to start analyzing the sample data`); ``` -------------------------------- ### Background Process: Early Lock Release in TypeScript Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/SESSION_EXECUTION_DEEP_DIVE.md For background processes, the session lock is released after the process starts and the PID is obtained. This allows other commands to run concurrently. Requires an 'onEvent' handler for the 'start' event. ```typescript if (background) { // BACKGROUND: Release lock after 'start' event const startupResult = await lock.runExclusive(async () => { const session = await this.getOrCreateSession(sessionId); const generator = session.execStream(command); // Wait for the 'start' event (which includes the PID) const firstResult = await generator.next(); await onEvent(firstResult.value); // 'start' event return { generator }; }); // ← Lock is released HERE, right after 'start' // Continue streaming WITHOUT the lock const continueStreaming = (async () => { for await (const event of startupResult.generator) { await onEvent(event); } })(); return { continueStreaming }; } else { // FOREGROUND STREAMING: Hold lock until complete return lock.runExclusive(async () => { const session = await this.getOrCreateSession(sessionId); for await (const event of session.execStream(command)) { await onEvent(event); } }); } ``` -------------------------------- ### Initialize Anthropic SDK Client Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/authentication/src/services/anthropic/README.md Instantiate the Anthropic client, which automatically detects the configured base URL. ```python from anthropic import Anthropic client = Anthropic() # Uses ANTHROPIC_BASE_URL ``` -------------------------------- ### GET /v1/sandbox/:id/running Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/worker/README.md Check whether the sandbox container is alive. ```APIDOC ## GET /v1/sandbox/:id/running ### Description Check whether the sandbox container is alive. ### Method GET ### Endpoint /v1/sandbox/:id/running ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the sandbox session. ### Request Example ```sh curl http://localhost:8787/v1/sandbox/mfrggzdfmy2tqnrz/running \ -H "Authorization: Bearer $SANDBOX_API_KEY" ``` ``` -------------------------------- ### Initialize WebSocket Endpoint and State Variables Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/codex-app-server/public/index.html Sets up the WebSocket endpoint and initializes various state variables for managing the connection, session, and application state. ```javascript const wsEndpoint = document.documentElement.dataset.wsEndpoint || 'ws://localhost:8787/ws'; let ws = null; let nextId = 0; let sessionName = ''; let repoUrl = ''; // Connection: disconnected → connecting → setup → initializing → starting → ready let connState = 'disconnected'; let pendingId = null; // Single thread let threadId = null; let turnActive = false; let activeAgentMsg = null; // index into messages\[\] const messages = []; // [{"role", "text", "streaming", "items[]"}] or [{"role", "text", "ts"}] // Null-prototype map; keys come straight from server payloads // (item.id) and are looked up without traversing Object.prototype. const items = Object.create(null); // itemId → {id, type, ...metadata} ``` -------------------------------- ### GET /health Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/worker/README.md Unauthenticated liveness probe to check if the sandbox worker is running. ```APIDOC ## GET /health ### Description Unauthenticated liveness probe. ### Method GET ### Endpoint /health ### Request Example ```sh curl http://localhost:8787/health ``` ``` -------------------------------- ### Create Nested Directories and Write File Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/harness/src/prompts/phase1_basic_ops.md Tests the creation of nested directories using `mkdir -p` and writing a file into the deepest directory. ```shell mkdir -p /workspace/a/b/c echo 'deep content' > /workspace/a/b/c/deep.txt cat /workspace/a/b/c/deep.txt ``` -------------------------------- ### Enter Ready State Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/codex-app-server/public/index.html Updates the application state to 'ready', sets the thread ID, updates the UI, and focuses the prompt input. ```javascript function enterReady(codexThreadId) { connState = 'ready'; threadId = codexThreadId; app.classList.remove('disconnected'); topbarSession.textContent = sessionName; updateInputState(); promptEl.focus(); } ``` -------------------------------- ### Send Thread Start Message Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/codex-app-server/public/index.html Sends a 'thread/start' message to initiate a new thread on the server. ```javascript function sendThreadStart() { connState = 'starting'; send({ method: 'initialized', params: {} }); const msg = rpcReq('thread/start'); pendingId = msg.id; send(msg); } ``` -------------------------------- ### API Endpoint for Listing Checkpoints Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/time-machine/README.md GET request to /api/checkpoints to retrieve a list of all available checkpoints. ```http GET /api/checkpoints ``` -------------------------------- ### Set up OpenAI API Key or Auth JSON Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/codex/README.md Configure your OpenAI credentials by setting either OPENAI_API_KEY or CODEX_AUTH_JSON in your .dev.vars file. The API key takes precedence if both are set. ```bash # Pay-per-token OPENAI_API_KEY= # OR ChatGPT subscription -- generate by running `codex login`, then paste # the contents of ~/.codex/auth.json into the variable as a single-line JSON. CODEX_AUTH_JSON= ``` -------------------------------- ### Spin up a fresh sandbox and mount S3 bucket Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/s3-mount/README.md Initiates a new sandbox environment and mounts the specified S3 bucket for access within the sandbox. Returns the sandbox ID and mount information. ```APIDOC ## POST /api/session ### Description Spins up a fresh sandbox and mounts the specified S3 bucket. Returns the sandbox ID and mount information. ### Method POST ### Endpoint /api/session ### Response #### Success Response (200) - **sandboxId** (string) - The unique identifier for the created sandbox. - **mount** (string) - Information about the mounted S3 bucket. ``` -------------------------------- ### Get Pool Statistics Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/worker/README.md Retrieves current statistics for the warm pool. Requires API key authentication. ```shell curl http://localhost:8787/v1/pool/stats \ -H "Authorization: Bearer $SANDBOX_API_KEY" ``` -------------------------------- ### Configure Agent with Sandbox Tools Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/OPENAI_AGENTS.md Initialize the Shell and Editor adapters and register them as tools within an OpenAI Agent instance. ```typescript import { getSandbox } from '@cloudflare/sandbox'; import { Shell, Editor } from '@cloudflare/sandbox/openai'; import { Agent, applyPatchTool, run, shellTool } from '@openai/agents'; export default { async fetch(request: Request, env: Env): Promise { // Get a sandbox instance const sandbox = getSandbox(env.Sandbox, 'workspace-session'); // Create shell adapter (executes commands in /workspace by default) const shell = new Shell(sandbox); // Create editor adapter (operates on /workspace by default) const editor = new Editor(sandbox, '/workspace'); // Create an agent with both tools const agent = new Agent({ name: 'Sandbox Assistant', model: 'gpt-4', instructions: 'You can execute shell commands and edit files in the workspace.', tools: [ shellTool({ shell, needsApproval: false }), applyPatchTool({ editor, needsApproval: false }) ] }); // Run the agent with user input const { input } = await request.json(); const result = await run(agent, input); // Access collected results const commandResults = shell.results; const fileOperations = editor.results; return new Response( JSON.stringify({ naturalResponse: result.finalOutput, commandResults, fileOperations }), { headers: { 'Content-Type': 'application/json' } } ); } }; ``` -------------------------------- ### Signal Handling Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/harness/src/prompts/phase3_stress_pty.md Verifies signal handling by starting a background process, sending a termination signal, and checking if it has exited. ```bash sleep 300 & BGPID=$! echo "started $BGPID" kill $BGPID 2>/dev/null sleep 0.5 kill -0 $BGPID 2>&1 || echo "process gone" ``` -------------------------------- ### Run Full Harness Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/harness/README.md Execute the complete test harness, including all phases and a pause/resume cycle. This command assumes the .env file is correctly configured. ```bash ./script/start ``` -------------------------------- ### DOM Element References Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/codex-app-server/public/index.html Gets references to various DOM elements used for UI interaction and status display. ```javascript const $ = (s) => document.getElementById(s); const app = $('app'); const sfSession = $('sf-session'); const sfRepo = $('sf-repo'); const sfConnect = $('sf-connect'); const sfStatus = $('sf-status'); const topbarSession = $('topbar-session'); const turnIndicator = $('turn-indicator'); const messagesEl = $('messages'); const logPanel = $('raw-log'); const logEntriesEl = $('log-entries'); const btnLogClose = $('btn-log-close'); const promptEl = $('prompt'); const btnSend = $('btn-send'); const btnEnd = $('btn-end'); const btnLogToggle = $('btn-log-toggle'); ``` -------------------------------- ### Run Agent with Image Input Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/examples/basic/README.md Provide a local image file as a visual reference for the agent. The image will be copied to the sandbox, and the agent will be prompted to inspect it. ```bash uv run main.py --image mockup.png "Build an HTML page that matches this mockup" ``` -------------------------------- ### Create Execution Session Response Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/worker/README.md Example JSON response when creating an execution session, containing the unique session ID. ```json { "id": "sess_abc123" } ``` -------------------------------- ### Create and Write to a FIFO (Named Pipe) Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/SESSION_EXECUTION_DEEP_DIVE.md Demonstrates creating a named pipe using `mkfifo` and writing data to it. Writing blocks until a reader is available. ```bash mkfifo /tmp/my.pipe # Create a named pipe (looks like a file, but isn't) # Terminal 1: Write to the pipe echo "hello" > /tmp/my.pipe # This BLOCKS! It waits until someone reads from the other end. # Terminal 2: Read from the pipe cat /tmp/my.pipe ``` -------------------------------- ### Define TypeScript schema with npm dependency Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/typescript-validator/README.md Example of user-provided TypeScript code utilizing the zod library for schema validation. ```typescript import { z } from 'zod'; export const schema = z.object({ name: z.string().min(1), email: z.string().email() }); ``` -------------------------------- ### Commit and Push File to Sandbox Repo Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/git-repo-per-sandbox/README.md Creates a file with content, commits it, and pushes it to the Artifacts repository associated with the sandbox. This call also creates the sandbox and repo if they don't exist. ```bash curl -X POST http://localhost:8787/sandboxes/demo/commit/hello.txt \ -d 'Hello from the sandbox!' ``` -------------------------------- ### Check Sandbox Liveness Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/worker/README.md Verify if the sandbox container is currently running by sending a GET request to the /v1/sandbox/:id/running endpoint. ```sh curl http://localhost:8787/v1/sandbox/mfrggzdfmy2tznrz/running \ -H "Authorization: Bearer $SANDBOX_API_KEY" ``` -------------------------------- ### Configure GitHub in Sandbox Source: https://github.com/cloudflare/sandbox-sdk/blob/main/examples/authentication/src/services/github/README.md Initialize the GitHub proxy configuration within the sandbox environment. ```typescript await configureGithub(sandbox, proxyBase, token); ``` -------------------------------- ### Clean Workspace Chat Session Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/examples/workspace-chat/README.md Discard the current sandbox session and start with a fresh sandbox. This is useful for resetting the workspace state. ```bash script/clean ``` -------------------------------- ### GET /v1/sandbox/:id/pty Source: https://github.com/cloudflare/sandbox-sdk/blob/main/bridge/worker/README.md Opens a WebSocket PTY (pseudo-terminal) session to the sandbox, allowing bidirectional communication with the container's terminal. ```APIDOC ## GET /v1/sandbox/:id/pty ### Description Open a WebSocket PTY session to the sandbox. The connection is a bidirectional proxy to the container's terminal via `sandbox.terminal()`. ### Method GET ### Endpoint `/v1/sandbox/:id/pty` ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the sandbox. #### Query Parameters - **cols** (number) - Optional - Terminal width in columns. Defaults to 80. - **rows** (number) - Optional - Terminal height in rows. Defaults to 24. - **shell** (string) - Optional - Shell binary to use (e.g., `/bin/bash`). - **session** (string) - Optional - SDK session ID for session-scoped PTY. ### WebSocket Frame Protocol #### Client → Server - **Binary**: UTF-8 encoded keystrokes / input - **Text (JSON)**: Control messages (e.g., `{"type": "resize", "cols": 120, "rows": 30}`) #### Server → Client - **Binary**: Terminal output (including ANSI escape sequences) - **Text (JSON)**: Status messages (`ready`, `exit`, `error`) ### Request Example ```sh # Example using websocat websocat "ws://localhost:8787/v1/sandbox/mfrggzdfmy2tqnrz/pty?cols=120&rows=30" \ -H "Authorization: Bearer $SANDBOX_API_KEY" ``` ### Note The request must include the `Upgrade: websocket` header; plain HTTP requests return `400`. ``` -------------------------------- ### Execute Kill Sequence Source: https://github.com/cloudflare/sandbox-sdk/blob/main/docs/SESSION_EXECUTION_DEEP_DIVE.md Implements a kill sequence starting with SIGTERM, followed by a wait, and then SIGKILL if necessary. Handles late-spawned children by re-walking the tree. ```typescript // First try SIGTERM - give processes a chance to clean up gracefully killTree(pid, 'SIGTERM'); // Wait up to 5 seconds for the entire tree to exit if (!(await waitForPidsExit(treePids, 5000))) { // Re-walk the tree for late-spawned children, then SIGKILL everything killTree(pid, 'SIGKILL'); // Also SIGKILL the original snapshot to cover orphans for (const treePid of treePids) { process.kill(treePid, 'SIGKILL'); } } ``` -------------------------------- ### Run Unit Tests Source: https://github.com/cloudflare/sandbox-sdk/blob/main/AGENTS.md Execute all unit tests for the repository. You can also target specific packages like `@cloudflare/sandbox` or `@repo/sandbox-container` using the `-w` flag. ```bash npm test # All unit tests npm test -w @cloudflare/sandbox # SDK unit tests only npm test -w @repo/sandbox-container # Container unit tests only ```