201 lines
6.2 KiB
JavaScript
201 lines
6.2 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
/**
|
||
* Script de validação do Model Context Protocol (MCP)
|
||
* Verifica se a estrutura MCP está correta e todos os arquivos referenciados existem
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
// Cores para output no terminal
|
||
const colors = {
|
||
green: '\x1b[32m',
|
||
red: '\x1b[31m',
|
||
yellow: '\x1b[33m',
|
||
blue: '\x1b[34m',
|
||
reset: '\x1b[0m'
|
||
};
|
||
|
||
function log(message, color = 'reset') {
|
||
console.log(`${colors[color]}${message}${colors.reset}`);
|
||
}
|
||
|
||
function validateMCPStructure() {
|
||
log('🔍 Validando estrutura MCP...', 'blue');
|
||
|
||
let errors = 0;
|
||
let warnings = 0;
|
||
|
||
// Verificar se arquivos principais existem
|
||
const requiredFiles = [
|
||
'MCP.md',
|
||
'.mcp/config.json',
|
||
'.mcp/README.md'
|
||
];
|
||
|
||
log('\n📁 Verificando arquivos principais:');
|
||
|
||
requiredFiles.forEach(file => {
|
||
if (fs.existsSync(file)) {
|
||
log(` ✅ ${file}`, 'green');
|
||
} else {
|
||
log(` ❌ ${file} - AUSENTE`, 'red');
|
||
errors++;
|
||
}
|
||
});
|
||
|
||
// Carregar e validar config.json
|
||
try {
|
||
const configPath = '.mcp/config.json';
|
||
if (fs.existsSync(configPath)) {
|
||
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
||
|
||
log('\n⚙️ Validando configuração:');
|
||
|
||
// Verificar se projetos existem
|
||
if (config.projects) {
|
||
log(' 📂 Verificando projetos:');
|
||
Object.entries(config.projects).forEach(([key, project]) => {
|
||
if (fs.existsSync(project.path)) {
|
||
log(` ✅ ${key}: ${project.path}`, 'green');
|
||
} else {
|
||
log(` ❌ ${key}: ${project.path} - AUSENTE`, 'red');
|
||
errors++;
|
||
}
|
||
});
|
||
}
|
||
|
||
// Verificar contextos
|
||
if (config.contexts) {
|
||
log(' 📋 Verificando contextos:');
|
||
Object.entries(config.contexts).forEach(([key, context]) => {
|
||
log(` 📌 ${key}: ${context.description}`);
|
||
if (context.files) {
|
||
context.files.forEach(file => {
|
||
// Remover wildcards para verificação básica
|
||
const cleanFile = file.replace(/\/\*\*\/\*\.\w+$/, '');
|
||
if (file.includes('**')) {
|
||
// É um padrão wildcard, verificar se diretório existe
|
||
const dir = cleanFile;
|
||
if (fs.existsSync(dir)) {
|
||
log(` ✅ ${file} (padrão)`, 'green');
|
||
} else {
|
||
log(` ⚠️ ${file} (diretório base não encontrado)`, 'yellow');
|
||
warnings++;
|
||
}
|
||
} else {
|
||
// Arquivo específico
|
||
if (fs.existsSync(file)) {
|
||
log(` ✅ ${file}`, 'green');
|
||
} else {
|
||
log(` ⚠️ ${file} - não encontrado`, 'yellow');
|
||
warnings++;
|
||
}
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
// Verificar se package.json está alinhado com configuração
|
||
if (fs.existsSync('package.json')) {
|
||
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
||
|
||
log('\n📦 Verificando alinhamento com package.json:');
|
||
|
||
// Verificar scripts
|
||
if (config.tools && config.tools['development-servers']) {
|
||
const devCommands = config.tools['development-servers'].commands;
|
||
Object.entries(devCommands).forEach(([project, command]) => {
|
||
const scriptName = `serve:${project}` || `${project.toUpperCase()}_development`;
|
||
if (packageJson.scripts && Object.values(packageJson.scripts).some(script => script.includes(command.split(' ')[2]))) {
|
||
log(` ✅ Script para ${project} encontrado`, 'green');
|
||
} else {
|
||
log(` ⚠️ Script para ${project} pode estar desatualizado`, 'yellow');
|
||
warnings++;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
}
|
||
} catch (error) {
|
||
log(`❌ Erro ao validar config.json: ${error.message}`, 'red');
|
||
errors++;
|
||
}
|
||
|
||
// Verificar estrutura de domínios do IDT App
|
||
const idtAppPath = 'projects/idt_app/src/app';
|
||
if (fs.existsSync(idtAppPath)) {
|
||
log('\n🏗️ Verificando estrutura IDT App:');
|
||
|
||
const domainPath = path.join(idtAppPath, 'domain');
|
||
if (fs.existsSync(domainPath)) {
|
||
const domains = fs.readdirSync(domainPath, { withFileTypes: true })
|
||
.filter(dirent => dirent.isDirectory())
|
||
.map(dirent => dirent.name);
|
||
|
||
log(` 📁 Domínios encontrados: ${domains.join(', ')}`, 'blue');
|
||
|
||
domains.forEach(domain => {
|
||
const domainDir = path.join(domainPath, domain);
|
||
const expectedDirs = ['components', 'services', 'interfaces'];
|
||
|
||
expectedDirs.forEach(dir => {
|
||
const dirPath = path.join(domainDir, dir);
|
||
if (fs.existsSync(dirPath)) {
|
||
log(` ✅ ${domain}/${dir}`, 'green');
|
||
} else {
|
||
log(` ⚠️ ${domain}/${dir} - recomendado`, 'yellow');
|
||
warnings++;
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
const sharedPath = path.join(idtAppPath, 'shared');
|
||
if (fs.existsSync(sharedPath)) {
|
||
log(' 📁 Verificando estrutura shared:');
|
||
const expectedSharedDirs = ['components', 'services', 'interfaces'];
|
||
|
||
expectedSharedDirs.forEach(dir => {
|
||
const dirPath = path.join(sharedPath, dir);
|
||
if (fs.existsSync(dirPath)) {
|
||
log(` ✅ shared/${dir}`, 'green');
|
||
} else {
|
||
log(` ⚠️ shared/${dir} - recomendado`, 'yellow');
|
||
warnings++;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
// Relatório final
|
||
log('\n📊 Relatório da Validação:', 'blue');
|
||
|
||
if (errors === 0 && warnings === 0) {
|
||
log('🎉 Estrutura MCP válida e completa!', 'green');
|
||
} else {
|
||
if (errors > 0) {
|
||
log(`❌ ${errors} erro(s) encontrado(s)`, 'red');
|
||
}
|
||
if (warnings > 0) {
|
||
log(`⚠️ ${warnings} aviso(s) encontrado(s)`, 'yellow');
|
||
}
|
||
|
||
if (errors === 0) {
|
||
log('✅ Nenhum erro crítico encontrado', 'green');
|
||
}
|
||
}
|
||
|
||
return { errors, warnings };
|
||
}
|
||
|
||
// Executar validação
|
||
if (require.main === module) {
|
||
const result = validateMCPStructure();
|
||
process.exit(result.errors > 0 ? 1 : 0);
|
||
}
|
||
|
||
module.exports = { validateMCPStructure };
|