263 lines
7.3 KiB
JavaScript
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;
|