import { CommandHandle, Sandbox } from "e2b" // Terminal class to manage a pseudo-terminal (PTY) in a sandbox environment export class Terminal { private pty: CommandHandle | undefined // Holds the PTY process handle private sandbox: Sandbox // Reference to the sandbox environment // Constructor initializes the Terminal with a sandbox constructor(sandbox: Sandbox) { this.sandbox = sandbox } // Initialize the terminal with specified rows, columns, and data handler async init({ rows = 20, cols = 80, onData, }: { rows?: number cols?: number onData: (responseData: string) => void }): Promise { // Create a new PTY process this.pty = await this.sandbox.pty.create({ rows, cols, timeoutMs: 0, onData: (data: Uint8Array) => { onData(new TextDecoder().decode(data)) // Convert received data to string and pass to handler }, }) } // Send data to the terminal async sendData(data: string) { if (this.pty) { await this.sandbox.pty.sendInput( this.pty.pid, new TextEncoder().encode(data) ) } else { console.log("Cannot send data because pty is not initialized.") } } // Resize the terminal async resize(size: { cols: number; rows: number }): Promise { if (this.pty) { await this.sandbox.pty.resize(this.pty.pid, size) } else { console.log("Cannot resize terminal because pty is not initialized.") } } // Close the terminal, killing the PTY process and stopping the input stream async close(): Promise { if (this.pty) { await this.pty.kill() } else { console.log("Cannot kill pty because it is not initialized.") } } } // Usage example: // const terminal = new Terminal(sandbox); // await terminal.init(); // terminal.sendData('ls -la'); // await terminal.resize({ cols: 100, rows: 30 }); // await terminal.close();