UNPKG

agentic-qe

Version:

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

377 lines (375 loc) 13.5 kB
"use strict"; /** * Diagnostics Command * Runs comprehensive system diagnostics */ 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.runDiagnostics = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const os = __importStar(require("os")); const child_process_1 = require("child_process"); /** * Run comprehensive system diagnostics */ async function runDiagnostics(options) { const checks = []; const checksToRun = options.checks || ['memory', 'cpu', 'disk', 'network', 'dependencies', 'agents', 'performance']; try { for (const checkName of checksToRun) { let check; switch (checkName) { case 'memory': check = await checkMemory(); break; case 'cpu': check = await checkCPU(); break; case 'disk': check = await checkDisk(); break; case 'network': check = await checkNetwork(); break; case 'dependencies': check = await checkDependencies(); break; case 'agents': check = await checkAgents(); break; case 'performance': check = await checkPerformance(); break; default: check = { name: checkName, status: 'fail', message: `Unknown check: ${checkName}`, timestamp: Date.now(), }; } checks.push(check); } // 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(), checks, summary: { total: checks.length, passed: checks.filter(c => c.status === 'pass').length, failed: checks.filter(c => c.status === 'fail').length, warnings: checks.filter(c => c.status === 'warning').length, }, }; if (options.export === 'json') { reportPath = path.join(outputDir, `diagnostics-${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, `diagnostics-${timestamp}.yaml`); fs.writeFileSync(reportPath, yaml.stringify(report)); } else if (options.export === 'html') { reportPath = path.join(outputDir, `diagnostics-${timestamp}.html`); const html = generateHTMLReport(report); fs.writeFileSync(reportPath, html); } } return { success: true, checks, reportPath, }; } catch (error) { return { success: false, checks, error: error.message, }; } } exports.runDiagnostics = runDiagnostics; async function checkMemory() { const memUsage = process.memoryUsage(); const totalMem = os.totalmem(); const freeMem = os.freemem(); const usedPercent = ((totalMem - freeMem) / totalMem) * 100; return { name: 'memory', status: usedPercent > 90 ? 'warning' : 'pass', message: `Memory usage: ${usedPercent.toFixed(2)}%`, data: { heapUsed: memUsage.heapUsed, heapTotal: memUsage.heapTotal, external: memUsage.external, rss: memUsage.rss, totalMem, freeMem, usedPercent, }, timestamp: Date.now(), }; } async function checkCPU() { const cpus = os.cpus(); const loadAvg = os.loadavg(); const avgLoad = loadAvg[0] / cpus.length; return { name: 'cpu', status: avgLoad > 0.8 ? 'warning' : 'pass', message: `CPU load: ${(avgLoad * 100).toFixed(2)}%`, data: { loadAverage: loadAvg, cpuCount: cpus.length, cpuModel: cpus[0]?.model, cpuSpeed: cpus[0]?.speed, avgLoad, }, timestamp: Date.now(), }; } async function checkDisk() { try { // Get disk usage using df command on Linux/Mac or wmic on Windows let diskInfo = {}; if (process.platform === 'win32') { const output = (0, child_process_1.execSync)('wmic logicaldisk get size,freespace,caption', { encoding: 'utf-8' }); diskInfo = { raw: output }; } else { const output = (0, child_process_1.execSync)('df -h /', { encoding: 'utf-8' }); const lines = output.split('\n'); if (lines.length > 1) { const parts = lines[1].split(/\s+/); diskInfo = { filesystem: parts[0], size: parts[1], used: parts[2], available: parts[3], usePercent: parts[4], }; } } return { name: 'disk', status: 'pass', message: 'Disk space check completed', data: { ...diskInfo, total: os.totalmem(), available: os.freemem(), }, timestamp: Date.now(), }; } catch (error) { return { name: 'disk', status: 'warning', message: `Disk check failed: ${error.message}`, timestamp: Date.now(), }; } } async function checkNetwork() { const interfaces = os.networkInterfaces(); const activeInterfaces = Object.entries(interfaces) .filter(([_, addrs]) => addrs && addrs.length > 0) .map(([name, addrs]) => ({ name, addresses: addrs?.map(addr => ({ address: addr.address, family: addr.family, internal: addr.internal, })), })); return { name: 'network', status: activeInterfaces.length > 0 ? 'pass' : 'fail', message: `Found ${activeInterfaces.length} network interface(s)`, data: { interfaces: activeInterfaces, hostname: os.hostname(), }, timestamp: Date.now(), }; } async function checkDependencies() { const packageJsonPath = path.join(process.cwd(), 'package.json'); if (!fs.existsSync(packageJsonPath)) { return { name: 'dependencies', status: 'warning', message: 'No package.json found', timestamp: Date.now(), }; } const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); const deps = { ...packageJson.dependencies, ...packageJson.devDependencies }; const nodeModules = path.join(process.cwd(), 'node_modules'); const installed = fs.existsSync(nodeModules) ? fs.readdirSync(nodeModules).filter(d => !d.startsWith('.')) : []; const missing = Object.keys(deps).filter(dep => !installed.includes(dep)); return { name: 'dependencies', status: missing.length === 0 ? 'pass' : 'warning', message: missing.length === 0 ? 'All dependencies installed' : `${missing.length} missing dependencies`, data: { total: Object.keys(deps).length, installed: installed.length, missing, }, timestamp: Date.now(), }; } async function checkAgents() { const agentDir = path.join(process.cwd(), '.claude', 'agents'); if (!fs.existsSync(agentDir)) { return { name: 'agents', status: 'warning', message: 'No agents directory found', data: { active: 0, idle: 0 }, timestamp: Date.now(), }; } const agents = fs.readdirSync(agentDir).filter(f => f.endsWith('.json')); return { name: 'agents', status: 'pass', message: `Found ${agents.length} agent(s)`, data: { active: agents.length, idle: 0, agents: agents.map(a => a.replace('.json', '')), }, timestamp: Date.now(), }; } async function checkPerformance() { const startTime = Date.now(); // Simulate some work for (let i = 0; i < 1000000; i++) { Math.sqrt(i); } const duration = Date.now() - startTime; const memUsage = process.memoryUsage(); // Detect bottlenecks const bottlenecks = []; if (memUsage.heapUsed > memUsage.heapTotal * 0.8) { bottlenecks.push('High memory usage'); } if (os.loadavg()[0] / os.cpus().length > 0.8) { bottlenecks.push('High CPU load'); } return { name: 'performance', status: bottlenecks.length === 0 ? 'pass' : 'warning', message: bottlenecks.length === 0 ? 'Performance OK' : `Found ${bottlenecks.length} bottleneck(s)`, data: { testDuration: duration, memory: memUsage, bottlenecks, }, timestamp: Date.now(), }; } function generateHTMLReport(report) { const statusColor = (status) => { switch (status) { case 'pass': return '#4ade80'; case 'warning': return '#fbbf24'; case 'fail': return '#f87171'; default: return '#6b7280'; } }; return `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Diagnostics Report</title> <style> body { font-family: system-ui, -apple-system, sans-serif; padding: 20px; background: #f9fafb; } .container { max-width: 1200px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); } h1 { margin-top: 0; } .summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin: 20px 0; } .summary-card { padding: 20px; border-radius: 4px; background: #f3f4f6; } .summary-card h3 { margin: 0 0 10px 0; font-size: 14px; color: #6b7280; } .summary-card .value { font-size: 32px; font-weight: bold; } .checks { margin-top: 30px; } .check { padding: 15px; margin: 10px 0; border-left: 4px solid; border-radius: 4px; background: #f9fafb; } .check h3 { margin: 0 0 5px 0; } .check p { margin: 5px 0; color: #6b7280; } .timestamp { color: #9ca3af; font-size: 12px; } </style> </head> <body> <div class="container"> <h1>Diagnostics Report</h1> <p class="timestamp">Generated: ${new Date(report.timestamp).toLocaleString()}</p> <div class="summary"> <div class="summary-card"> <h3>Total Checks</h3> <div class="value">${report.summary.total}</div> </div> <div class="summary-card"> <h3>Passed</h3> <div class="value" style="color: #4ade80;">${report.summary.passed}</div> </div> <div class="summary-card"> <h3>Warnings</h3> <div class="value" style="color: #fbbf24;">${report.summary.warnings}</div> </div> <div class="summary-card"> <h3>Failed</h3> <div class="value" style="color: #f87171;">${report.summary.failed}</div> </div> </div> <div class="checks"> <h2>Diagnostic Checks</h2> ${report.checks.map((check) => ` <div class="check" style="border-color: ${statusColor(check.status)};"> <h3>${check.name}</h3> <p><strong>Status:</strong> ${check.status.toUpperCase()}</p> <p>${check.message}</p> ${check.data ? `<details><summary>View Details</summary><pre>${JSON.stringify(check.data, null, 2)}</pre></details>` : ''} </div> `).join('')} </div> </div> </body> </html>`; } //# sourceMappingURL=diagnostics.js.map