# frozen_string_literal: true require 'optparse' require 'json' require_relative '../core/colores' require_relative '../db/core/mejoras_sensor' module ADN class SubcomandoSalud def initialize(args, logger) @args = args @logger = logger @opciones = { dashboard: false, json: false, mejoras: false } end def ejecutar parser = OptionParser.new do |opts| opts.banner = "Uso: ./adn/tools/run salud [OPCIONES]" opts.separator "" opts.separator "Muestra salud general del sistema ADN" opts.separator "" opts.separator "Opciones:" opts.on("--dashboard", "Mostrar en formato dashboard (no implementado)") do @opciones[:dashboard] = true end opts.on("--json", "Salida en formato JSON") do @opciones[:json] = true end opts.on("--mejoras", "Incluir sugerencias de mejora continua") do @opciones[:mejoras] = true end opts.on("-h", "--help", "Mostrar esta ayuda") do puts opts exit 1 end opts.on("-h", "--help", "Mostrar esta ayuda") do puts opts exit end end begin parser.parse!(@args) rescue OptionParser::InvalidOption => e @logger.error("Opción inválida: #{e.message}") puts parser exit 1 end mostrar_salud end private def mostrar_salud @logger.info("Generando reporte de salud del ADN") datos = { timestamp: Time.now.utc.iso8601, hebras_adn: contar_hebras_adn, bitacoras: contar_bitacoras, nodos: contar_nodos, proyectos: contar_proyectos, errores_recientes: buscar_errores_recientes } # Add improvement suggestions if requested if @opciones[:mejoras] datos[:sugerencias_mejora] = obtener_sugerencias_mejora end if @opciones[:json] puts JSON.pretty_generate(datos) return end if @opciones[:dashboard] puts "#{Color::YELLOW}⚠ El dashboard será implementado en Fase 3#{Color::RESET}" # TODO: Implementar dashboard en Fase 3 end # Mostrar en formato legible puts "#{Color::CYAN}🧬 Salud del Sistema ADN#{Color::RESET}" puts "#{Color::DIM}#{'-' * 60}#{Color::RESET}" puts " #{Color::GREEN}Hebras ADN:#{Color::RESET} #{datos[:hebras_adn]} / 7" puts " #{Color::GREEN}Bitácoras:#{Color::RESET} #{datos[:bitacoras]}" puts " #{Color::GREEN}Nodos registrados:#{Color::RESET} #{datos[:nodos]}" puts " #{Color::GREEN}Proyectos activos:#{Color::RESET} #{datos[:proyectos]}" if datos[:errores_recientes] > 0 puts " #{Color::RED}Errores recientes:#{Color::RESET} #{datos[:errores_recientes]}" else puts " #{Color::GREEN}Errores recientes:#{Color::RESET} 0" end puts "#{Color::DIM}#{'-' * 60}#{Color::RESET}" puts "#{Color::DIM}Para más detalles: ./adn/tools/run salud --json#{Color::RESET}" @logger.exito("Reporte de salud generado") end # Obtener sugerencias de mejora continua def obtener_sugerencias_mejora # Activar el sensor temporalmente para obtener sugerencias ::ADN::MejorasSensor.activo = true sugerencias = ::ADN::MejorasSensor.generar_sugerencias ::ADN::MejorasSensor.activo = false # Desactivar nuevamente para no afectar rendimiento sugerencias end def contar_hebras_adn Dir.glob(File.join(ADN::PROJECT_ROOT, 'adn', "*.md")).count end def contar_bitacoras Dir.glob(File.join(ADN::BITACORAS_DIR, "*.md")).count end def contar_nodos Dir.glob(File.join(ADN::NODOS_DIR, "*.md")).count end def contar_proyectos Dir.glob(File.join(ADN::PROYECTOS_DIR, "*.md")).count end def buscar_errores_recientes # Buscar en logs de hoy log_hoy = File.join(ADN::LOGS_DIR, "#{Date.today}.log") return 0 unless File.exist?(log_hoy) errores = 0 File.foreach(log_hoy) do |linea| begin entrada = JSON.parse(linea) errores += 1 if entrada['nivel'] == 'ERROR' rescue JSON::ParserError next end end errores end end end