Add desktop runtime management (Xvfb, openbox, dbus), screen capture,
mouse/keyboard input, and video streaming via neko binary extracted
from the m1k1o/neko container. Includes Docker test rig, TypeScript SDK
desktop support, and inspector Desktop tab.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add hidden `mock-agent-process` CLI subcommand implementing a stdio
JSON-RPC echo agent (ported from examples/mock-acp-agent)
- Update write_mock_agent_process_launcher() to exec the new subcommand
instead of exiting with error
- Update sdks/react to support React 18 and 19 peer dependencies
- Update @types/react to v19 across workspace (pnpm override + inspector)
- Fix RefObject<T | null> compatibility for React 19 useRef() signatures
- Add version reference replacement logic to release update_version.ts
covering all docs, examples, and code files listed in CLAUDE.md
- Add missing files to CLAUDE.md Install Version References list
(architecture.mdx, boxlite, modal, computesdk docs and examples)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* SDK sandbox provisioning: built-in providers, docs restructure, and quickstart overhaul
- Add built-in sandbox providers (local, docker, e2b, daytona, vercel, cloudflare) to the TypeScript SDK so users import directly instead of passing client instances
- Restructure docs: rename architecture to orchestration-architecture, add new architecture page for server overview, improve getting started flow
- Rewrite quickstart to be TypeScript-first with provider CodeGroup and custom provider accordion
- Update all examples to use new provider APIs
- Update persist drivers and foundry for new SDK surface
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix SDK typecheck errors and update persist drivers for insertEvent signature
- Fix insertEvent call in client.ts to pass sessionId as first argument
- Update Daytona provider create options to use Partial type (image has default)
- Update StrictUniqueSessionPersistDriver in tests to match new insertEvent signature
- Sync persist packages, openapi spec, and docs with upstream changes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add Modal and ComputeSDK built-in providers, update examples and docs
- Add `sandbox-agent/modal` provider using Modal SDK with node:22-slim image
- Add `sandbox-agent/computesdk` provider using ComputeSDK's unified sandbox API
- Update Modal and ComputeSDK examples to use new SDK providers
- Update Modal and ComputeSDK deploy docs with provider-based examples
- Add Modal to quickstart CodeGroup and docs.json navigation
- Add provider test entries for Modal and ComputeSDK
- Remove old standalone example files (modal.ts, computesdk.ts)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Modal provider: pre-install agents in image, fire-and-forget exec for server
- Pre-install agents in Dockerfile commands so they are cached across creates
- Use fire-and-forget exec (no wait) to keep server alive in Modal sandbox
- Add memoryMiB option (default 2GB) to avoid OOM during agent install
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Sync upstream changes: multiplayer docs, logos, openapi spec, foundry config
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* SDK: Add ensureServer() for automatic server recovery
Add ensureServer() to SandboxProvider interface to handle cases where the
sandbox-agent server stops or goes to sleep. The SDK now calls this method
after 3 consecutive health-check failures, allowing providers to restart the
server if needed. Most built-in providers (E2B, Daytona, Vercel, Modal,
ComputeSDK) implement this. Docker and Cloudflare manage server lifecycle
differently, and Local uses managed child processes.
Also update docs for quickstart, architecture, multiplayer, and session
persistence; mark persist-* packages as deprecated; and add ensureServer
implementations to all applicable providers.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* wip
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Bump @agentclientprotocol/sdk from 0.14.1 to 0.16.1 in acp-http-client
- Update adapters.json to reflect new SDK version
- Migrate unstableListSessions to listSessions (stabilized in SDK 0.16.0)
- Add CLAUDE.md guidance: request token location before e2e agent testing
All 5 ACP adapters remain at their latest versions. E2E testing confirms
Claude, Codex, Pi, and Cursor agents work end-to-end with credentials.
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
* Improve Daytona sandbox provisioning and frontend UI
Refactor git clone script in Daytona provider to use cleaner shell logic for GitHub token authentication and branch checkout. Add support for private repository clones with token-based auth. Improve Daytona provider error handling and git configuration setup.
Frontend improvements include enhanced dev panel, workspace dashboard, sidebar navigation, and UI components for better task/session management. Update interest manager and backend client to support improved session state handling.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* Add header status pill showing task/session/sandbox state
Surface aggregate status (error, provisioning, running, ready, no sandbox)
as a colored pill in the transcript panel header. Integrates task runtime
status, session status, and sandbox availability via the sandboxProcesses
interest topic so the pill accurately reflects unreachable sandboxes.
Includes mock tasks demonstrating error, provisioning, and running states,
unit tests for deriveHeaderStatus, and workspace-dashboard integration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
* Fix Foundry auth: migrate to Better Auth adapter, fix access token retrieval
- Remove @ts-nocheck from better-auth.ts, auth-user/index.ts, app-shell.ts
and fix all type errors
- Fix getAccessTokenForSession: read GitHub token directly from account
record instead of calling Better Auth's internal /get-access-token
endpoint which returns 403 on server-side calls
- Re-implement workspaceAuth helper functions (workspaceAuthColumn,
normalizeAuthValue, workspaceAuthClause, workspaceAuthWhere) that were
accidentally deleted
- Remove all retry logic (withRetries, isRetryableAppActorError)
- Implement CORS origin allowlist from configured environment
- Document cachedAppWorkspace singleton pattern
- Add inline org sync fallback in buildAppSnapshot for post-OAuth flow
- Add no-retry rule to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add Foundry dev panel from fix-git-data branch
Port the dev panel component that was left out when PR #243 was replaced
by PR #247. Adapted to remove runtime/mock-debug references that don't
exist on the current branch.
- Toggle with Shift+D, persists visibility to localStorage
- Shows context, session, GitHub sync status sections
- Dev-only (import.meta.env.DEV)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add full Docker image defaults, fix actor deadlocks, and improve dev experience
- Add Dockerfile.full and --all flag to install-agent CLI for pre-built images
- Centralize Docker image constant (FULL_IMAGE) pinned to 0.3.1-full
- Remove examples/shared/Dockerfile{,.dev} and daytona snapshot example
- Expand Docker docs with full runnable Dockerfile
- Fix self-deadlock in createWorkbenchSession (fire-and-forget provisioning)
- Audit and convert 12 task actions from wait:true to wait:false
- Add bun --hot for dev backend hot reload
- Remove --force from pnpm install in dev Dockerfile for faster startup
- Add env_file support to compose.dev.yaml for automatic credential loading
- Add mock frontend compose config and dev panel
- Update CLAUDE.md with wait:true policy and dev environment setup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* WIP: async action fixes and interest manager
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Foundry UI bugs: org names, hanging sessions, and wrong repo creation
- Fix org display name using GitHub description instead of name field
- Fix createWorkbenchSession hanging when sandbox is provisioning
- Fix auto-session creation retry storm on errors
- Fix task creation using wrong repo due to React state race conditions
- Remove Bun hot-reload from backend Dockerfile (causes port drift)
- Add GitHub sync/install status to dev panel
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Move Foundry HTTP APIs out of /api/rivet
* Move Foundry HTTP APIs onto /v1
* Fix Foundry Rivet base path and frontend endpoint fallback
* Configure Foundry Rivet runner pool for /v1
* Remove Foundry Rivet runner override
* Serve Foundry Rivet routes directly from Bun
* Log Foundry RivetKit deployment friction
* Add actor display metadata
* Tighten actor schema constraints
* Reset actor persistence baseline
* Remove temporary actor key version prefix
Railway has no persistent volumes so stale actors are wiped on
each deploy. The v2 key rotation is no longer needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Cache app workspace actor handle across requests
Every request was calling getOrCreate on the Rivet engine API
to resolve the workspace actor, even though it's always the same
actor. Cache the handle and invalidate on error so retries
re-resolve. This eliminates redundant cross-region round-trips
to api.rivet.dev on every request.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add temporary debug logging to GitHub OAuth exchange
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Make squashed baseline migrations idempotent
Use CREATE TABLE IF NOT EXISTS and CREATE UNIQUE INDEX IF NOT
EXISTS so the squashed baseline can run against actors that
already have tables from the pre-squash migration sequence.
This fixes the "table already exists" error when org workspace
actors wake up with stale migration journals.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Revert "Make squashed baseline migrations idempotent"
This reverts commit 356c146035.
* Fix GitHub OAuth callback by removing retry wrapper
OAuth authorization codes are single-use. The appWorkspaceAction wrapper
retries failed calls up to 20 times, but if the code exchange succeeds
and a later step fails, every retry sends the already-consumed code,
producing "bad_verification_code" from GitHub.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add runner versioning to RivetKit registry
Uses Date.now() so each process start gets a unique version.
This ensures Rivet Cloud migrates actors to the new runner on
deploy instead of routing requests to stale runners.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add backend request and workspace logging
* Log callback request headers
* Make GitHub OAuth callback idempotent against duplicate requests
Clear oauthState before exchangeCode so duplicate callback requests
fail the state check instead of hitting GitHub with a consumed code.
Marked as HACK — root cause of duplicate HTTP requests is unknown.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add temporary header dump on GitHub OAuth callback
Log all request headers on the callback endpoint to diagnose
the source of duplicate requests (Railway proxy, Cloudflare, browser).
Remove once root cause is identified.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Defer slow GitHub org sync to workflow queue for fast OAuth callback
Split syncGithubSessionFromToken into a fast path (initGithubSession:
exchange code, get viewer, store token+identity) and a slow path
(syncGithubOrganizations: list orgs/installations, sync workspaces).
completeAppGithubAuth now returns the 302 redirect in ~2s instead of
~18s by enqueuing the org sync to the workspace workflow queue
(fire-and-forget). This eliminates the proxy timeout window that was
causing duplicate callback requests.
bootstrapAppGithubSession (dev-only) still calls the full synchronous
sync since proxy timeouts are not a concern and it needs the session
fully populated before returning.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* foundry: async app repo import on org select
* foundry: parallelize app snapshot org reads
* repo: push all current workspace changes
* foundry: update runner version and snapshot logging
* Refactor Foundry GitHub state and sandbox runtime
Refactors Foundry around organization/repository ownership and adds an organization-scoped GitHub state actor plus a user-scoped GitHub auth actor, removing the old project PR/branch sync actors and repo PR cache.
Updates sandbox provisioning to rely on sandbox-agent for in-sandbox work, hardens Daytona startup and image-build behavior, and surfaces runtime and task-startup errors more clearly in the UI.
Extends workbench and GitHub state handling to track merged PR state, adds runtime-issue tracking, refreshes client/test/config wiring, and documents the main live Foundry test flow plus actor coordination rules.
Also updates the remaining Sandbox Agent install-version references in docs/examples to the current pinned minor channel.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* chore: recover hamburg workspace state
* chore: drop workspace context files
* refactor: generalize permissions example
* refactor: parse permissions example flags
* docs: clarify why fs and terminal stay native
* feat: add interactive permission prompt UI to Inspector
Add permission request handling to the Inspector UI so users can
Allow, Always Allow, or Reject tool calls that require permissions
instead of having them auto-cancelled. Wires up SDK
onPermissionRequest/respondPermission through App → ChatPanel →
ChatMessages with proper toolCallId-to-pendingId mapping.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: prevent permission reply from silently escalating "once" to "always"
Remove allow_always from the fallback chain when the user replies "once",
aligning with the ACP spec which says "map by option kind first" with no
fallback for allow_once. Also fix Inspector to use rawSend, revert
hydration guard to accept empty configOptions, and handle respondPermission
errors by rejecting the pending promise.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: improve inspector UI for processes and fix PTY terminal
- Simplify ProcessRunTab layout: compact form with collapsible Advanced section for timeout/maxOutputBytes
- Rewrite ProcessesTab: collapsible create form, lightweight list items with status dots, clean detail panel with tabs
- Extract error details: use problem.detail instead of generic "Stream Error" title for better error messages
- Fix GhosttyTerminal binary frame parsing: handle server's binary ArrayBuffer control frames (ready/exit/error)
- Enable WebSocket proxying in Vite dev server with ws: true
- Set TERM=xterm-256color default for TTY processes so tools like tmux, vim, htop work out of the box
- Remove orange gradient background from terminal container for cleaner look
- Remove orange left border from selected process list items
- Update inspector CSS with new process/terminal styles
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* fix: address review issues and add processes documentation
- Fix unstable onExit callback in ProcessesTab (useCallback)
- Fix SSE follow stream race condition (subscribe before history read)
- Update inspector.mdx with new process management features
- Change observability icon to avoid conflict with processes
- Add docs/processes.mdx covering the full process management API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: simplify processes doc — rename sections, remove low-level protocol
- Rename "Interactive terminals" to "Terminals" with "Connect to a terminal" sub-heading
- Add TTY process creation step at top of Terminals section
- Remove low-level WebSocket protocol table and raw WebSocket example
- Keep browser terminal emulator reference with Ghostty link
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: update GhosttyTerminal permalink to latest commit
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: use main branch permalink for GhosttyTerminal reference
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: refine process API — WebSocket binary protocol, SDK terminal session, updated tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: update GhosttyTerminal permalink to 636eefb
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* inspector: use websocket terminal API
* sdk: restore high-level terminal session
* docs: update inspector terminal permalink
* inspector: update run once placeholder
* Fix lazy install v1 API test fixture
* Add reusable React terminal component
* Fix terminal WebSocket ready state checks
---------
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
* feat: add process management API
Introduces a complete Process Management API for Sandbox Agent with process lifecycle management (start, stop, kill, delete), one-shot command execution, log streaming via SSE and WebSocket, stdin input, and PTY/terminal support. Includes new process_runtime module for managing process state, HTTP route handlers, OpenAPI documentation, and integration tests.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* fix: address review issues in process management API
- Add doc comments to all 13 new #[utoipa::path] handlers (CLAUDE.md compliance)
- Fix send_signal ESRCH check: use raw_os_error() == Some(libc::ESRCH) instead of ErrorKind::NotFound
- Add max_input_bytes_per_request enforcement in WebSocket terminal handler
- URL-decode access_token query parameter for WebSocket auth
- Replace fragile string prefix matching with proper SandboxError::NotFound variant
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
* feat: add TypeScript SDK support for process management
Add process CRUD operations (create, get, list, update, delete) and
event streaming to the TypeScript SDK. Includes integration tests,
mock agent updates, and test environment fixes for cross-platform
home directory handling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: provide WebSocket impl for process terminal test on Node 20
Node 20 lacks globalThis.WebSocket. Add ws as a devDependency and
pass it to connectProcessTerminalWebSocket in the integration test
so CI no longer fails.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
* docs: add Cloudflare Sandbox SDK deployment guide
- Add docs/deploy/cloudflare.mdx with full deployment guide
- Add examples/cloudflare/ with working Worker code
- Update docs navigation to include Cloudflare option
- Update deploy index page with Cloudflare card
The example shows how to run sandbox-agent inside a Cloudflare Sandbox
with exposed ports for API access.
Co-authored-by: Shelley <shelley@exe.dev>
* fix: guard server startup to avoid port conflicts
Add health check before starting sandbox-agent to prevent 'address already
in use' errors on subsequent requests. The isServerRunning() function probes
the health endpoint to determine if setup should be skipped.
Co-authored-by: Shelley <shelley@exe.dev>
* fix: default cloudflare/sandbox:0.7.0 (latest does not exist)
* feat(cloudflare): add React frontend and improve deployment docs
- Add React + Vite frontend for Cloudflare example with sandbox-agent SDK
- Update ensureRunning to poll health endpoint instead of fixed wait
- Fix SDK fetch binding issue (globalThis.fetch.bind)
- Update docs with .dev.vars format warning and container caching tip
- Use containerFetch proxy pattern for reliable local dev
---------
Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Nathan Flurry <git@nathanflurry.com>
Co-authored-by: Nathan Flurry <developer@nathanflurry.com>
* fix: fix bun install bug
* refactor: consolidate executable check into assertExecutable helper
- Add assertExecutable() to cli-shared that checks and attempts chmod
- Simplify CLI and SDK spawn code to use the shared helper
- Fix cli-shared package.json exports (.js not .mjs)
- Add global install instructions to SDK error message
* chore(release): update version to 0.1.6-rc.1
* fix: add cli-shared package to Dockerfiles
* chore(release): update version to 0.1.6-rc.1
* fix: add cli-shared publishing to release workflow
* chore(release): update version to 0.1.6-rc.1
* fix: handle already-exists error during crate publish
* chore(release): update version to 0.1.6-rc.1
Previously used cfg!(target_env = "musl") which checks compile-time,
causing musl-compiled sandbox-agent to always download musl binaries
even on glibc systems like Debian/E2B.
Now checks for /lib/ld-musl-*.so.1 at runtime to detect the actual
system libc and download the correct Claude binary variant.
- Restructure examples into individual packages per provider (daytona, docker, e2b, vercel) with shared utilities in @sandbox-agent/example-shared
- Make Claude plan mode prompt-only (no longer requires permissionMode=plan)
- Claude now defaults to bypass permission mode
- Add agent_file_edit_flow test for file editing capabilities
- Fix Daytona file permission setting to use executeCommand