feat: add integrated terminal with xterm.js and shell sessions
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import { spawn, ChildProcess } from "child_process";
|
||||
import { WebSocket } from "ws";
|
||||
|
||||
interface TerminalSession {
|
||||
id: string;
|
||||
process: ChildProcess;
|
||||
ws: WebSocket | null;
|
||||
}
|
||||
|
||||
const sessions = new Map<string, TerminalSession>();
|
||||
|
||||
export function createTerminalSession(id: string): TerminalSession {
|
||||
const proc = spawn("/bin/bash", ["-l"], {
|
||||
env: { ...process.env, TERM: "xterm-256color" },
|
||||
cwd: process.env.WORKSPACE_PATH || "/workspace",
|
||||
});
|
||||
const session: TerminalSession = { id, process: proc, ws: null };
|
||||
sessions.set(id, session);
|
||||
proc.on("exit", () => sessions.delete(id));
|
||||
return session;
|
||||
}
|
||||
|
||||
export function attachWebSocket(sessionId: string, ws: WebSocket): boolean {
|
||||
const session = sessions.get(sessionId);
|
||||
if (!session) return false;
|
||||
session.ws = ws;
|
||||
session.process.stdout?.on("data", (data: Buffer) => {
|
||||
if (ws.readyState === WebSocket.OPEN) ws.send(data.toString());
|
||||
});
|
||||
session.process.stderr?.on("data", (data: Buffer) => {
|
||||
if (ws.readyState === WebSocket.OPEN) ws.send(data.toString());
|
||||
});
|
||||
ws.on("message", (data) => {
|
||||
session.process.stdin?.write(data.toString());
|
||||
});
|
||||
ws.on("close", () => {
|
||||
session.ws = null;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
export function destroySession(id: string): void {
|
||||
const session = sessions.get(id);
|
||||
if (session) {
|
||||
session.process.kill();
|
||||
sessions.delete(id);
|
||||
}
|
||||
}
|
||||
|
||||
export function listSessions(): string[] {
|
||||
return Array.from(sessions.keys());
|
||||
}
|
||||
Reference in New Issue
Block a user