Skip to main content

TypeScript SDK

The official TypeScript/JavaScript SDK for the Caged platform.

Installation

npm install @caged-dev/sdk

Quick Start

import { Caged } from "@caged-dev/sdk";

const caged = new Caged({ apiKey: process.env.CAGED_API_KEY! });

const sandbox = await caged.sandboxes.create({
  template: "node-20",
  cpus: 2,
  memory_mb: 1024,
});

console.log(`Sandbox ${sandbox.id} is ${sandbox.status}`);

Configuration

const caged = new Caged({
  apiKey: "caged_sk_...",             // Required
  baseUrl: "https://api.caged.dev",   // Optional
  timeout: 30000,                     // Optional: ms (default 30s)
});

Sandboxes

// Create
const sandbox = await caged.sandboxes.create({
  template: "node-20",
  repo: "https://github.com/user/repo",
  env: { NODE_ENV: "development" },
});

// Create with an AI agent and a budget cap
const agentBox = await caged.sandboxes.create({
  template: "python-312",
  agents: ["claude"],
  budget: 5.0, // USD
  env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});

// List all
const sandboxes = await caged.sandboxes.list();

// Get by ID
const sb = await caged.sandboxes.get("cage_abc123");

// Lifecycle
await caged.sandboxes.pause("cage_abc123");
await caged.sandboxes.resume("cage_abc123");
await caged.sandboxes.destroy("cage_abc123");

Executing Commands

Run shell commands inside a sandbox — including prompting installed AI agents:
// Run a command
const result = await caged.sandboxes.exec(sandbox.id, "npm test");
console.log(result.output);
if (result.exit_code !== 0) {
  console.error(`Tests failed with exit code ${result.exit_code}`);
}

// Prompt Claude Code (requires agents: ["claude"] at creation)
const answer = await caged.sandboxes.exec(
  sandbox.id,
  'cd /workspace && claude -p "Find and fix the failing test"'
);
console.log(answer.output);
A non-zero exit_code does not throw — it means the command ran and failed. Only infrastructure failures (sandbox unreachable) set result.error. Exec calls default to a 5-minute timeout; pass a third argument to override: caged.sandboxes.exec(id, cmd, 600_000).

Files

// List directory
const files = await caged.files.list(sandbox.id, "/workspace");

// Read file
const content = await caged.files.read(sandbox.id, "/workspace/package.json");

// Write file
await caged.files.write(sandbox.id, "/workspace/index.js", "console.log('hello')");

// Git diff
const diff = await caged.files.gitDiff(sandbox.id);

Snapshots

// Create snapshot
const snap = await caged.snapshots.create(sandbox.id, {
  name: "pre-refactor",
});

// Wait for completion
let snapshot = await caged.snapshots.get(snap.id);
while (snapshot.status === "pending") {
  await new Promise((r) => setTimeout(r, 1000));
  snapshot = await caged.snapshots.get(snap.id);
}

// Restore
await caged.snapshots.restore(snap.id);

// Download
const { url } = await caged.snapshots.downloadUrl(snap.id);

Error Handling

import { Caged, CagedAPIError, CagedTimeoutError } from "@caged-dev/sdk";

try {
  await caged.sandboxes.get("nonexistent");
} catch (err) {
  if (err instanceof CagedAPIError) {
    console.error(`Status ${err.status}: ${err.message}`);
    // err.body contains the raw error response
  } else if (err instanceof CagedTimeoutError) {
    console.error("Request timed out");
  }
}

TypeScript Types

All types are exported and available for use:
import type { Sandbox, SandboxCreateParams, FileEntry, Snapshot } from "@caged-dev/sdk";