UNPKG

acs-framework-cli

Version:

🚀 CLI inteligente para configurar automáticamente el Augmented Context Standard (ACS) Framework. Context-as-Code que convierte tu conocimiento en un activo versionado.

376 lines (318 loc) 13.4 kB
const fs = require('fs-extra'); const path = require('path'); const chalk = require('chalk'); const inquirer = require('inquirer'); /** * NUEVO ONBOARDING SIMPLIFICADO * Máximo 3 preguntas, enfoque en valor inmediato * * Filosofía ACS: "Context-as-Code" - no interrogatorios, sino valor directo */ class StreamlinedOnboarding { constructor(targetDir) { this.targetDir = targetDir; this.projectInsights = null; } async run() { console.clear(); await this.showWelcome(); // Cargar preferencias del usuario const UserPreferences = require('./user-preferences'); this.userPrefs = new UserPreferences(); await this.userPrefs.load(); // Análisis automático primero await this.analyzeProject(); // Solo preguntar si es necesario const userPreferences = await this.getSmartPreferences(); // Recomendación directa basada en contexto const recommendation = this.generateRecommendation(userPreferences); return { insights: this.projectInsights, preferences: userPreferences, recommendation }; } async showWelcome() { console.log(chalk.cyan(` █████╗ ██████╗ ███████╗ ██╔══██╗██╔════╝ ██╔════╝ ███████║██║ ███████╗ ██╔══██║██║ ╚════██║ ██║ ██║╚██████╗ ███████║ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ${chalk.white.bold('ACS FRAMEWORK')} - ${chalk.gray('Hub Central de Control')} `)); } async analyzeProject() { console.log(chalk.yellow('🔍 Analizando tu proyecto...')); const SmartComplexityAnalyzer = require('./smart-complexity-analyzer'); const complexityAnalyzer = new SmartComplexityAnalyzer(this.targetDir); const complexityAnalysis = await complexityAnalyzer.analyze(); // Detectar tipo de proyecto de manera inteligente const projectType = await this.detectProjectType(); // Detectar si ya tiene ACS const hasACS = await fs.pathExists(path.join(this.targetDir, '.context')); this.projectInsights = { projectType, complexity: complexityAnalysis, hasACS, directory: path.basename(this.targetDir) }; // Mostrar resumen conciso this.showProjectSummary(); } showProjectSummary() { const { projectType, complexity, hasACS, directory } = this.projectInsights; console.log(chalk.magenta('\n📊 Tu proyecto:')); console.log(` 📁 ${chalk.cyan(directory)} - ${chalk.yellow(projectType)}`); console.log(` ${complexity.icon} Complejidad: ${complexity.description}`); console.log(` ⏱️ Setup estimado: ${chalk.cyan(complexity.estimatedSetupTime)}`); if (hasACS) { console.log(` ✅ ACS ya configurado`); } else { console.log(` 💡 ACS no configurado - ${chalk.green('¡perfecto para empezar!')}`); } // Mostrar valor específico para este proyecto this.showProjectSpecificValue(); } showProjectSpecificValue() { const { projectType, complexity } = this.projectInsights; console.log(chalk.cyan('\n🎁 ACS te ayudará con:')); // Beneficios centrados en el desarrollador, no en riesgos empresariales console.log(chalk.green(' ✨ IA que respeta tu arquitectura y no alucina')); console.log(chalk.green(' � Eliminar las "cajas negras" que frenan la innovación')); console.log(chalk.green(' 🧠 Convertir tu conocimiento en un activo del equipo')); console.log(chalk.green(' ⚡ Onboarding instantáneo sin interrumpir a seniors')); // Solo agregar beneficio específico si es relevante if (complexity.level === 'complex') { console.log(chalk.green(' 🎯 Navegación inteligente en proyectos complejos')); } else { console.log(chalk.green(' 🎯 Base sólida que escala con tu proyecto')); } } async getSmartPreferences() { // Si ya tenemos preferencias recientes, usarlas SIN PREGUNTAR if (this.userPrefs.hasPreferences() && this.userPrefs.isRecentUser()) { const savedPrefs = this.userPrefs.getPreferences(); console.log(chalk.blue(`👋 Usando tus preferencias guardadas (${savedPrefs.comfortLevel})`)); console.log(chalk.gray(' Tip: usa "acs-master --reset-prefs" para cambiarlas\n')); return { comfortLevel: savedPrefs.comfortLevel, priority: savedPrefs.defaultPriority || 'fast-setup', teamContext: savedPrefs.teamContext || 'solo' }; } // SOLO SI ES PRIMERA VEZ - hacer onboarding console.log(chalk.cyan('\n🤔 Primera vez usando ACS - configuración rápida:')); const preferences = await this.askEssentialQuestions(); // Guardar para NO preguntar otra vez await this.userPrefs.save({ comfortLevel: preferences.comfortLevel, defaultPriority: preferences.priority, teamContext: preferences.teamContext }); console.log(chalk.green('✅ Preferencias guardadas - no se preguntarán de nuevo')); return preferences; } async askEssentialQuestions() { console.log(chalk.yellow('⚡ 3 preguntas rápidas para optimizar tu experiencia:\n')); // PREGUNTA 1: Estilo de trabajo real con diferencias claras const { workStyle } = await inquirer.prompt([{ type: 'list', name: 'workStyle', message: '¿Cómo prefieres trabajar con herramientas CLI?', choices: [ { name: '🚀 Directo - mínimas preguntas, máxima velocidad', value: 'direct', short: 'Directo' }, { name: '🎯 Balanceado - algunas opciones, explicaciones concisas', value: 'guided', short: 'Balanceado' }, { name: '📚 Educativo - explicaciones detalladas, tutoriales', value: 'educational', short: 'Educativo' } ], default: 'guided' }]); // PREGUNTA 2: Solo si proyecto complejo O usuario educativo let priority = 'fast-setup'; if (this.projectInsights.complexity.level === 'complex' || workStyle === 'educational') { const { priorityChoice } = await inquirer.prompt([{ type: 'list', name: 'priorityChoice', message: this.projectInsights.complexity.level === 'complex' ? 'Proyecto complejo detectado. ¿Tu estrategia?' : '¿Prefieres setup rápido o completo?', choices: [ { name: '⚡ Setup básico ahora, optimizar después', value: 'fast-setup' }, { name: '🎯 Setup completo desde el inicio', value: 'thorough-setup' } ], default: workStyle === 'direct' ? 'fast-setup' : 'thorough-setup' }]); priority = priorityChoice; } else { // Auto-asignar basado en estilo priority = workStyle === 'direct' ? 'fast-setup' : 'standard-setup'; } // PREGUNTA 3: Solo si no tiene ACS let teamContext = 'solo'; if (!this.projectInsights.hasACS) { const { teamChoice } = await inquirer.prompt([{ type: 'list', name: 'teamChoice', message: '¿Contexto de este proyecto?', choices: [ { name: '👤 Personal/Solo', value: 'solo' }, { name: '👥 Equipo pequeño (2-5 devs)', value: 'team' }, { name: '🏢 Empresarial (6+ devs)', value: 'enterprise' } ], default: 'solo' }]); teamContext = teamChoice; } return { comfortLevel: workStyle, priority, teamContext }; } generateRecommendation(preferences) { const { complexity, hasACS, projectType } = this.projectInsights; const { comfortLevel, priority, teamContext } = preferences; const recommendation = { action: '', explanation: '', estimatedTime: complexity.estimatedSetupTime, nextSteps: [] }; // Lógica de recomendación basada en contexto if (hasACS) { recommendation.action = 'optimize'; recommendation.explanation = 'Tu proyecto ya tiene ACS. Te ayudo a optimizarlo.'; recommendation.nextSteps = [ '🔍 Validar documentación existente', '🤖 Ejecutar agente para actualizaciones', '📊 Generar reporte de completitud' ]; } else if (priority === 'fast-setup' && complexity.level === 'simple') { recommendation.action = 'auto-setup'; recommendation.explanation = 'Setup automático perfecto para tu proyecto.'; recommendation.nextSteps = [ '🚀 Configuración automática (2 min)', '🧠 IA extrae contexto del código', '✅ Validación automática' ]; } else if (complexity.level === 'complex' && teamContext === 'enterprise') { recommendation.action = 'guided-enterprise'; recommendation.explanation = 'Setup enterprise guiado para proyecto complejo.'; recommendation.nextSteps = [ '📋 Configuración por módulos', '👥 Setup multi-usuario', '🔒 Validaciones de calidad enterprise' ]; } else { recommendation.action = 'standard-setup'; recommendation.explanation = 'Setup estándar con opciones personalizadas.'; recommendation.nextSteps = [ '🎯 Configuración guiada paso a paso', '🔧 Personalización según tu stack', '📚 Documentación progresiva' ]; } // Ajustar tiempo basado en preferencias if (comfortLevel === 'expert' && priority === 'fast-setup') { recommendation.estimatedTime = this.reduceTime(recommendation.estimatedTime); } else if (comfortLevel === 'guided') { recommendation.estimatedTime = this.increaseTime(recommendation.estimatedTime); } return recommendation; } async detectProjectType() { // Detección inteligente mejorada const detectors = [ { files: ['package.json'], check: this.analyzePackageJson.bind(this) }, { files: ['composer.json'], type: 'PHP' }, { files: ['requirements.txt', 'pyproject.toml'], check: this.analyzePython.bind(this) }, { files: ['go.mod'], type: 'Go' }, { files: ['Cargo.toml'], type: 'Rust' }, { files: ['pom.xml'], type: 'Java (Maven)' }, { files: ['build.gradle'], type: 'Java (Gradle)' }, { files: ['pubspec.yaml'], type: 'Flutter/Dart' } ]; for (const detector of detectors) { for (const file of detector.files) { const filePath = path.join(this.targetDir, file); if (await fs.pathExists(filePath)) { if (detector.check) { return await detector.check(filePath); } return detector.type; } } } return 'Proyecto genérico'; } async analyzePackageJson(packagePath) { try { const pkg = JSON.parse(await fs.readFile(packagePath, 'utf8')); const deps = { ...pkg.dependencies, ...pkg.devDependencies }; // Detectar framework específico if (deps.next) return 'Next.js'; if (deps.nuxt) return 'Nuxt.js'; if (deps.react || deps['@types/react']) return 'React'; if (deps.vue) return 'Vue.js'; if (deps['@angular/core']) return 'Angular'; if (deps.express) return 'Node.js/Express API'; if (deps.fastify) return 'Node.js/Fastify API'; if (deps['@nestjs/core']) return 'NestJS API'; return 'Node.js/JavaScript'; } catch (error) { return 'Node.js'; } } async analyzePython(reqPath) { try { const content = await fs.readFile(reqPath, 'utf8'); if (content.includes('django')) return 'Python/Django'; if (content.includes('flask')) return 'Python/Flask'; if (content.includes('fastapi')) return 'Python/FastAPI'; if (content.includes('pandas') || content.includes('numpy')) return 'Python/Data Science'; return 'Python'; } catch (error) { return 'Python'; } } reduceTime(timeStr) { // Lógica simple para reducir tiempo estimado if (timeStr.includes('10-20')) return '5-10 min'; if (timeStr.includes('5-10')) return '3-5 min'; if (timeStr.includes('2-5')) return '2-3 min'; return timeStr; } increaseTime(timeStr) { // Lógica simple para aumentar tiempo estimado if (timeStr.includes('2-5')) return '5-8 min'; if (timeStr.includes('5-10')) return '8-15 min'; if (timeStr.includes('10-20')) return '15-25 min'; return timeStr; } showRecommendation(recommendation) { console.log(chalk.green(`\n✨ RECOMENDACIÓN PERSONALIZADA`)); console.log(chalk.gray('═══════════════════════════════════════')); console.log(`🎯 ${chalk.cyan(recommendation.explanation)}`); console.log(`⏱️ Tiempo estimado: ${chalk.yellow(recommendation.estimatedTime)}`); console.log(chalk.cyan('\n📋 Próximos pasos:')); recommendation.nextSteps.forEach(step => { console.log(` ${step}`); }); // Eliminar el "Presiona Enter" duplicado console.log(''); } } module.exports = StreamlinedOnboarding;