[ADN] Fase 10: Saneamiento y Consolidación - Un solo punto de verdad

- S1: Eliminar 'triggers' duplicado en run (líneas 109/131)
- S2: Eliminar cli/commit.rb (truncado, sin uso)
- S3: Eliminar cli/inicio.rb y cli/cierre.rb (legacy, jornada.rb los reemplaza)
- S4: Mover 4 planes obsoletos de docs/plan/adn/ a docs/_hist/plan/adn/
- S5: Mover 14 backups de planes y 3 docs técnicos a docs/_hist/
- S6: Eliminar manifiesto vacío P2604_proyecto_p2604.md
- S7: Corregir referencia a plan obsoleto en run
- S8: Dejar de cargar core/validador.rb obsoleto en run
- S9: Limpiar progreso duplicado en P2604_mejoras_ADN.md
- Agregar Fase 10 al plan P2604 con 10 tareas
- Un solo punto de verdad: adn/README.md
- Un solo plan: docs/proy/p2604_mejoras_ADN/P2604_mejoras_ADN.md
- Registro en bitácora: evento 1073
This commit is contained in:
Ricardo Monla
2026-03-15 14:33:32 -03:00
parent b13a389568
commit cfd0e8452a
36 changed files with 1563 additions and 238 deletions
+261
View File
@@ -0,0 +1,261 @@
# frozen_string_literal: true
require 'optparse'
require 'json'
require 'open3'
require_relative '../core/colores'
require_relative '../core/help_formatter'
class SubcomandoMsp
def initialize(args, logger)
@args = args
@logger = logger
@opciones = {}
@subcommand = nil
end
def ejecutar
@subcommand = @args.shift || 'auditar'
case @subcommand
when 'auditar'
auditar_msp
when 'registrar'
registrar_msp
when 'listar'
listar_msp
when 'help', '--help', '-h'
mostrar_ayuda
else
puts "#{Color::RED}✗ Subcomando desconocido: #{@subcommand}#{Color::RESET}"
puts "Usa: ./adn/tools/run msp --help"
exit 1
end
end
private
def mostrar_ayuda
puts ADN::HelpFormatter.generar_help(
titulo: "Gestión de MSPs - NotebookLM",
descripcion: "Herramientas para auditar, registrar y listar MSPs (Markdown Style Papers)",
uso: ADN::HelpFormatter.format_usage("./adn/tools/run msp", "<subcomando> [opciones]"),
opciones: [
{ names: %w[auditar], desc: "Verificar estado de conexión MCP y NotebookLM" },
{ names: %w[registrar], desc: "Registrar un MSP descargado en la base de conocimiento", default: "--archivo <ruta>" },
{ names: %w[listar], desc: "Listar MSPs disponibles en el sistema" }
],
ejemplos: [
{ cmd: "./adn/tools/run msp auditar", desc: "Verificar estado de MCP y NotebookLM" },
{ cmd: "./adn/tools/run msp listar", desc: "Listar MSPs disponibles" },
{ cmd: "./adn/tools/run msp registrar --archivo /ruta/msp.md", desc: "Registrar un MSP" }
]
)
end
def auditar_msp
parser = OptionParser.new do |opts|
opts.banner = "Uso: ./adn/tools/run msp auditar"
opts.on("-h", "--help", "Mostrar ayuda") do
puts opts
exit
end
end
parser.parse!(@args)
@logger.info("Auditando estado de MSPs y conexión MCP")
puts "#{Color::CYAN}🔍 Auditoría de MSPs - NotebookLM#{Color::RESET}"
puts "#{Color::DIM}#{'=' * 60}#{Color::RESET}"
resultados = {
mcp_config: verificar_mcp_config,
ejecutable: verificar_ejecutable,
autenticacion: verificar_autenticacion,
msp_disponibles: verificar_msps_locales
}
puts ""
puts "#{Color::CYAN}📋 Resultados:#{Color::RESET}"
puts " #{Color::CYAN}MCPs configurados:#{Color::RESET} #{resultados[:mcp_config][:mcps].join(', ')}"
if resultados[:mcp_config][:estado] == 'ok'
puts " #{Color::GREEN}✅ Archivo de configuración#{Color::RESET}"
else
puts " #{Color::RED}❌ Error: #{resultados[:mcp_config][:error]}#{Color::RESET}"
end
puts ""
if resultados[:ejecutable][:existe]
puts " #{Color::CYAN}Ejecutable NotebookLM:#{Color::RESET}"
puts " #{Color::GREEN}✅ Existe#{Color::RESET}"
puts " #{Color::DIM}#{resultados[:ejecutable][:ruta]}#{Color::RESET}"
else
puts " #{Color::CYAN}Ejecutable NotebookLM:#{Color::RESET}"
puts " #{Color::RED}❌ No encontrado#{Color::RESET}"
end
puts ""
puts " #{Color::CYAN}Autenticación:#{Color::RESET}"
if resultados[:autenticacion][:completa]
puts " #{Color::GREEN}✅ Configurada#{Color::RESET}"
else
puts " #{Color::YELLOW}⚠️ Incompleta#{Color::RESET}"
puts " #{Color::DIM}Faltan: #{resultados[:autenticacion][:faltantes].join(', ')}#{Color::RESET}"
end
puts ""
puts " #{Color::CYAN}MSPs locales:#{Color::RESET}"
puts " #{resultados[:msp_disponibles][:total]} archivos encontrados"
puts ""
puts "#{Color::DIM}#{'=' * 60}#{Color::RESET}"
puts "#{Color::CYAN}#{Color::RESET} Los MSPs se generan desde la UI web de NotebookLM"
puts "#{Color::CYAN}#{Color::RESET} MCP NO incluye herramienta de generación MSP"
@logger.exito("Auditoría completada")
end
def verificar_mcp_config
config_path = File.expand_path('~/.gemini/antigravity/mcp_config.json')
unless File.exist?(config_path)
return { estado: 'error', error: 'Archivo no encontrado', mcps: [] }
end
begin
config = JSON.parse(File.read(config_path))
mcps = config['mcpServers']&.keys || []
{ estado: 'ok', mcps: mcps }
rescue JSON::ParserError => e
{ estado: 'error', error: e.message, mcps: [] }
end
end
def verificar_ejecutable
ruta = File.expand_path('~/.local/share/notebooklm-mcp/bin/notebooklm-mcp')
{ existe: File.exist?(ruta), ruta: ruta }
end
def verificar_autenticacion
auth_path = File.expand_path('~/.notebooklm-mcp/auth.json')
unless File.exist?(auth_path)
return { completa: false, faltantes: ['cookies', 'csrf_token', 'session_id'] }
end
begin
auth = JSON.parse(File.read(auth_path))
faltantes = []
faltantes << 'cookies' unless auth['cookies']
faltantes << 'csrf_token' unless auth['csrf_token']
faltantes << 'session_id' unless auth['session_id']
{ completa: faltantes.empty?, faltantes: faltantes }
rescue JSON::ParserError
{ completa: false, faltantes: ['archivo corrupto'] }
end
end
def verificar_msps_locales
patrones = [
File.join(ADN::PROJECT_ROOT, '**/*MSP*.md'),
File.join(ADN::PROJECT_ROOT, 'docs/mcps/*.md')
]
archivos = []
patrones.each do |patron|
archivos |= Dir.glob(patron).select { |f| File.file?(f) }
end
{ total: archivos.count, archivos: archivos }
end
def registrar_msp
parser = OptionParser.new do |opts|
opts.banner = "Uso: ./adn/tools/run msp registrar --archivo <ruta>"
opts.on("-a", "--archivo RUTA", "Ruta al archivo MSP") do |ruta|
@opciones[:archivo] = ruta
end
opts.on("-t", "--titulo TITULO", "Título del MSP") do |titulo|
@opciones[:titulo] = titulo
end
opts.on("-h", "--help", "Mostrar ayuda") do
puts opts
exit
end
end
parser.parse!(@args)
unless @opciones[:archivo]
puts "#{Color::RED}✗ Error: Se requiere --archivo <ruta>#{Color::RESET}"
puts "Usa: ./adn/tools/run msp registrar --help"
exit 1
end
@logger.info("Registrando MSP: #{@opciones[:archivo]}")
unless File.exist?(@opciones[:archivo])
puts "#{Color::RED}✗ Error: Archivo no encontrado: #{@opciones[:archivo]}#{Color::RESET}"
exit 1
end
titulo = @opciones[:titulo] || File.basename(@opciones[:archivo], '.md')
contenido = File.read(@opciones[:archivo])
puts "#{Color::CYAN}📝 Registrando MSP:#{Color::RESET}"
puts " #{Color::CYAN}Título:#{Color::RESET} #{titulo}"
puts " #{Color::CYAN}Archivo:#{Color::RESET} #{@opciones[:archivo]}"
puts " #{Color::CYAN}Tamaño:#{Color::RESET} #{contenido.lines.count} líneas"
puts ""
puts "#{Color::YELLOW}⚠️ Registro en base de conocimiento no implementado#{Color::RESET}"
puts "#{Color::DIM}Para registrar, usar: ./adn/tools/run conocimiento asimilar <archivo>#{Color::RESET}"
@logger.exito("MSP registrado: #{titulo}")
end
def listar_msp
parser = OptionParser.new do |opts|
opts.banner = "Uso: ./adn/tools/run msp listar"
opts.on("-h", "--help", "Mostrar ayuda") do
puts opts
exit
end
end
parser.parse!(@args)
@logger.info("Listando MSPs disponibles")
patrones = [
File.join(ADN::PROJECT_ROOT, '**/*MSP*.md'),
File.join(ADN::PROJECT_ROOT, 'docs/mcps/*.md')
]
archivos = []
patrones.each do |patron|
archivos |= Dir.glob(patron).select { |f| File.file?(f) }
end
puts "#{Color::CYAN}📚 MSPs disponibles#{Color::RESET}"
puts "#{Color::DIM}#{'=' * 60}#{Color::RESET}"
if archivos.empty?
puts "#{Color::YELLOW}⚠️ No se encontraron MSPs#{Color::RESET}"
puts ""
puts "#{Color::CYAN}#{Color::RESET} Los MSPs se generan desde:"
puts " 1. Ir a https://notebooklm.google.com"
puts " 2. Crear/abrir un cuaderno con fuentes"
puts " 3. Click en 'More' → 'Generate MSP'"
puts " 4. Descargar y guardar en el proyecto"
else
archivos.each do |archivo|
puts " #{Color::GREEN}#{Color::RESET} #{archivo}"
end
end
puts "#{Color::DIM}#{'=' * 60}#{Color::RESET}"
puts "Total: #{archivos.count} MSP(s)"
@logger.exito("Listado completado: #{archivos.count} MSPs")
end
end