UNPKG

vibe-coder-mcp

Version:

Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.

73 lines (72 loc) 2.48 kB
import chalk from 'chalk'; import { SessionPersistence } from './persistence.js'; import logger from '../../logger.js'; export class GracefulShutdown { handlers = []; isShuttingDown = false; register(handler) { this.handlers.push(handler); } async execute() { if (this.isShuttingDown) { return; } this.isShuttingDown = true; console.log(); console.log(chalk.yellow('Shutting down...')); const timeout = 5000; const handlerPromises = this.handlers.map(handler => Promise.race([ handler(), new Promise((_, reject) => setTimeout(() => reject(new Error('Shutdown timeout')), timeout)) ]).catch(error => { logger.error({ err: error }, 'Shutdown handler error'); })); await Promise.all(handlerPromises); console.log(chalk.green('Goodbye! 👋')); process.exit(0); } setupSignalHandlers() { process.on('SIGINT', async () => { await this.execute(); }); process.on('SIGTERM', async () => { await this.execute(); }); process.on('uncaughtException', async (error) => { console.error(chalk.red('Uncaught exception:'), error); logger.error({ err: error }, 'Uncaught exception in interactive mode'); await this.execute(); }); process.on('unhandledRejection', async (reason, promise) => { console.error(chalk.red('Unhandled rejection:'), reason); logger.error({ reason, promise }, 'Unhandled rejection in interactive mode'); await this.execute(); }); } } export function createAutoSaveHandler(sessionId, getSessionData, interval = 60000) { const persistence = new SessionPersistence(); let intervalId = null; const save = async () => { try { await persistence.saveSession(sessionId, getSessionData()); logger.debug({ sessionId }, 'Session auto-saved'); } catch (error) { logger.error({ err: error, sessionId }, 'Failed to auto-save session'); } }; return { start: () => { save(); intervalId = setInterval(save, interval); }, stop: async () => { if (intervalId) { clearInterval(intervalId); intervalId = null; } await save(); } }; }