"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = register; /** * HarborForge Monitor Plugin for OpenClaw * * Manages sidecar lifecycle and provides monitor-related tools. */ const child_process_1 = require("child_process"); const path_1 = require("path"); const fs_1 = require("fs"); function register(api, config) { const logger = api.logger || { info: (...args) => console.log('[HF-Monitor]', ...args), error: (...args) => console.error('[HF-Monitor]', ...args), debug: (...args) => console.debug('[HF-Monitor]', ...args), warn: (...args) => console.warn('[HF-Monitor]', ...args), }; if (!config?.enabled) { logger.info('HarborForge Monitor plugin disabled'); return; } if (!config.apiKey) { logger.warn('Missing config: apiKey'); logger.warn('API authentication will fail. Generate apiKey from HarborForge Monitor admin.'); } const serverPath = (0, path_1.join)(__dirname, '..', 'server', 'telemetry.mjs'); if (!(0, fs_1.existsSync)(serverPath)) { logger.error('Telemetry server not found:', serverPath); return; } let sidecar = null; function startSidecar() { if (sidecar) { logger.debug('Sidecar already running'); return; } logger.info('Starting HarborForge Monitor telemetry server...'); const env = { ...process.env, HF_MONITOR_BACKEND_URL: config.backendUrl || 'https://monitor.hangman-lab.top', HF_MONITOR_IDENTIFIER: config.identifier || '', HF_MONITOR_API_KEY: config.apiKey || '', HF_MONITOR_REPORT_INTERVAL: String(config.reportIntervalSec || 30), HF_MONITOR_HTTP_FALLBACK_INTERVAL: String(config.httpFallbackIntervalSec || 60), HF_MONITOR_LOG_LEVEL: config.logLevel || 'info', OPENCLAW_PATH: process.env.OPENCLAW_PATH || (0, path_1.join)(process.env.HOME || '/root', '.openclaw'), OPENCLAW_VERSION: api.version || 'unknown', }; sidecar = (0, child_process_1.spawn)('node', [serverPath], { env, detached: false, stdio: ['ignore', 'pipe', 'pipe'] }); sidecar.stdout?.on('data', (data) => { logger.info('[telemetry]', data.toString().trim()); }); sidecar.stderr?.on('data', (data) => { logger.error('[telemetry]', data.toString().trim()); }); sidecar.on('exit', (code, signal) => { logger.info(`Telemetry server exited (code: ${code}, signal: ${signal})`); sidecar = null; }); sidecar.on('error', (err) => { logger.error('Failed to start telemetry server:', err.message); sidecar = null; }); logger.info('Telemetry server started with PID:', sidecar.pid); } function stopSidecar() { if (!sidecar) { logger.debug('Telemetry server not running'); return; } logger.info('Stopping HarborForge Monitor telemetry server...'); sidecar.kill('SIGTERM'); const timeout = setTimeout(() => { if (sidecar && !sidecar.killed) { logger.warn('Telemetry server did not exit gracefully, forcing kill'); sidecar.kill('SIGKILL'); } }, 5000); sidecar.on('exit', () => { clearTimeout(timeout); }); } // Hook into Gateway lifecycle api.on('gateway:start', () => { logger.info('Gateway starting, starting telemetry server...'); startSidecar(); }); api.on('gateway:stop', () => { logger.info('Gateway stopping, stopping telemetry server...'); stopSidecar(); }); // Handle process signals process.on('SIGTERM', stopSidecar); process.on('SIGINT', stopSidecar); // Start immediately if Gateway is already running if (api.isRunning?.()) { startSidecar(); } else { setTimeout(() => startSidecar(), 1000); } // Register status tool api.registerTool(() => ({ name: 'harborforge_monitor_status', description: 'Get HarborForge Monitor plugin status', parameters: { type: 'object', properties: {} }, async execute() { return { enabled: true, sidecarRunning: sidecar !== null && sidecar.exitCode === null, pid: sidecar?.pid || null, config: { backendUrl: config.backendUrl, identifier: config.identifier || 'auto-detected', reportIntervalSec: config.reportIntervalSec } }; } })); logger.info('HarborForge Monitor plugin registered'); } //# sourceMappingURL=index.js.map