UNPKG

@dailyautomations/terminal-logger

Version:

Terminal command logger with Supabase sync for swarm prompts

164 lines (163 loc) 6.88 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.config = exports.TerminalLogger = void 0; const capture_1 = require("./capture"); const storage_1 = require("./storage"); const supabase_sync_1 = require("./supabase-sync"); const config_1 = require("./config"); const logger_1 = require("./logger"); class TerminalLogger { capture; storage; supabaseSync; isRunning = false; constructor() { this.storage = new storage_1.LocalStorage(config_1.config.logFilePath); this.supabaseSync = new supabase_sync_1.SupabaseSync(config_1.config.supabaseUrl, config_1.config.supabaseAnonKey); // Don't initialize capture here - wait until we have the session ID this.capture = null; // Will be initialized in start() } async start() { try { (0, config_1.validateConfig)(); logger_1.logger.info('Starting Terminal Logger...'); // Initialize components await this.storage.initialize(); await this.supabaseSync.initialize(); // Get the session info const sessionInfo = await this.storage.getSessionInfo(); // Sync the current session to Supabase first if (config_1.config.supabaseUrl && config_1.config.supabaseAnonKey) { await this.supabaseSync.syncSession(sessionInfo); } // Now create capture with the correct session ID this.capture = new capture_1.CommandCapture(config_1.config.shellHistoryFile, sessionInfo.id); // Start command capture await this.capture.startWatching(async (command) => { await this.handleNewCommand(command); }); // Start periodic sync if configured if (config_1.config.supabaseUrl && config_1.config.supabaseAnonKey) { this.supabaseSync.startPeriodicSync(config_1.config.syncIntervalMinutes, async () => { const lastSync = this.supabaseSync.getSyncStatus().lastSyncTime; return this.storage.getUnsyncedCommands(lastSync); }); } this.isRunning = true; logger_1.logger.info('Terminal Logger started successfully'); // Handle graceful shutdown this.setupShutdownHandlers(); } catch (error) { logger_1.logger.error('Failed to start Terminal Logger', error); throw error; } } async stop() { logger_1.logger.info('Stopping Terminal Logger...'); if (this.capture) { this.capture.stopWatching(); } this.supabaseSync.stopPeriodicSync(); // Final sync before shutdown if (config_1.config.supabaseUrl && config_1.config.supabaseAnonKey) { try { const lastSync = this.supabaseSync.getSyncStatus().lastSyncTime; const unsyncedCommands = await this.storage.getUnsyncedCommands(lastSync); if (unsyncedCommands.length > 0) { await this.supabaseSync.syncCommands(unsyncedCommands); } // Sync session end time const sessionInfo = await this.storage.getSessionInfo(); sessionInfo.endTime = new Date(); await this.supabaseSync.syncSession(sessionInfo); } catch (error) { logger_1.logger.error('Error during final sync', error); } } this.isRunning = false; logger_1.logger.info('Terminal Logger stopped'); } async handleNewCommand(command) { try { // Store locally await this.storage.addCommand(command); // Log special commands if (command.metadata?.isSwarmPrompt) { logger_1.logger.info('Captured swarm command', { command: command.command, swarmId: command.metadata.swarmId, agentType: command.metadata.agentType }); } // Real-time sync if enabled if (config_1.config.enableRealTimeSync && config_1.config.supabaseUrl && config_1.config.supabaseAnonKey) { await this.supabaseSync.syncCommands([command]); } } catch (error) { logger_1.logger.error('Error handling new command', error); } } setupShutdownHandlers() { const shutdown = async () => { if (this.isRunning) { await this.stop(); process.exit(0); } }; process.on('SIGINT', shutdown); process.on('SIGTERM', shutdown); } // Public API methods async getRecentCommands(limit = 100) { return this.storage.getCommands(limit); } async searchCommands(searchTerm) { if (config_1.config.supabaseUrl && config_1.config.supabaseAnonKey) { return this.supabaseSync.queryCommands({ searchTerm }); } // Local search fallback const allCommands = await this.storage.getCommands(); return allCommands.filter(cmd => cmd.command.toLowerCase().includes(searchTerm.toLowerCase())); } async getSwarmCommands() { if (config_1.config.supabaseUrl && config_1.config.supabaseAnonKey) { return this.supabaseSync.queryCommands({ isSwarmPrompt: true }); } // Local filter fallback const allCommands = await this.storage.getCommands(); return allCommands.filter(cmd => cmd.metadata?.isSwarmPrompt); } getSyncStatus() { return this.supabaseSync.getSyncStatus(); } } exports.TerminalLogger = TerminalLogger; // Export for library usage __exportStar(require("./types"), exports); var config_2 = require("./config"); Object.defineProperty(exports, "config", { enumerable: true, get: function () { return config_2.config; } }); // CLI execution if (require.main === module) { const terminalLogger = new TerminalLogger(); terminalLogger.start().catch(error => { logger_1.logger.error('Fatal error', error); process.exit(1); }); }