npm package: @papercraneai/sandbox-agent
Description: Claude Agent SDK server for sandbox environments
Latest version: 0.1.11

# Sandbox Agent

An Express server that runs the Claude Agent SDK inside Daytona sandboxes, providing AI-assisted development capabilities.

## Overview

This agent runs inside a Daytona sandbox and exposes HTTP endpoints for chat interactions. It uses the Claude Agent SDK with built-in tools (Read, Write, Edit, Glob, Grep, Bash) to help users build applications.

## Building the Daytona Snapshot

### Prerequisites

1. Install the Daytona CLI:
   ```bash
   curl -sf https://download.daytona.io/daytona/install.sh | bash
   ```

2. Authenticate:
   ```bash
   daytona login
   ```

### Creating the Snapshot

From this directory (`papercrane/apps/sandbox-agent`):

```bash
daytona snapshot create <snapshot-name> --dockerfile ./Dockerfile --context .
```

**Important:** The `--context .` flag is required. Without it, Daytona only includes files explicitly referenced in COPY commands and may miss the `src/` directory.

### Monorepo Considerations

This project lives in a monorepo with npm workspaces. The `package-lock.json` must be generated standalone (outside the workspace) for the Docker build to work:

```bash
# Copy to temp directory
cp -r . /tmp/sandbox-agent-standalone
cd /tmp/sandbox-agent-standalone

# Generate lock file
npm install

# Copy back
cp package-lock.json /path/to/papercrane/apps/sandbox-agent/
```

## Claude Agent SDK Usage

### Key Options

```typescript
import { query } from "@anthropic-ai/claude-agent-sdk"

for await (const msg of query({
  prompt: message,
  options: {
    systemPrompt: "Your system prompt",
    maxTurns: 15,
    cwd: "/path/to/project",  // NOT workingDirectory
    permissionMode: "bypassPermissions",
    allowDangerouslySkipPermissions: true,  // Required when bypassing
    allowedTools: ["Read", "Write", "Edit", "Glob", "Grep", "Bash"]
  }
})) {
  // Handle streaming messages
}
```

### Common Pitfalls

1. **`workingDirectory` vs `cwd`**: The SDK uses `cwd` (not `workingDirectory`) to set the working directory.

2. **`allowDangerouslySkipPermissions`**: When using `permissionMode: "bypassPermissions"`, you must also set `allowDangerouslySkipPermissions: true`. This is a safety measure to ensure intentional bypassing.

3. **Built-in Tools**: The SDK provides these built-in tools - no need to implement them yourself:
   - `Read` - Read files
   - `Write` - Write files
   - `Edit` - Edit files with find/replace
   - `Glob` - Find files by pattern
   - `Grep` - Search file contents
   - `Bash` - Execute shell commands

## API Endpoints

### `GET /health`
Health check endpoint.

### `POST /chat`
Streaming chat endpoint (SSE). Send a message and receive streaming responses.

```json
{ "message": "Create a hello world component" }
```

### `POST /chat/sync`
Synchronous chat endpoint. Waits for completion and returns all messages.

## Environment Variables

- `PORT` - Server port (default: 3001)
- `PROJECT_DIR` - Working directory for the agent (default: /home/user/project)
- `ANTHROPIC_API_KEY` - Required for Claude API access (injected at sandbox creation time, not in the snapshot)

## Architecture

```
┌─────────────────────────────────────────────────────────┐
│                    Daytona Sandbox                       │
│  ┌─────────────────┐     ┌─────────────────────────┐   │
│  │  sandbox-agent  │     │   Vite Dev Server       │   │
│  │   (port 3001)   │     │     (port 3000)         │   │
│  │                 │     │                         │   │
│  │  Claude Agent   │────▶│   /tmp/project          │   │
│  │  SDK + Tools    │     │   (React app)           │   │
│  └─────────────────┘     └─────────────────────────┘   │
└─────────────────────────────────────────────────────────┘
           │                          │
           │ Preview Token            │ Preview Token
           ▼                          ▼
┌─────────────────────────────────────────────────────────┐
│                    AuthLLM Server                        │
│  - Proxies chat requests to sandbox-agent               │
│  - Manages sandbox lifecycle                            │
│  - Handles authentication                               │
└─────────────────────────────────────────────────────────┘
```

## Security

- Sandboxes are created with `public: false`
- All requests to the sandbox require a Daytona preview token (`X-Daytona-Preview-Token` header)
- The `ANTHROPIC_API_KEY` is injected at runtime, not baked into the snapshot