Skip to content

Sandbox Execution

Run AI agents in isolated Docker containers with resource limits, workspace mounting, and parallel execution support. This is ideal for safe local development and testing.

  • Docker installed and running
  • @jbcom/agentic installed
  • AI provider API key (for AI-powered sandboxes)
Terminal window
agentic sandbox run "Analyze this codebase for security vulnerabilities" \
--workspace . \
--output ./analysis-results
Terminal window
agentic sandbox run "Refactor the authentication module" \
--runtime claude \
--workspace ./src \
--output ./refactor-results \
--timeout 300

Run multiple tasks in parallel:

Terminal window
agentic sandbox fleet \
"Review authentication system" \
"Analyze database queries" \
"Check for security vulnerabilities" \
--runtime claude \
--workspace . \
--output ./fleet-results
Terminal window
agentic sandbox run "Analyze large codebase" \
--workspace . \
--output ./analysis \
--memory 2048 \
--timeout 600 \
--env "NODE_ENV=development,LOG_LEVEL=debug"
import { SandboxExecutor } from '@jbcom/agentic';
async function runSandbox() {
const sandbox = new SandboxExecutor();
const result = await sandbox.execute({
runtime: 'claude',
workspace: './src',
outputDir: './analysis',
prompt: 'Analyze this code for performance bottlenecks',
timeout: 300000, // 5 minutes
});
if (result.success) {
console.log('Analysis complete:', result.output);
} else {
console.error('Sandbox failed:', result.error);
}
return result;
}
import { SandboxExecutor } from '@jbcom/agentic';
async function runFleet() {
const sandbox = new SandboxExecutor();
const results = await sandbox.executeFleet([
{
runtime: 'claude',
workspace: './frontend',
outputDir: './frontend-analysis',
prompt: 'Review React components for accessibility issues',
},
{
runtime: 'claude',
workspace: './backend',
outputDir: './backend-analysis',
prompt: 'Analyze API endpoints for security vulnerabilities',
},
{
runtime: 'claude',
workspace: './shared',
outputDir: './shared-analysis',
prompt: 'Check shared utilities for performance issues',
},
]);
// Process results
for (const [index, result] of results.entries()) {
console.log(`Task ${index + 1}: ${result.success ? '' : ''}`);
if (result.success) {
console.log(` Output: ${result.outputDir}`);
} else {
console.error(` Error: ${result.error}`);
}
}
return results;
}
import { SandboxExecutor, SandboxConfig } from '@jbcom/agentic';
async function customSandbox() {
const sandbox = new SandboxExecutor();
const config: SandboxConfig = {
runtime: 'claude',
workspace: './src/api',
outputDir: './api-refactor',
prompt: `
Refactor the API layer to use async/await consistently.
Requirements:
1. Convert all callback-based code to async/await
2. Add proper error handling with try/catch
3. Ensure backwards compatibility
4. Add JSDoc comments to all public functions
`,
timeout: 600000, // 10 minutes
memory: 2048, // 2GB RAM limit
env: {
NODE_ENV: 'development',
LOG_LEVEL: 'debug',
DEBUG: 'api:*',
},
volumes: [
// Mount additional directories read-only
{ source: './config', target: '/config', readonly: true },
{ source: './fixtures', target: '/fixtures', readonly: true },
],
};
const result = await sandbox.execute(config);
return result;
}
RuntimeDescriptionUse Case
claudeAnthropic Claude in containerGeneral analysis, refactoring
cursorCursor agent runtimeCode generation, complex tasks
aiderAider CLI in containerQuick code fixes
customCustom Docker imageSpecialized environments
const result = await sandbox.execute({
runtime: 'custom',
image: 'my-registry/my-ai-agent:latest',
workspace: './src',
outputDir: './output',
prompt: 'Custom analysis task',
});
interface SandboxConfig {
// Required
workspace: string; // Path to mount as workspace
outputDir: string; // Path for output files
prompt: string; // Task description
// Runtime
runtime: 'claude' | 'cursor' | 'aider' | 'custom';
image?: string; // Custom Docker image (for runtime: 'custom')
// Resource limits
timeout?: number; // Milliseconds (default: 300000 / 5 min)
memory?: number; // MB (default: 1024)
cpus?: number; // CPU cores (default: 2)
// Environment
env?: Record<string, string>; // Environment variables
// Volumes
volumes?: Array<{
source: string; // Host path
target: string; // Container path
readonly?: boolean; // Mount as read-only
}>;
// Callbacks
onProgress?: (message: string) => void;
onOutput?: (chunk: string) => void;
}
import { SandboxExecutor } from '@jbcom/agentic';
async function securityAudit() {
const sandbox = new SandboxExecutor();
const result = await sandbox.execute({
runtime: 'claude',
workspace: '.',
outputDir: './security-audit',
prompt: `
Perform a comprehensive security audit:
1. Check for hardcoded secrets and credentials
2. Identify SQL injection vulnerabilities
3. Find XSS attack vectors
4. Review authentication/authorization logic
5. Check for insecure dependencies
6. Identify OWASP Top 10 issues
Create a detailed report with severity ratings.
`,
timeout: 900000, // 15 minutes
memory: 2048,
});
return result;
}
import { SandboxExecutor } from '@jbcom/agentic';
async function updateDependencies() {
const sandbox = new SandboxExecutor();
const result = await sandbox.execute({
runtime: 'claude',
workspace: '.',
outputDir: './dependency-update',
prompt: `
Update all npm dependencies to their latest compatible versions:
1. Run npm outdated to identify updates
2. Update each dependency one at a time
3. Run tests after each update
4. Document any breaking changes
5. Create a summary of all updates
If tests fail, revert that specific update.
`,
timeout: 600000,
env: {
NPM_CONFIG_REGISTRY: 'https://registry.npmjs.org',
},
});
return result;
}
import { SandboxExecutor } from '@jbcom/agentic';
async function migrateToTypeScript() {
const sandbox = new SandboxExecutor();
const results = await sandbox.executeFleet([
{
runtime: 'claude',
workspace: './src/utils',
outputDir: './migration/utils',
prompt: 'Convert all JavaScript files to TypeScript with proper types',
},
{
runtime: 'claude',
workspace: './src/components',
outputDir: './migration/components',
prompt: 'Convert React components to TypeScript with proper prop types',
},
{
runtime: 'claude',
workspace: './src/api',
outputDir: './migration/api',
prompt: 'Convert API layer to TypeScript with proper request/response types',
},
]);
return results;
}
// Quick analysis: 5 minutes
timeout: 300000
// Complex refactoring: 15 minutes
timeout: 900000
// Large codebase analysis: 30 minutes
timeout: 1800000
// Small tasks
memory: 512 // 512MB
// Medium tasks
memory: 1024 // 1GB (default)
// Large codebases
memory: 4096 // 4GB
volumes: [
{ source: './config', target: '/config', readonly: true },
{ source: './node_modules', target: '/node_modules', readonly: true },
]
const result = await sandbox.execute({
// ...config
onProgress: (message) => {
console.log(`[${new Date().toISOString()}] ${message}`);
},
onOutput: (chunk) => {
process.stdout.write(chunk);
},
});
const result = await sandbox.execute(config);
if (!result.success) {
if (result.error?.includes('timeout')) {
console.log('Task timed out, retrying with longer timeout...');
return sandbox.execute({ ...config, timeout: config.timeout * 2 });
}
if (result.error?.includes('memory')) {
console.log('Out of memory, retrying with more RAM...');
return sandbox.execute({ ...config, memory: config.memory * 2 });
}
throw new Error(result.error);
}
  • The sandbox mounts your workspace into the container
  • Changes made inside the container affect your actual files
  • Use outputDir to separate outputs from source code
  • By default, containers have network access for API calls
  • Use --network none for fully isolated execution (custom Docker only)
  • Pass API keys via environment variables, not in prompts
  • Use .dockerignore to prevent sensitive files from being copied
// Good: API key via env
env: {
ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
}
// Bad: API key in prompt
prompt: `Use API key sk-xxx to call...`