refactor: split examples into separate packages and update Claude plan mode

- 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
This commit is contained in:
Nathan Flurry 2026-01-27 22:50:31 -08:00
parent 30c4ad6b39
commit 6d6f6d0272
17 changed files with 2773 additions and 165 deletions

View file

@ -6,7 +6,7 @@ import {
logInspectorUrl,
runPrompt,
waitForHealth,
} from "../shared/sandbox-agent-client.ts";
} from "@sandbox-agent/example-shared";
const DEFAULT_PORT = 3000;
const BINARY_PATH = resolve(dirname(fileURLToPath(import.meta.url)), "../../target/release/sandbox-agent");
@ -25,9 +25,10 @@ export async function setupDaytonaSandboxAgent(): Promise<{
console.log("Creating sandbox...");
const sandbox = await daytona.create({ language });
// Daytona sandboxes can't reach releases.rivet.dev, so upload binary directly
console.log("Uploading sandbox-agent...");
await sandbox.fs.uploadFile(BINARY_PATH, "/home/daytona/sandbox-agent");
await sandbox.fs.setFilePermissions("/home/daytona/sandbox-agent", { mode: "755" });
await sandbox.process.executeCommand("chmod +x /home/daytona/sandbox-agent");
console.log("Starting server...");
const tokenFlag = token ? `--token ${token}` : "--no-token";

View file

@ -0,0 +1,17 @@
{
"name": "@sandbox-agent/example-daytona",
"private": true,
"type": "module",
"scripts": {
"start": "tsx daytona.ts"
},
"dependencies": {
"@daytonaio/sdk": "latest",
"@sandbox-agent/example-shared": "workspace:*"
},
"devDependencies": {
"@types/node": "latest",
"tsx": "latest",
"typescript": "latest"
}
}

View file

@ -5,7 +5,7 @@ import {
logInspectorUrl,
runPrompt,
waitForHealth,
} from "../shared/sandbox-agent-client.ts";
} from "@sandbox-agent/example-shared";
const INSTALL_SCRIPT = "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh";
const DEFAULT_IMAGE = "debian:bookworm-slim";

View file

@ -0,0 +1,18 @@
{
"name": "@sandbox-agent/example-docker",
"private": true,
"type": "module",
"scripts": {
"start": "tsx docker.ts"
},
"dependencies": {
"dockerode": "latest",
"@sandbox-agent/example-shared": "workspace:*"
},
"devDependencies": {
"@types/dockerode": "latest",
"@types/node": "latest",
"tsx": "latest",
"typescript": "latest"
}
}

View file

@ -5,7 +5,7 @@ import {
logInspectorUrl,
runPrompt,
waitForHealth,
} from "../shared/sandbox-agent-client.ts";
} from "@sandbox-agent/example-shared";
const INSTALL_SCRIPT = "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh";
const DEFAULT_PORT = 2468;

17
examples/e2b/package.json Normal file
View file

@ -0,0 +1,17 @@
{
"name": "@sandbox-agent/example-e2b",
"private": true,
"type": "module",
"scripts": {
"start": "tsx e2b.ts"
},
"dependencies": {
"@e2b/code-interpreter": "latest",
"@sandbox-agent/example-shared": "workspace:*"
},
"devDependencies": {
"@types/node": "latest",
"tsx": "latest",
"typescript": "latest"
}
}

View file

@ -1,25 +0,0 @@
{
"name": "sandbox-agent-examples",
"private": true,
"type": "module",
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"start:docker": "tsx docker/docker.ts",
"start:e2b": "tsx e2b/e2b.ts",
"start:daytona": "tsx daytona/daytona.ts",
"start:vercel": "tsx vercel/vercel-sandbox.ts"
},
"dependencies": {
"@daytonaio/sdk": "latest",
"@e2b/code-interpreter": "latest",
"@vercel/sandbox": "latest",
"dockerode": "latest"
},
"devDependencies": {
"@types/node": "latest",
"tsx": "latest",
"typescript": "latest",
"vitest": "latest"
}
}

View file

@ -0,0 +1,8 @@
{
"name": "@sandbox-agent/example-shared",
"private": true,
"type": "module",
"exports": {
".": "./sandbox-agent-client.ts"
}
}

View file

@ -1,13 +0,0 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2022", "DOM"],
"types": ["node"],
"strict": true,
"skipLibCheck": true,
"noEmit": true
},
"include": ["**/*.ts"]
}

View file

@ -0,0 +1,17 @@
{
"name": "@sandbox-agent/example-vercel",
"private": true,
"type": "module",
"scripts": {
"start": "tsx vercel-sandbox.ts"
},
"dependencies": {
"@vercel/sandbox": "latest",
"@sandbox-agent/example-shared": "workspace:*"
},
"devDependencies": {
"@types/node": "latest",
"tsx": "latest",
"typescript": "latest"
}
}

View file

@ -5,7 +5,7 @@ import {
logInspectorUrl,
runPrompt,
waitForHealth,
} from "../shared/sandbox-agent-client.ts";
} from "@sandbox-agent/example-shared";
const INSTALL_SCRIPT = "curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh";
const DEFAULT_PORT = 2468;

View file

@ -1,9 +0,0 @@
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
include: ["**/*.test.ts"],
testTimeout: 300_000,
hookTimeout: 300_000,
},
});