/** * MastraSandbox Base Class * * Abstract base class for sandbox providers that want automatic logger integration. * Extends MastraBase to receive the Mastra logger when registered with a Mastra instance. * * MountManager is automatically created if the subclass implements `mount()`. * Use `declare readonly mounts: MountManager` to get non-optional typing. * * ## Lifecycle Management * * The base class provides race-condition-safe lifecycle wrappers: * - `_start()` - Handles concurrent calls, status management, and mount processing * - `_stop()` - Handles concurrent calls and status management * - `_destroy()` - Handles concurrent calls and status management * * Subclasses override the plain `start()`, `stop()`, and `destroy()` methods * to provide their implementation. Callers use the `_`-prefixed wrappers * (or `callLifecycle()`) which add status tracking and race-condition safety. * * External providers can extend this class to get logger support, or implement * the WorkspaceSandbox interface directly if they don't need logging. */ import { MastraBase } from '../../base.js'; import type { IMastraLogger } from '../../logger/index.js'; import type { WorkspaceFilesystem } from '../filesystem/filesystem.js'; import type { MountResult } from '../filesystem/mount.js'; import type { ProviderStatus } from '../lifecycle.js'; import { MountManager } from './mount-manager.js'; import type { SandboxProcessManager } from './process-manager/index.js'; import type { WorkspaceSandbox } from './sandbox.js'; import type { CommandResult, ExecuteCommandOptions, SandboxInfo } from './types.js'; /** * Lifecycle hook that fires during sandbox state transitions. * Receives the sandbox instance so users can call `executeCommand`, read files, etc. */ export type SandboxLifecycleHook = (args: { sandbox: WorkspaceSandbox; }) => void | Promise; /** * Options for the MastraSandbox base class constructor. * Providers extend this to add their own options while inheriting lifecycle hooks. */ export interface MastraSandboxOptions { /** Called after the sandbox reaches 'running' status */ onStart?: SandboxLifecycleHook; /** Called before the sandbox stops */ onStop?: SandboxLifecycleHook; /** Called before the sandbox is destroyed */ onDestroy?: SandboxLifecycleHook; /** * Process manager for this sandbox. * * When provided, the base class automatically: * 1. Sets the sandbox back-reference on the process manager * 2. Exposes it via `this.processes` * 3. Creates a default `executeCommand` implementation (spawn + wait) * * @example * ```typescript * class MySandbox extends MastraSandbox { * constructor() { * super({ * name: 'MySandbox', * processes: new MyProcessManager({ env: myEnv }), * }); * } * } * ``` */ processes?: SandboxProcessManager; } /** * Abstract base class for sandbox providers with logger support. * * Providers that extend this class automatically receive the Mastra logger * when the sandbox is used with a Mastra instance. MountManager is also * automatically created if the subclass implements `mount()`. * * @example * ```typescript * class MyCustomSandbox extends MastraSandbox { * declare readonly mounts: MountManager; // Non-optional type * readonly id = 'my-sandbox'; * readonly name = 'MyCustomSandbox'; * readonly provider = 'custom'; * status: ProviderStatus = 'pending'; * * constructor() { * super({ * name: 'MyCustomSandbox', * processes: new MyProcessManager({ env: myEnv }), * }); * } * * async start(): Promise { /* startup logic *\/ } * async mount(filesystem, mountPath) { ... } * async unmount(mountPath) { ... } * } * ``` */ export declare abstract class MastraSandbox extends MastraBase implements WorkspaceSandbox { /** Unique identifier for this sandbox instance */ abstract readonly id: string; /** Human-readable name (e.g., 'E2B Sandbox', 'Docker') */ abstract readonly name: string; /** Provider type identifier */ abstract readonly provider: string; /** Current status of the sandbox */ abstract status: ProviderStatus; /** * Execute a shell command and wait for completion. * * Method syntax (not property syntax) is intentional — it prevents * `useDefineForClassFields` from emitting `this.executeCommand = undefined` * which would shadow prototype methods defined by subclasses. */ executeCommand?(command: string, args?: string[], options?: ExecuteCommandOptions): Promise; /** Process manager */ readonly processes?: SandboxProcessManager; /** Mount manager - automatically created if subclass implements mount() */ readonly mounts?: MountManager; /** Optional mount method - implement to enable mounting support */ mount?(filesystem: WorkspaceFilesystem, mountPath: string): Promise; /** Optional unmount method */ unmount?(mountPath: string): Promise; /** Get instructions describing how this sandbox works */ getInstructions?(): string; /** Get sandbox status and metadata */ getInfo?(): SandboxInfo | Promise; /** Promise for _start() to prevent race conditions from concurrent calls */ protected _startPromise?: Promise; /** Promise for _stop() to prevent race conditions from concurrent calls */ protected _stopPromise?: Promise; /** Promise for _destroy() to prevent race conditions from concurrent calls */ protected _destroyPromise?: Promise; /** Lifecycle callbacks */ private readonly _onStart?; private readonly _onStop?; private readonly _onDestroy?; constructor(options: { name: string; } & MastraSandboxOptions); /** * Start the sandbox (wrapper with status management and race-condition safety). * * This method is race-condition-safe - concurrent calls will return the same promise. * Handles status management and automatically processes pending mounts after startup. * * Subclasses override `start()` to provide their startup logic. */ _start(): Promise; /** * Internal start execution - handles status and mount processing. */ private _executeStart; /** * Override this method to implement sandbox startup logic. * * Called by `_start()` after status is set to 'starting'. * Status will be set to 'running' on success, 'error' on failure. * * @example * ```typescript * async start(): Promise { * this._sandbox = await Sandbox.create({ ... }); * } * ``` */ start(): Promise; /** * Ensure the sandbox is running. * * Calls `_start()` if status is not 'running'. Useful for lazy initialization * where operations should automatically start the sandbox if needed. * * @throws {SandboxNotReadyError} if the sandbox fails to reach 'running' status * * @example * ```typescript * async executeCommand(command: string): Promise { * await this.ensureRunning(); * // Now safe to use the sandbox * } * ``` */ ensureRunning(): Promise; /** * Stop the sandbox (wrapper with status management and race-condition safety). * * This method is race-condition-safe - concurrent calls will return the same promise. * Handles status management. * * Subclasses override `stop()` to provide their stop logic. */ _stop(): Promise; /** * Internal stop execution - handles status. */ private _executeStop; /** * Override this method to implement sandbox stop logic. * * Called by `_stop()` after status is set to 'stopping'. * Status will be set to 'stopped' on success, 'error' on failure. */ stop(): Promise; /** * Destroy the sandbox and clean up all resources (wrapper with status management). * * This method is race-condition-safe - concurrent calls will return the same promise. * Handles status management. * * Subclasses override `destroy()` to provide their destroy logic. */ _destroy(): Promise; /** * Internal destroy execution - handles status. */ private _executeDestroy; /** * Override this method to implement sandbox destroy logic. * * Called by `_destroy()` after status is set to 'destroying'. * Status will be set to 'destroyed' on success, 'error' on failure. */ destroy(): Promise; /** * Override to propagate logger to MountManager. * @internal */ __setLogger(logger: IMastraLogger): void; } //# sourceMappingURL=mastra-sandbox.d.ts.map