import express from 'express'; import si from 'systeminformation'; import { eventBus } from '../mcp/EventBus.js'; const router = express.Router(); // Get top processes by CPU usage router.get('/processes', async (req, res) => { try { const data = await si.processes(); // Sort by CPU usage and take top 5 const topProcesses = data.list .sort((a, b) => (b.cpu || 0) - (a.cpu || 0)) .slice(0, 5) .map(p => ({ name: p.name || 'Unknown', cpu: Number((p.cpu || 0).toFixed(1)), mem: Number((p.mem || 0).toFixed(1)), pid: p.pid })); res.json(topProcesses); } catch (error) { console.error('Error fetching processes:', error); res.status(500).json({ error: 'Failed to fetch process information' }); } }); // Get system information (CPU, memory, etc.) router.get('/system', async (req, res) => { try { const [cpu, mem, osInfo, currentLoad, cpuTemp] = await Promise.all([ si.cpu(), si.mem(), si.osInfo(), si.currentLoad(), si.cpuTemperature() ]); const systemInfo = { cpu: { manufacturer: cpu.manufacturer, brand: cpu.brand, cores: cpu.cores, physicalCores: cpu.physicalCores, speed: cpu.speed, temperature: cpuTemp.main || null }, memory: { total: mem.total, used: mem.used, available: mem.available, usedPercent: Number(((mem.used / mem.total) * 100).toFixed(1)) }, os: { platform: osInfo.platform, distro: osInfo.distro, release: osInfo.release, arch: osInfo.arch }, load: { avgLoad: Number(currentLoad.avgLoad.toFixed(2)), currentLoad: Number(currentLoad.currentLoad.toFixed(1)), currentLoadUser: Number(currentLoad.currentLoadUser.toFixed(1)), currentLoadSystem: Number(currentLoad.currentLoadSystem.toFixed(1)) } }; // Check for high load and emit event if (systemInfo.load.currentLoad > 90) { eventBus.emitEvent({ type: 'system.alert', timestamp: new Date().toISOString(), source: 'sys.ts', payload: { message: 'High CPU Load detected', load: systemInfo.load.currentLoad } }); } res.json(systemInfo); } catch (error) { console.error('Error fetching system info:', error); res.status(500).json({ error: 'Failed to fetch system information' }); } }); // Get network information router.get('/network', async (req, res) => { try { const [networkStats, networkConnections] = await Promise.all([ si.networkStats(), si.networkConnections() ]); // Get the primary network interface stats const primaryInterface = networkStats.find(stat => stat.rx_sec || stat.tx_sec); const networkInfo = { stats: primaryInterface ? { interface: primaryInterface.iface, rx_sec: primaryInterface.rx_sec || 0, tx_sec: primaryInterface.tx_sec || 0, rx_bytes: primaryInterface.rx_bytes || 0, tx_bytes: primaryInterface.tx_bytes || 0 } : null, connections: networkConnections.length, activeConnections: networkConnections.filter(conn => conn.state === 'ESTABLISHED').length }; res.json(networkInfo); } catch (error) { console.error('Error fetching network info:', error); res.status(500).json({ error: 'Failed to fetch network information' }); } }); // Get GPU information router.get('/gpu', async (req, res) => { try { const graphics = await si.graphics(); const gpuInfo = graphics.controllers.map(gpu => ({ vendor: gpu.vendor, model: gpu.model, vram: gpu.vram, temperature: (gpu as any).temperatureGpu || null, utilizationGpu: gpu.utilizationGpu || null })); res.json(gpuInfo); } catch (error) { console.error('Error fetching GPU info:', error); res.status(500).json({ error: 'Failed to fetch GPU information' }); } }); // Get Real Security Anomalies (No Mock) router.get('/security/anomalies', async (req, res) => { try { const [processes, connections] = await Promise.all([ si.processes(), si.networkConnections() ]); const anomalies = []; // 1. High Resource Processes (Potential Crypto Miners / Runaway scripts) const heavyProcs = processes.list.filter(p => p.cpu > 50 || p.mem > 10); // >50% CPU or >10% Mem heavyProcs.forEach(p => { anomalies.push({ id: `PROC-${p.pid}`, type: 'RESOURCE_ANOMALY', severity: p.cpu > 80 ? 'CRITICAL' : 'HIGH', source: p.name, details: `PID: ${p.pid} | CPU: ${p.cpu.toFixed(1)}% | MEM: ${p.mem.toFixed(1)}%`, path: p.path, timestamp: new Date().toISOString() }); }); // 2. Exposed Ports (Listening on 0.0.0.0) const listeningPorts = connections.filter(c => c.state === 'LISTEN' && (c.localAddress === '0.0.0.0' || c.localAddress === '::')); listeningPorts.forEach(c => { // Filter out standard safe ports if needed, but show all for visibility anomalies.push({ id: `NET-${c.localPort}`, type: 'OPEN_PORT', severity: 'MEDIUM', source: c.process || `Port ${c.localPort}`, details: `Listening on ${c.localAddress}:${c.localPort} (${c.protocol})`, path: 'NETWORK', timestamp: new Date().toISOString() }); }); res.json({ count: anomalies.length, critical: anomalies.filter(a => a.severity === 'CRITICAL').length, high: anomalies.filter(a => a.severity === 'HIGH').length, anomalies }); } catch (error) { console.error('Error scanning anomalies:', error); res.status(500).json({ error: 'Failed to scan system anomalies' }); } }); export default router;