@diazpolanco13/context-control-mcp
Version:
🔥 Context Control MCP v5.0 PORTABLE EDITION - Análisis universal de proyectos que funciona en CUALQUIER entorno. Contexto completo automático para IA.
504 lines (428 loc) • 17.4 kB
JavaScript
// 🔥 Context Control MCP v5.0 - PORTABLE EDITION
// Funciona en CUALQUIER proyecto, CUALQUIER entorno, CUALQUIER estructura
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
console.error('🔥 Context Control MCP v5.0 "PORTABLE EDITION" - Análisis Universal');
console.error('==================================================================');
console.error('✅ Funciona en cualquier proyecto, cualquier entorno, cualquier estructura');
console.error('==================================================================');
// 🛡️ UTILIDADES DE SEGURIDAD - Nunca fallan
function safeReadFile(filePath) {
try {
return fs.readFileSync(filePath, 'utf8');
} catch {
return null;
}
}
function safeExecSync(command) {
try {
return execSync(command, { encoding: 'utf8', stdio: 'pipe' });
} catch {
return null;
}
}
function safeFileExists(filePath) {
try {
return fs.existsSync(filePath);
} catch {
return false;
}
}
function safeReadDir(dirPath) {
try {
return fs.readdirSync(dirPath, { withFileTypes: true });
} catch {
return [];
}
}
// 🌍 ANÁLISIS DE ENTORNO
function analyzeEnvironment() {
return {
nodeVersion: process.version,
platform: process.platform,
os: process.platform === 'win32' ? 'Windows' : process.platform === 'darwin' ? 'macOS' : 'Linux',
cwd: process.cwd(),
hasGit: safeExecSync('git --version') !== null,
hasNpm: safeExecSync('npm --version') !== null,
hasYarn: safeExecSync('yarn --version') !== null
};
}
// 📦 ANÁLISIS DE PROYECTO (múltiples estrategias)
function analyzeProjectInfo() {
const project = {
name: 'Unknown Project',
version: '0.0.0',
description: '',
type: 'unknown',
allDependencies: {},
scripts: []
};
// Estrategia 1: package.json
const packageJson = safeReadFile('package.json');
if (packageJson) {
try {
const pkg = JSON.parse(packageJson);
project.name = pkg.name || path.basename(process.cwd());
project.version = pkg.version || '0.0.0';
project.description = pkg.description || '';
project.allDependencies = { ...pkg.dependencies, ...pkg.devDependencies } || {};
project.scripts = Object.keys(pkg.scripts || {});
project.type = detectProjectType(pkg);
} catch (e) {
console.error('⚠️ package.json existe pero tiene formato inválido');
}
} else {
// Estrategia 2: Sin package.json - detectar por archivos
project.name = path.basename(process.cwd());
project.type = detectProjectTypeByFiles();
}
return project;
}
// 🔍 DETECCIÓN DE TIPO DE PROYECTO
function detectProjectType(pkg) {
const deps = { ...pkg.dependencies, ...pkg.devDependencies } || {};
if (deps.next || deps['@next/core']) return 'Next.js App';
if (deps.react) return 'React App';
if (deps.vue) return 'Vue App';
if (deps.angular) return 'Angular App';
if (deps.express) return 'Express API';
if (deps.fastify) return 'Fastify API';
if (deps['@modelcontextprotocol/sdk']) return 'MCP Server';
if (pkg.bin) return 'CLI Tool';
if (pkg.main && !deps.react && !deps.vue) return 'Node.js Library';
return 'Node.js Project';
}
function detectProjectTypeByFiles() {
if (safeFileExists('next.config.js') || safeFileExists('next.config.ts')) return 'Next.js App';
if (safeFileExists('vue.config.js') || safeFileExists('vite.config.js')) return 'Vue App';
if (safeFileExists('angular.json')) return 'Angular App';
if (safeFileExists('Dockerfile')) return 'Docker Project';
if (safeFileExists('requirements.txt')) return 'Python Project';
if (safeFileExists('Cargo.toml')) return 'Rust Project';
if (safeFileExists('go.mod')) return 'Go Project';
if (safeFileExists('pom.xml')) return 'Java Project';
if (safeFileExists('index.html')) return 'Static Website';
return 'Generic Project';
}
// 🏗️ ANÁLISIS DE ARQUITECTURA PORTABLE
function analyzeArchitecturePortable() {
const arch = {
framework: 'Unknown',
database: 'None',
auth: 'None',
testing: 'None',
styling: 'None',
deployment: 'None'
};
// Leer package.json si existe
const packageJson = safeReadFile('package.json');
if (packageJson) {
try {
const pkg = JSON.parse(packageJson);
const deps = { ...pkg.dependencies, ...pkg.devDependencies } || {};
// Framework detection
if (deps.next) arch.framework = `Next.js ${deps.next}`;
else if (deps.react) arch.framework = `React ${deps.react}`;
else if (deps.vue) arch.framework = `Vue ${deps.vue}`;
else if (deps.express) arch.framework = `Express ${deps.express}`;
else if (deps['@modelcontextprotocol/sdk']) arch.framework = 'MCP Server';
// Database detection
if (deps['@prisma/client'] || deps.prisma) arch.database = 'Prisma';
else if (deps.mongoose) arch.database = 'MongoDB';
else if (deps.mysql2) arch.database = 'MySQL';
else if (deps.pg) arch.database = 'PostgreSQL';
// Auth detection
if (deps['@supabase/supabase-js']) arch.auth = 'Supabase';
else if (deps['next-auth']) arch.auth = 'NextAuth';
else if (deps.firebase) arch.auth = 'Firebase';
// Testing detection
if (deps.jest) arch.testing = 'Jest';
else if (deps.vitest) arch.testing = 'Vitest';
else if (deps.mocha) arch.testing = 'Mocha';
// Styling detection
if (deps.tailwindcss) arch.styling = 'Tailwind CSS';
else if (deps['styled-components']) arch.styling = 'Styled Components';
// Deployment detection
if (safeFileExists('vercel.json')) arch.deployment = 'Vercel';
else if (safeFileExists('.netlify')) arch.deployment = 'Netlify';
else if (safeFileExists('Dockerfile')) arch.deployment = 'Docker';
} catch (e) {
console.error('⚠️ Error analizando arquitectura desde package.json');
}
}
// Detección por archivos si no hay package.json
if (arch.framework === 'Unknown') {
if (safeFileExists('next.config.js')) arch.framework = 'Next.js';
else if (safeFileExists('vite.config.js')) arch.framework = 'Vite';
else if (safeFileExists('webpack.config.js')) arch.framework = 'Webpack';
}
return arch;
}
// 📁 ANÁLISIS UNIVERSAL DE ESTRUCTURA
function analyzeUniversalStructure() {
const metrics = {
totalFiles: 0,
codeFiles: 0,
configFiles: 0,
docFiles: 0,
components: 0,
pages: 0,
apis: 0,
tests: 0,
directories: [],
fileTypes: {},
largestFiles: []
};
// Extensiones de código comunes
const codeExtensions = ['.js', '.jsx', '.ts', '.tsx', '.vue', '.py', '.go', '.rs', '.java', '.cpp', '.c', '.php', '.rb'];
const configExtensions = ['.json', '.yaml', '.yml', '.toml', '.ini', '.env'];
const docExtensions = ['.md', '.txt', '.rst', '.adoc'];
// Escanear directorio actual (no recursivo para evitar node_modules)
function scanDirectory(dir, maxDepth = 2, currentDepth = 0) {
if (currentDepth > maxDepth) return;
const items = safeReadDir(dir);
for (const item of items) {
const fullPath = path.join(dir, item.name);
if (item.isDirectory()) {
// Skip directorios problemáticos
if (['node_modules', '.git', '.next', 'dist', 'build', '.cache'].includes(item.name)) {
continue;
}
metrics.directories.push(item.name);
// Detectar tipos especiales de directorios
if (item.name === 'components' || item.name.includes('component')) {
metrics.components += countFilesInDir(fullPath, codeExtensions);
} else if (item.name === 'pages' || item.name === 'app') {
metrics.pages += countFilesInDir(fullPath, codeExtensions);
} else if (item.name === 'api' || item.name.includes('api')) {
metrics.apis += countFilesInDir(fullPath, codeExtensions);
} else if (item.name.includes('test') || item.name.includes('spec')) {
metrics.tests += countFilesInDir(fullPath, codeExtensions);
}
// Recursión limitada
if (currentDepth < maxDepth) {
scanDirectory(fullPath, maxDepth, currentDepth + 1);
}
} else if (item.isFile()) {
metrics.totalFiles++;
const ext = path.extname(item.name);
metrics.fileTypes[ext] = (metrics.fileTypes[ext] || 0) + 1;
if (codeExtensions.includes(ext)) {
metrics.codeFiles++;
} else if (configExtensions.includes(ext)) {
metrics.configFiles++;
} else if (docExtensions.includes(ext)) {
metrics.docFiles++;
}
// Detectar archivos especiales
if (item.name.includes('test') || item.name.includes('spec')) {
metrics.tests++;
}
}
}
}
scanDirectory('.');
return metrics;
}
function countFilesInDir(dir, extensions) {
let count = 0;
const items = safeReadDir(dir);
for (const item of items) {
if (item.isFile()) {
const ext = path.extname(item.name);
if (extensions.includes(ext)) {
count++;
}
}
}
return count;
}
// 🚨 DETECCIÓN DE PROBLEMAS CRÍTICOS
function detectCriticalGaps(project, architecture, metrics) {
const gaps = [];
// Gap 1: Proyecto sin archivos de código
if (metrics.codeFiles === 0) {
gaps.push({
type: 'HIGH',
issue: 'No se detectaron archivos de código',
impact: 'Proyecto podría estar incompleto o en estructura no estándar',
action: 'Verificar estructura de directorios o añadir archivos de código'
});
}
// Gap 2: Proyecto Node.js sin package.json
if (metrics.fileTypes['.js'] > 0 && !safeFileExists('package.json')) {
gaps.push({
type: 'MEDIUM',
issue: 'Archivos JavaScript sin package.json',
impact: 'Dependencias no gestionadas, difícil de mantener',
action: 'Inicializar proyecto con npm init'
});
}
// Gap 3: Muchos archivos pero sin tests
if (metrics.codeFiles > 10 && metrics.tests === 0) {
gaps.push({
type: 'MEDIUM',
issue: `${metrics.codeFiles} archivos de código sin tests`,
impact: 'Calidad del código no verificada',
action: 'Implementar testing con Jest, Vitest o similar'
});
}
// Gap 4: Base de datos configurada pero sin APIs
if (architecture.database !== 'None' && metrics.apis === 0) {
gaps.push({
type: 'HIGH',
issue: 'Base de datos configurada pero sin APIs detectadas',
impact: 'Backend incompleto, frontend desconectado',
action: 'Implementar endpoints API para conectar con la base de datos'
});
}
return gaps;
}
// 💡 DETERMINACIÓN DE PRÓXIMO PASO
function determineIntelligentNextAction(project, architecture, metrics, gaps) {
const criticalGaps = gaps.filter(g => g.type === 'CRITICAL');
const highGaps = gaps.filter(g => g.type === 'HIGH');
if (criticalGaps.length > 0) {
return {
priority: 'CRÍTICA',
action: criticalGaps[0].action,
reasoning: criticalGaps[0].impact,
estimatedHours: criticalGaps.length * 4,
blocksProduction: true
};
}
if (highGaps.length > 0) {
return {
priority: 'ALTA',
action: highGaps[0].action,
reasoning: highGaps[0].impact,
estimatedHours: highGaps.length * 2,
blocksProduction: false
};
}
// Sugerencias basadas en tipo de proyecto
if (project.type.includes('MCP')) {
return {
priority: 'MEDIA',
action: 'Mejorar compatibilidad y documentación del MCP',
reasoning: 'Proyecto MCP detectado, enfocar en usabilidad',
estimatedHours: 4,
blocksProduction: false
};
}
if (metrics.codeFiles > 0 && metrics.tests === 0) {
return {
priority: 'MEDIA',
action: 'Implementar testing para mejorar calidad',
reasoning: `${metrics.codeFiles} archivos sin cobertura de tests`,
estimatedHours: metrics.codeFiles * 0.5,
blocksProduction: false
};
}
return {
priority: 'BAJA',
action: 'Continuar desarrollo según roadmap',
reasoning: 'Proyecto en buen estado técnico',
estimatedHours: 0,
blocksProduction: false
};
}
// 🚀 FUNCIÓN PRINCIPAL
function analyzeProject() {
const results = {
project: {},
architecture: {},
metrics: {},
criticalGaps: [],
nextAction: {},
environment: {}
};
console.error('🔍 Iniciando análisis portable...');
try {
// FASE 0: Entorno
results.environment = analyzeEnvironment();
console.error(`📍 Entorno: ${results.environment.os} | Node: ${results.environment.nodeVersion}`);
// FASE 1: Proyecto
results.project = analyzeProjectInfo();
console.error(`📊 Proyecto: ${results.project.name} detectado como ${results.project.type}`);
// FASE 2: Arquitectura
results.architecture = analyzeArchitecturePortable();
console.error(`🏗️ Stack: ${results.architecture.framework} + ${results.architecture.database}`);
// FASE 3: Estructura
results.metrics = analyzeUniversalStructure();
console.error(`📁 Archivos: ${results.metrics.totalFiles} total, ${results.metrics.codeFiles} código`);
// FASE 4: Gaps críticos
results.criticalGaps = detectCriticalGaps(results.project, results.architecture, results.metrics);
console.error(`🚨 Gaps: ${results.criticalGaps.length} problemas detectados`);
// FASE 5: Próximo paso
results.nextAction = determineIntelligentNextAction(
results.project,
results.architecture,
results.metrics,
results.criticalGaps
);
console.error(`💡 Próximo paso: ${results.nextAction.action}`);
} catch (error) {
console.error('❌ Error en análisis:', error.message);
return null;
}
return results;
}
// 📊 EJECUCIÓN Y DISPLAY
const analysis = analyzeProject();
if (analysis) {
console.log('\n🔥 **ANÁLISIS PORTABLE COMPLETADO**');
console.log('═══════════════════════════════════════════════');
console.log(`\n🌍 **ENTORNO DETECTADO**:`);
console.log(`• Sistema: ${analysis.environment.os} (${analysis.environment.platform})`);
console.log(`• Node.js: ${analysis.environment.nodeVersion}`);
console.log(`• Git: ${analysis.environment.hasGit ? 'Disponible' : 'No disponible'}`);
console.log(`• NPM: ${analysis.environment.hasNpm ? 'Disponible' : 'No disponible'}`);
console.log(`\n📊 **PROYECTO DETECTADO**:`);
console.log(`• Nombre: ${analysis.project.name} v${analysis.project.version}`);
console.log(`• Tipo: ${analysis.project.type}`);
console.log(`• Descripción: ${analysis.project.description || 'Sin descripción'}`);
console.log(`• Scripts: ${analysis.project.scripts.length} comandos disponibles`);
console.log(`\n🏗️ **ARQUITECTURA DETECTADA**:`);
console.log(`• Framework: ${analysis.architecture.framework}`);
console.log(`• Base de datos: ${analysis.architecture.database}`);
console.log(`• Autenticación: ${analysis.architecture.auth}`);
console.log(`• Testing: ${analysis.architecture.testing}`);
console.log(`• Styling: ${analysis.architecture.styling}`);
console.log(`• Deployment: ${analysis.architecture.deployment}`);
console.log(`\n📁 **ESTRUCTURA ANALIZADA**:`);
console.log(`• Total archivos: ${analysis.metrics.totalFiles}`);
console.log(`• Archivos de código: ${analysis.metrics.codeFiles}`);
console.log(`• Archivos de config: ${analysis.metrics.configFiles}`);
console.log(`• Documentación: ${analysis.metrics.docFiles}`);
console.log(`• Componentes: ${analysis.metrics.components}`);
console.log(`• Páginas: ${analysis.metrics.pages}`);
console.log(`• APIs: ${analysis.metrics.apis}`);
console.log(`• Tests: ${analysis.metrics.tests}`);
console.log(`• Directorios: ${analysis.metrics.directories.join(', ')}`);
if (analysis.criticalGaps.length > 0) {
console.log(`\n🚨 **PROBLEMAS DETECTADOS** (${analysis.criticalGaps.length}):`);
analysis.criticalGaps.forEach((gap, i) => {
const icon = gap.type === 'CRITICAL' ? '❌' : gap.type === 'HIGH' ? '⚠️' : 'ℹ️';
console.log(`${i+1}. ${icon} [${gap.type}] ${gap.issue}`);
console.log(` 💥 Impacto: ${gap.impact}`);
console.log(` 🔧 Acción: ${gap.action}`);
});
} else {
console.log('\n✅ **No hay problemas críticos detectados**');
}
console.log(`\n💡 **PRÓXIMO PASO INTELIGENTE**:`);
console.log(`• **Prioridad**: ${analysis.nextAction.priority}`);
console.log(`• **Acción**: ${analysis.nextAction.action}`);
console.log(`• **Razón**: ${analysis.nextAction.reasoning}`);
console.log(`• **Tiempo estimado**: ${analysis.nextAction.estimatedHours} horas`);
console.log(`• **Bloquea producción**: ${analysis.nextAction.blocksProduction ? 'SÍ' : 'NO'}`);
console.log('\n🏆 **ANÁLISIS PORTABLE v5.0 COMPLETADO**');
console.log('✅ Funciona en CUALQUIER proyecto, CUALQUIER entorno, CUALQUIER estructura');
console.log('🚀 Context Control MCP v5.0 "PORTABLE EDITION" - Análisis 100% universal');
} else {
console.error('❌ No se pudo completar el análisis');
process.exit(1);
}