mcp-extended-tools
Version:
Extended tools for command execution
131 lines (108 loc) • 3.84 kB
JavaScript
const { executor } = require('./command-executor');
const { watcher } = require('./file-watcher');
const path = require('path');
class AutoRestartManager {
constructor() {
this.restartConfigs = new Map();
}
async setupAutoRestart(options) {
const {
command,
args = [],
watchPaths = ['.'],
ignore = ['**/node_modules/**', '**/.git/**'],
delay = 1000,
maxRetries = 3
} = options;
// Generate unique ID for this auto-restart config
const configId = Date.now().toString();
// Set up file watching
const watchId = watcher.watch({
paths: watchPaths,
ignore,
watchId: configId
});
// Start the initial process
const initialProcess = await executor.execute(command, args);
let currentProcess = initialProcess;
let retryCount = 0;
// Store the configuration
this.restartConfigs.set(configId, {
command,
args,
currentProcess: initialProcess.processId,
watchId,
retryCount
});
// Set up file change handler
watcher.on('file-event', async ({ watchId: eventWatchId, type }) => {
if (eventWatchId !== watchId || type !== 'change') return;
const config = this.restartConfigs.get(configId);
if (!config) return;
// Debounce restart
if (config.restartTimeout) {
clearTimeout(config.restartTimeout);
}
config.restartTimeout = setTimeout(async () => {
try {
// Stop current process
await executor.stop(config.currentProcess);
// Start new process
currentProcess = await executor.execute(command, args);
config.currentProcess = currentProcess.processId;
config.retryCount = 0;
} catch (error) {
config.retryCount++;
if (config.retryCount >= maxRetries) {
await this.stopAutoRestart(configId);
}
}
}, delay);
});
return {
configId,
processId: initialProcess.processId,
watchId
};
}
async stopAutoRestart(configId) {
const config = this.restartConfigs.get(configId);
if (!config) {
throw new Error(`Auto-restart config ${configId} not found`);
}
// Stop file watching
watcher.unwatch(config.watchId);
// Stop current process
await executor.stop(config.currentProcess);
// Clear any pending restart
if (config.restartTimeout) {
clearTimeout(config.restartTimeout);
}
// Remove configuration
this.restartConfigs.delete(configId);
return true;
}
listAutoRestarts() {
return Array.from(this.restartConfigs.entries()).map(([configId, config]) => ({
configId,
command: config.command,
args: config.args,
currentProcess: config.currentProcess,
watchId: config.watchId,
retryCount: config.retryCount
}));
}
async cleanup() {
const configs = Array.from(this.restartConfigs.keys());
await Promise.all(configs.map(configId => this.stopAutoRestart(configId)));
}
}
// Create singleton instance
const autoRestartManager = new AutoRestartManager();
// Cleanup on exit
process.on('SIGINT', () => autoRestartManager.cleanup());
process.on('SIGTERM', () => autoRestartManager.cleanup());
module.exports = {
AutoRestartManager,
autoRestartManager
};