UNPKG

@wonderwhy-er/desktop-commander

Version:

MCP server for terminal operations and file editing

256 lines (255 loc) 8.07 kB
import { REPLSessionManager } from '../REPLSessionManager.js'; let replManager = null; /** * Initialize the REPL manager with a terminal manager instance * @param terminalManager - The terminal manager instance */ export function initializeREPLManager(terminalManager) { if (!replManager) { replManager = new REPLSessionManager(terminalManager); } } /** * Command handler for REPL-related operations */ export const replCommandHandler = { /** * Create a new REPL session * @param params - Command parameters * @returns Result object with session PID */ createREPLSession: async (params) => { try { if (!replManager) { return { success: false, error: "REPL Manager not initialized" }; } const language = params.language; if (!language) { return { success: false, error: "Language parameter is required" }; } const pid = await replManager.createSession(language, params.options || {}); return { success: true, pid, message: `${language} REPL session started with PID ${pid}` }; } catch (error) { return { success: false, error: error.message || "Failed to create REPL session" }; } }, /** * Execute code in an existing REPL session * @param params - Command parameters * @returns Result with execution output */ executeREPLCode: async (params) => { try { if (!replManager) { return { success: false, error: "REPL Manager not initialized" }; } const { pid, code } = params; if (!pid || !code) { return { success: false, error: "Both pid and code parameters are required" }; } const result = await replManager.executeCode(typeof pid === 'string' ? parseInt(pid) : pid, code, params.options || {}); return { success: true, ...result }; } catch (error) { return { success: false, error: error.message || "Failed to execute code in REPL session" }; } }, /** * Create a new SSH session * @param params - Command parameters * @returns Result object with session PID */ createSSHSession: async (params) => { try { if (!replManager) { return { success: false, error: "REPL Manager not initialized" }; } const { host, username, port, identity, password } = params; if (!host) { return { success: false, error: "Host parameter is required" }; } const options = { username, port, identity, password, ...(params.options || {}) }; const pid = await replManager.createSSHSession(host, options); return { success: true, pid, message: `SSH session to ${host} started with PID ${pid}` }; } catch (error) { return { success: false, error: error.message || "Failed to create SSH session" }; } }, /** * Execute a command in an SSH session * @param params - Command parameters * @returns Result with execution output */ executeSSHCommand: async (params) => { try { if (!replManager) { return { success: false, error: "REPL Manager not initialized" }; } const { pid, command } = params; if (!pid || !command) { return { success: false, error: "Both pid and command parameters are required" }; } // For SSH, we use the same sendAndReadREPL method but specify 'ssh' as the language const parsedPid = typeof pid === 'string' ? parseInt(pid) : pid; const session = replManager.listSessions().find(s => s.pid === parsedPid); if (!session || session.language !== 'ssh') { return { success: false, error: "Invalid SSH session PID" }; } const result = await replManager.sendAndReadREPL(parsedPid, command, 'ssh', params.options?.timeout || 10000); return { success: true, ...result }; } catch (error) { return { success: false, error: error.message || "Failed to execute command in SSH session" }; } }, /** * List all active REPL sessions * @returns List of active sessions */ listREPLSessions: () => { try { if (!replManager) { return { success: false, error: "REPL Manager not initialized" }; } const sessions = replManager.listSessions(); return { success: true, sessions }; } catch (error) { return { success: false, error: error.message || "Failed to list REPL sessions" }; } }, /** * Close a specific REPL session * @param params - Command parameters * @returns Result indicating success */ closeREPLSession: async (params) => { try { if (!replManager) { return { success: false, error: "REPL Manager not initialized" }; } const { pid } = params; if (!pid) { return { success: false, error: "PID parameter is required" }; } const parsedPid = typeof pid === 'string' ? parseInt(pid) : pid; const success = await replManager.closeSession(parsedPid); return { success, message: success ? `REPL session with PID ${pid} closed successfully` : `Failed to close REPL session with PID ${pid}` }; } catch (error) { return { success: false, error: error.message || "Failed to close REPL session" }; } }, /** * Close all idle REPL sessions * @param params - Command parameters * @returns Result with number of closed sessions */ closeIdleREPLSessions: async (params) => { try { if (!replManager) { return { success: false, error: "REPL Manager not initialized" }; } const maxIdleMs = params?.maxIdleMs || 30 * 60 * 1000; // Default 30 minutes const closedCount = await replManager.closeIdleSessions(maxIdleMs); return { success: true, closedCount, message: `Closed ${closedCount} idle REPL session(s)` }; } catch (error) { return { success: false, error: error.message || "Failed to close idle REPL sessions" }; } } };