UNPKG

agentic-qe

Version:

Agentic Quality Engineering Fleet System - AI-driven quality management platform

317 lines 11 kB
"use strict"; /** * Health Check Command * Performs system health checks with export capabilities */ 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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.healthCheck = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const os = __importStar(require("os")); /** * Perform system health check */ async function healthCheck(options) { const components = []; const startTime = Date.now(); try { // Check core components components.push(await checkMemoryHealth(options)); components.push(await checkCPUHealth(options)); components.push(await checkDiskHealth(options)); if (options.comprehensive) { components.push(await checkAgentHealth(options)); components.push(await checkNetworkHealth(options)); components.push(await checkDependencyHealth(options)); components.push(await checkDatabaseHealth(options)); } // Determine overall status const hasUnhealthy = components.some(c => c.status === 'unhealthy'); const hasDegraded = components.some(c => c.status === 'degraded'); const overallStatus = hasUnhealthy ? 'unhealthy' : hasDegraded ? 'degraded' : 'healthy'; const unhealthyComponents = components .filter(c => c.status !== 'healthy') .map(c => c.name); // Collect remediation suggestions let remediation; if (options.includeRemediation && unhealthyComponents.length > 0) { remediation = {}; for (const component of components) { if (component.status !== 'healthy' && component.remediation) { remediation[component.name] = component.remediation; } } } // Measure performance if requested let performanceMetrics; if (options.measurePerformance) { const responseTime = Math.max(Date.now() - startTime, 1); // Ensure at least 1ms performanceMetrics = { responseTime, throughput: components.length / (responseTime / 1000), errorRate: unhealthyComponents.length / components.length, }; } // Export report if requested let reportPath; if (options.export) { const outputDir = options.outputDir || path.join(process.cwd(), '.swarm', 'reports'); fs.mkdirSync(outputDir, { recursive: true }); const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const report = { timestamp: Date.now(), status: overallStatus, components, unhealthyComponents, remediation, performanceMetrics, }; if (options.export === 'json') { reportPath = path.join(outputDir, `health-check-${timestamp}.json`); fs.writeFileSync(reportPath, JSON.stringify(report, null, 2)); } else if (options.export === 'yaml') { const yaml = await Promise.resolve().then(() => __importStar(require('yaml'))); reportPath = path.join(outputDir, `health-check-${timestamp}.yaml`); fs.writeFileSync(reportPath, yaml.stringify(report)); } } return { success: true, status: overallStatus, components, unhealthyComponents: unhealthyComponents.length > 0 ? unhealthyComponents : undefined, remediation, performanceMetrics, reportPath, timestamp: Date.now(), }; } catch (error) { return { success: false, status: 'unhealthy', components, timestamp: Date.now(), }; } } exports.healthCheck = healthCheck; async function checkMemoryHealth(options) { const memUsage = process.memoryUsage(); const totalMem = os.totalmem(); const freeMem = os.freemem(); const usedPercent = ((totalMem - freeMem) / totalMem) * 100; let status; let remediation; if (usedPercent > 95) { status = 'unhealthy'; remediation = [ 'Memory usage critical (>95%)', 'Restart the application', 'Increase system memory', 'Check for memory leaks', ]; } else if (usedPercent > 85) { status = 'degraded'; remediation = [ 'Memory usage high (>85%)', 'Monitor memory consumption', 'Consider restarting soon', ]; } else { status = 'healthy'; } return { name: 'memory', status, message: `Memory usage: ${usedPercent.toFixed(2)}%`, metrics: { heapUsed: memUsage.heapUsed, heapTotal: memUsage.heapTotal, usedPercent, }, remediation: options.includeRemediation ? remediation : undefined, }; } async function checkCPUHealth(options) { const cpus = os.cpus(); const loadAvg = os.loadavg(); const avgLoad = loadAvg[0] / cpus.length; let status; let remediation; if (avgLoad > 0.95) { status = 'unhealthy'; remediation = [ 'CPU load critical (>95%)', 'Identify CPU-intensive processes', 'Scale horizontally', 'Optimize code performance', ]; } else if (avgLoad > 0.80) { status = 'degraded'; remediation = [ 'CPU load high (>80%)', 'Monitor CPU usage', 'Profile application performance', ]; } else { status = 'healthy'; } return { name: 'cpu', status, message: `CPU load: ${(avgLoad * 100).toFixed(2)}%`, metrics: { loadAverage: loadAvg, cpuCount: cpus.length, avgLoad, }, remediation: options.includeRemediation ? remediation : undefined, }; } async function checkDiskHealth(options) { const tmpDir = os.tmpdir(); let status = 'healthy'; const metrics = {}; try { // Try to write a test file const testFile = path.join(tmpDir, 'health-check-test'); fs.writeFileSync(testFile, 'test'); fs.unlinkSync(testFile); metrics.writable = true; status = 'healthy'; } catch (error) { metrics.writable = false; status = 'unhealthy'; } return { name: 'disk', status, message: status === 'healthy' ? 'Disk accessible' : 'Disk write failed', metrics, remediation: status !== 'healthy' ? [ 'Disk write failed', 'Check disk permissions', 'Check disk space', 'Verify mount points', ] : undefined, }; } async function checkAgentHealth(options) { const agentDir = path.join(process.cwd(), '.claude', 'agents'); if (!fs.existsSync(agentDir)) { return { name: 'agents', status: 'degraded', message: 'No agents configured', remediation: ['Initialize agent fleet with: aqe init'], }; } const agents = fs.readdirSync(agentDir).filter(f => f.endsWith('.json')); return { name: 'agents', status: agents.length > 0 ? 'healthy' : 'degraded', message: `${agents.length} agent(s) configured`, metrics: { agentCount: agents.length }, }; } async function checkNetworkHealth(options) { const interfaces = os.networkInterfaces(); const hasActive = Object.values(interfaces).some(addrs => addrs?.some(addr => !addr.internal && addr.family === 'IPv4')); return { name: 'network', status: hasActive ? 'healthy' : 'unhealthy', message: hasActive ? 'Network available' : 'No network connectivity', remediation: !hasActive ? [ 'No network connectivity detected', 'Check network cables', 'Verify network configuration', 'Restart network service', ] : undefined, }; } async function checkDependencyHealth(options) { const packageJsonPath = path.join(process.cwd(), 'package.json'); if (!fs.existsSync(packageJsonPath)) { return { name: 'dependencies', status: 'degraded', message: 'No package.json found', }; } const nodeModules = path.join(process.cwd(), 'node_modules'); const hasNodeModules = fs.existsSync(nodeModules); return { name: 'dependencies', status: hasNodeModules ? 'healthy' : 'degraded', message: hasNodeModules ? 'Dependencies installed' : 'Dependencies not installed', remediation: !hasNodeModules ? ['Run: npm install'] : undefined, }; } async function checkDatabaseHealth(options) { const dbPath = path.join(process.cwd(), '.swarm', 'memory.db'); if (!fs.existsSync(dbPath)) { return { name: 'database', status: 'degraded', message: 'Database not initialized', remediation: ['Initialize database with: npx claude-flow memory store "test" "value"'], }; } try { const stats = fs.statSync(dbPath); return { name: 'database', status: 'healthy', message: 'Database accessible', metrics: { size: stats.size, modified: stats.mtime, }, }; } catch (error) { return { name: 'database', status: 'unhealthy', message: 'Database access failed', remediation: [ 'Database file exists but cannot be accessed', 'Check file permissions', 'Verify database is not corrupted', ], }; } } //# sourceMappingURL=health-check.js.map