2024-09-05 12:32:32 -07:00
|
|
|
import { Sandbox, ProcessHandle } from "e2b";
|
|
|
|
|
|
|
|
// Terminal class to manage a pseudo-terminal (PTY) in a sandbox environment
|
|
|
|
export class Terminal {
|
|
|
|
private pty: ProcessHandle | 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<void> {
|
|
|
|
// Create a new PTY process
|
|
|
|
this.pty = await this.sandbox.pty.create({
|
|
|
|
rows,
|
|
|
|
cols,
|
|
|
|
timeout: 0,
|
|
|
|
onData: (data: Uint8Array) => {
|
2024-09-05 14:23:14 -07:00
|
|
|
onData(new TextDecoder().decode(data)); // Convert received data to string and pass to handler
|
2024-09-05 12:32:32 -07:00
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send data to the terminal
|
2024-09-05 14:23:14 -07:00
|
|
|
async sendData(data: string) {
|
|
|
|
if (this.pty) {
|
|
|
|
await this.sandbox.pty.sendInput(this.pty.pid, new TextEncoder().encode(data));
|
2024-09-05 12:32:32 -07:00
|
|
|
} else {
|
2024-09-05 14:23:14 -07:00
|
|
|
console.log("Cannot send data because pty is not initialized.");
|
2024-09-05 12:32:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Resize the terminal
|
|
|
|
async resize(size: { cols: number; rows: number }): Promise<void> {
|
|
|
|
if (this.pty) {
|
|
|
|
await this.sandbox.pty.resize(this.pty.pid, size);
|
|
|
|
} else {
|
2024-09-05 14:23:14 -07:00
|
|
|
console.log("Cannot resize terminal because pty is not initialized.");
|
2024-09-05 12:32:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close the terminal, killing the PTY process and stopping the input stream
|
|
|
|
async close(): Promise<void> {
|
|
|
|
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();
|