testes/.agent/orchestrator/AgentOrchestrator.js

263 lines
7.3 KiB
JavaScript

/**
* 🤖 ORQUESTRADOR DE AGENTES - Sistema de Validação Automatizada
*
* Este módulo coordena todos os agentes/personas do sistema para validar
* componentes, features e builds de forma automatizada.
*
* @module AgentOrchestrator
*/
import { BrowserValidationAgent } from '../agents/BrowserValidationAgent.js';
import { UIAdaptationAgent } from '../agents/UIAdaptationAgent.js';
import { DataIntegrityAgent } from '../agents/DataIntegrityAgent.js';
import { PerformanceOptimizationAgent } from '../agents/PerformanceOptimizationAgent.js';
import { FontQualityAgent } from '../agents/FontQualityAgent.js';
import { GitSyncAgent } from '../agents/GitSyncAgent.js';
import { DocumentationAgent } from '../agents/DocumentationAgent.js';
import { SecurityAgent } from '../agents/SecurityAgent.js';
/**
* Resultado de uma validação de agente
* @typedef {Object} ValidationResult
* @property {string} agent - Nome do agente
* @property {boolean} passed - Se a validação passou
* @property {string[]} errors - Lista de erros encontrados
* @property {string[]} warnings - Lista de avisos
* @property {Object} metadata - Metadados adicionais
*/
export class AgentOrchestrator {
constructor(options = {}) {
this.agents = [];
this.results = [];
this.options = {
verbose: options.verbose ?? false,
failFast: options.failFast ?? false,
...options
};
this.initializeAgents();
}
/**
* Inicializa todos os agentes disponíveis
*/
initializeAgents() {
this.agents = [
new BrowserValidationAgent(),
new UIAdaptationAgent(),
new DataIntegrityAgent(),
new PerformanceOptimizationAgent(),
new FontQualityAgent(),
new GitSyncAgent(),
new DocumentationAgent(),
new SecurityAgent()
];
}
/**
* Executa validação de um componente específico
* @param {string|Object} component - Componente ou caminho do componente
* @param {Object} context - Contexto adicional (props, environment, etc)
* @returns {Promise<ValidationResult[]>}
*/
async validateComponent(component, context = {}) {
const componentPath = typeof component === 'string' ? component : component.path;
const componentName = typeof component === 'string'
? component.split('/').pop().replace(/\.(jsx?|tsx?)$/, '')
: component.name;
if (this.options.verbose) {
console.log(`\n🔍 Validando componente: ${componentName}`);
console.log(`📁 Caminho: ${componentPath}`);
}
const results = [];
for (const agent of this.agents) {
try {
if (this.options.verbose) {
console.log(` 🤖 Executando: ${agent.name}...`);
}
const result = await agent.validate(component, context);
results.push({
agent: agent.name,
component: componentName,
...result
});
if (result.passed === false && this.options.failFast) {
if (this.options.verbose) {
console.log(` ❌ Falha detectada. Parando validação (failFast=true)`);
}
break;
}
} catch (error) {
results.push({
agent: agent.name,
component: componentName,
passed: false,
errors: [`Erro ao executar agente: ${error.message}`],
warnings: [],
metadata: { error: error.stack }
});
}
}
this.results.push(...results);
return results;
}
/**
* Executa validação de múltiplos componentes
* @param {Array<string|Object>} components - Lista de componentes
* @param {Object} context - Contexto compartilhado
* @returns {Promise<ValidationResult[]>}
*/
async validateComponents(components, context = {}) {
const allResults = [];
for (const component of components) {
const results = await this.validateComponent(component, context);
allResults.push(...results);
}
return allResults;
}
/**
* Executa validação de uma feature completa
* @param {string} featurePath - Caminho da feature (ex: 'src/features/rh')
* @param {Object} context - Contexto adicional
* @returns {Promise<ValidationResult[]>}
*/
async validateFeature(featurePath, context = {}) {
if (this.options.verbose) {
console.log(`\n📦 Validando feature: ${featurePath}`);
}
// Esta função será expandida para descobrir componentes automaticamente
// Por enquanto, requer lista explícita de componentes
const components = context.components || [];
return this.validateComponents(components, { ...context, featurePath });
}
/**
* Executa validação de build
* @param {Object} buildInfo - Informações do build
* @returns {Promise<ValidationResult[]>}
*/
async validateBuild(buildInfo = {}) {
if (this.options.verbose) {
console.log(`\n🏗️ Validando build...`);
}
const results = [];
// Validações específicas de build
for (const agent of this.agents) {
if (agent.validateBuild) {
try {
const result = await agent.validateBuild(buildInfo);
results.push({
agent: agent.name,
type: 'build',
...result
});
} catch (error) {
results.push({
agent: agent.name,
type: 'build',
passed: false,
errors: [`Erro na validação de build: ${error.message}`],
warnings: [],
metadata: { error: error.stack }
});
}
}
}
this.results.push(...results);
return results;
}
/**
* Gera relatório de validação
* @returns {Object}
*/
generateReport() {
const total = this.results.length;
const passed = this.results.filter(r => r.passed).length;
const failed = total - passed;
const warnings = this.results.reduce((acc, r) => acc + (r.warnings?.length || 0), 0);
const errors = this.results.reduce((acc, r) => acc + (r.errors?.length || 0), 0);
const report = {
summary: {
total,
passed,
failed,
warnings,
errors,
successRate: total > 0 ? ((passed / total) * 100).toFixed(2) : 0
},
results: this.results,
byAgent: this.groupByAgent(),
byComponent: this.groupByComponent()
};
return report;
}
/**
* Agrupa resultados por agente
* @returns {Object}
*/
groupByAgent() {
const grouped = {};
for (const result of this.results) {
if (!grouped[result.agent]) {
grouped[result.agent] = [];
}
grouped[result.agent].push(result);
}
return grouped;
}
/**
* Agrupa resultados por componente
* @returns {Object}
*/
groupByComponent() {
const grouped = {};
for (const result of this.results) {
const component = result.component || 'unknown';
if (!grouped[component]) {
grouped[component] = [];
}
grouped[component].push(result);
}
return grouped;
}
/**
* Limpa resultados anteriores
*/
clearResults() {
this.results = [];
}
/**
* Exporta resultados para JSON
* @param {string} filePath - Caminho do arquivo
*/
async exportResults(filePath) {
const fs = await import('fs/promises');
const report = this.generateReport();
await fs.writeFile(filePath, JSON.stringify(report, null, 2), 'utf-8');
}
}
export default AgentOrchestrator;