/** * SMI-1534: E2B Sandbox Execution for Skill Testing * * Provides isolated execution environment for testing untrusted skills. * Uses E2B (e2b.dev) sandboxes for secure, containerized execution. * * Features: * - Isolated filesystem per skill test * - Network isolation * - Resource limits (CPU, memory) * - Automatic cleanup after test * - Configurable timeout (default: 30s) */ /** * Configuration options for sandbox creation */ export interface SandboxOptions { /** Timeout in milliseconds (default: 30000) */ timeout?: number; /** Memory limit in MB (default: 256) */ memoryMB?: number; /** Whether to allow network access (default: false for security) */ allowNetwork?: boolean; /** Environment variables to inject */ env?: Record; } /** * Result from executing code in sandbox */ export interface ExecutionResult { /** Whether execution completed successfully */ success: boolean; /** Exit code from the process */ exitCode: number; /** Standard output */ stdout: string; /** Standard error */ stderr: string; /** Execution time in milliseconds */ durationMs: number; /** Whether execution timed out */ timedOut: boolean; /** Any error that occurred */ error?: string; } /** * Represents a file to be copied into the sandbox */ export interface SandboxFile { /** Path within the sandbox */ path: string; /** File content */ content: string; } /** * E2B Sandbox wrapper for skill testing * * @example * ```typescript * const sandbox = new SkillSandbox({ timeout: 60000 }) * try { * await sandbox.create() * await sandbox.copyFiles([ * { path: '/skill/SKILL.md', content: skillContent }, * { path: '/skill/test.ts', content: testCode } * ]) * const result = await sandbox.execute('node /skill/test.ts') * console.log(result.stdout) * } finally { * await sandbox.destroy() * } * ``` */ export declare class SkillSandbox { private options; private sandbox; private created; constructor(options?: SandboxOptions); /** * Create and initialize the sandbox environment * @throws Error if sandbox creation fails or E2B is unavailable */ create(): Promise; /** * Copy files into the sandbox filesystem * @param files - Array of files to copy */ copyFiles(files: SandboxFile[]): Promise; /** * Copy a skill directory into the sandbox * @param skillPath - Local path to skill directory * @param destPath - Destination path in sandbox (default: /skill) */ copySkill(skillContent: string, destPath?: string): Promise; /** * Execute a command in the sandbox * @param command - Command to execute * @param workingDir - Working directory (default: /skill) * @returns Execution result */ execute(command: string, workingDir?: string): Promise; /** * Execute TypeScript/JavaScript code directly * @param code - Code to execute * @returns Execution result */ executeCode(code: string): Promise; /** * Destroy the sandbox and clean up resources * Should always be called in a finally block */ destroy(): Promise; /** * Check if sandbox is active */ isActive(): boolean; /** * Get sandbox status */ getStatus(): SandboxStatus; private ensureCreated; /** * SMI-1534: Verify network isolation is actually in effect * Attempts to make a network request and expects it to fail */ private verifyNetworkIsolation; } /** * Sandbox status information */ export interface SandboxStatus { created: boolean; active: boolean; options: Required; } /** * Error thrown when E2B sandbox is not available */ export declare class SandboxUnavailableError extends Error { constructor(message: string); } /** * Factory function for creating sandboxes with proper cleanup * Ensures sandbox is destroyed even if test throws * * @example * ```typescript * const result = await withSandbox(async (sandbox) => { * await sandbox.copySkill(skillContent) * return sandbox.execute('node test.js') * }) * ``` */ export declare function withSandbox(fn: (sandbox: SkillSandbox) => Promise, options?: SandboxOptions): Promise; export default SkillSandbox; //# sourceMappingURL=SkillSandbox.d.ts.map