agentic-qe
Version:
Agentic Quality Engineering Fleet System - AI-driven quality management platform
224 lines ⢠10.6 kB
JavaScript
;
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;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FleetMonitorCommand = void 0;
const chalk_1 = __importDefault(require("chalk"));
const fs = __importStar(require("fs-extra"));
class FleetMonitorCommand {
static async execute(options) {
// Validate interval
const interval = options.interval || 5000;
if (interval < 100) {
throw new Error('Invalid interval: must be at least 100ms');
}
// Check if fleet is initialized
if (!await fs.pathExists('.agentic-qe/config/fleet.json')) {
throw new Error('Fleet not initialized. Run: aqe fleet init');
}
console.log(chalk_1.default.blue.bold('\nš” Fleet Monitoring Dashboard\n'));
console.log(chalk_1.default.gray(`Update interval: ${interval}ms`));
console.log(chalk_1.default.gray('Press Ctrl+C to stop monitoring\n'));
this.isMonitoring = true;
// Initial status display
await this.displayMonitoringData(options.verbose);
// Set up continuous monitoring
this.monitoringInterval = setInterval(async () => {
if (!this.isMonitoring) {
this.stopMonitoring();
return;
}
// Clear console for fresh display
if (!options.verbose) {
console.clear();
console.log(chalk_1.default.blue.bold('\nš” Fleet Monitoring Dashboard\n'));
}
await this.displayMonitoringData(options.verbose);
}, interval);
// Handle graceful shutdown
process.on('SIGINT', () => {
this.stopMonitoring();
console.log(chalk_1.default.yellow('\n\nš” Monitoring stopped'));
process.exit(0);
});
// Store monitoring start in coordination
await this.storeMonitoringStart();
// Keep process alive if continuous
if (options.continuous !== false) {
await new Promise(() => { }); // Keep alive indefinitely
}
}
static stopMonitoring() {
this.isMonitoring = false;
if (this.monitoringInterval) {
clearInterval(this.monitoringInterval);
this.monitoringInterval = null;
}
}
static async displayMonitoringData(verbose) {
try {
// Load fleet data
const fleetConfig = await fs.readJson('.agentic-qe/config/fleet.json');
const registryPath = '.agentic-qe/data/registry.json';
let registry = { agents: [], tasks: [], fleet: { status: 'unknown' } };
if (await fs.pathExists(registryPath)) {
registry = await fs.readJson(registryPath);
}
// Get real-time metrics
const metrics = await this.collectRealTimeMetrics();
// Display header
console.log(chalk_1.default.blue('š Fleet Status:'));
console.log(chalk_1.default.gray(` ID: ${fleetConfig.id || 'Unknown'}`));
console.log(chalk_1.default.gray(` Topology: ${fleetConfig.topology}`));
console.log(chalk_1.default.gray(` Status: ${this.getStatusEmoji(registry.fleet.status)} ${registry.fleet.status}`));
console.log(chalk_1.default.gray(` Time: ${new Date().toLocaleTimeString()}`));
// Display agent statistics
console.log(chalk_1.default.blue('\nš¤ Agent Statistics:'));
const activeAgents = registry.agents.filter((a) => a.status === 'active').length;
const idleAgents = registry.agents.filter((a) => a.status === 'idle').length;
const busyAgents = registry.agents.filter((a) => a.status === 'busy').length;
console.log(chalk_1.default.gray(` Total Agents: ${registry.agents.length}`));
console.log(chalk_1.default.green(` Active: ${activeAgents}`));
console.log(chalk_1.default.yellow(` Idle: ${idleAgents}`));
console.log(chalk_1.default.cyan(` Busy: ${busyAgents}`));
// Display task statistics
console.log(chalk_1.default.blue('\nš Task Statistics:'));
const runningTasks = registry.tasks.filter((t) => t.status === 'running').length;
const pendingTasks = registry.tasks.filter((t) => t.status === 'pending').length;
const completedTasks = registry.tasks.filter((t) => t.status === 'completed').length;
const failedTasks = registry.tasks.filter((t) => t.status === 'failed').length;
console.log(chalk_1.default.yellow(` Running: ${runningTasks}`));
console.log(chalk_1.default.gray(` Pending: ${pendingTasks}`));
console.log(chalk_1.default.green(` Completed: ${completedTasks}`));
console.log(chalk_1.default.red(` Failed: ${failedTasks}`));
// Display real-time metrics
console.log(chalk_1.default.blue('\nš Performance Metrics:'));
console.log(chalk_1.default.gray(` CPU Usage: ${metrics.cpu.toFixed(1)}%`));
console.log(chalk_1.default.gray(` Memory Usage: ${metrics.memory.toFixed(1)}%`));
console.log(chalk_1.default.gray(` Task Throughput: ${metrics.taskThroughput} tasks/min`));
console.log(chalk_1.default.gray(` Average Response Time: ${metrics.avgResponseTime}ms`));
// Verbose mode: Show detailed agent info
if (verbose && registry.agents.length > 0) {
console.log(chalk_1.default.blue('\nš Agent Details:'));
registry.agents.slice(0, 5).forEach((agent) => {
console.log(chalk_1.default.gray(` ${agent.id}: ${agent.type} - ${agent.status}`));
});
if (registry.agents.length > 5) {
console.log(chalk_1.default.gray(` ... and ${registry.agents.length - 5} more agents`));
}
}
// Display health indicators
const health = this.calculateHealthStatus(registry, metrics);
console.log(chalk_1.default.blue('\nš Health Indicators:'));
console.log(chalk_1.default.gray(` Overall: ${this.getHealthColor(health.overall)}${health.overall}`));
if (health.warnings.length > 0) {
console.log(chalk_1.default.yellow(` Warnings: ${health.warnings.length}`));
}
}
catch (error) {
console.error(chalk_1.default.red('ā Error collecting monitoring data:'), error.message);
}
}
static async collectRealTimeMetrics() {
// Simulate real-time metrics collection
// In production, this would query actual system metrics
return {
cpu: Math.random() * 100,
memory: Math.random() * 100,
taskThroughput: Math.floor(Math.random() * 50),
avgResponseTime: Math.floor(Math.random() * 1000)
};
}
static calculateHealthStatus(registry, metrics) {
const health = {
overall: 'healthy',
warnings: []
};
// Check agent health
const activeAgents = registry.agents.filter((a) => a.status === 'active').length;
if (activeAgents < registry.agents.length * 0.5) {
health.warnings.push('Low active agent count');
health.overall = 'degraded';
}
// Check task failure rate
const tasks = registry.tasks || [];
if (tasks.length > 0) {
const failedTasks = tasks.filter((t) => t.status === 'failed').length;
const failureRate = failedTasks / tasks.length;
if (failureRate > 0.2) {
health.warnings.push(`High task failure rate: ${(failureRate * 100).toFixed(1)}%`);
health.overall = 'degraded';
}
}
// Check resource usage
if (metrics.cpu > 90) {
health.warnings.push('High CPU usage');
health.overall = 'warning';
}
if (metrics.memory > 90) {
health.warnings.push('High memory usage');
health.overall = 'warning';
}
return health;
}
static getStatusEmoji(status) {
const emojis = {
'active': 'š¢',
'running': 'š¢',
'idle': 'š”',
'degraded': 'š”',
'stopped': 'š“',
'failed': 'š“',
'unknown': 'āŖ'
};
return emojis[status] || 'āŖ';
}
static getHealthColor(status) {
const colors = {
'healthy': chalk_1.default.green,
'degraded': chalk_1.default.yellow,
'warning': chalk_1.default.yellow,
'critical': chalk_1.default.red,
'unknown': chalk_1.default.gray
};
return (colors[status] || chalk_1.default.white)(status);
}
static async storeMonitoringStart() {
try {
const { execSync } = require('child_process');
const command = `npx claude-flow@alpha hooks notify --message "Fleet monitoring started"`;
execSync(command, { stdio: 'ignore' });
}
catch (error) {
// Silently handle coordination errors
}
}
}
exports.FleetMonitorCommand = FleetMonitorCommand;
FleetMonitorCommand.isMonitoring = false;
FleetMonitorCommand.monitoringInterval = null;
//# sourceMappingURL=monitor.js.map