ShellGenius Changelog

CHANGELOG — ShellGenius

2026.06.17.05 - 2026-06-17

Ayuda y cursor del terminal

  • Pestaña Ayuda reordenada: "Ayúdanos a mejorar" primero; nuevo bloque "Los tres paneles de la app" y "Cómo se trabaja" (conectar · pedir a la IA · ejecutar comando directo) tras "Qué puede hacer". Puntos de lista más grandes y en gris.
  • Cursor del terminal: parpadea solo con conexión activa Y foco; sin conexión o sin foco queda hueco/estático. (No se enfoca el terminal al arrancar ni al clicar si no hay conexión.)

2026.06.17.04 - 2026-06-17

Pulido de interfaz

  • Zonas de mensajes homogéneas: la de conexión (izquierda) y una nueva de IA (derecha) reservan 2 líneas por defecto; los mensajes cortos no mueven el layout y los largos (error/traza) crecen sin recortarse.
  • Estado conectado en 2 líneas: fila 1 = servidor + botón Desconectar; fila 2 = SO · shell · Handshake (antes ocupaba 4 líneas).
  • El resultado de "Probar proveedor" se muestra en la franja de IA ("✓ Verificado" / error), no en el chat.
  • Cursor del terminal: parpadea al enfocar el terminal (el CSS apuntaba al renderer canvas; ahora al DOM real, animado con .xterm.focus).
  • Flechas del árbol de Tareas más atenuadas y un poco más grandes.

2026.06.17.01 - 2026-06-17

Arreglo: la caja de IA se bloqueaba al cambiar de conexión

  • Síntoma: al cambiar de una conexión a otra, la caja de entrada del chat de IA no mostraba el cursor y no aceptaba texto.
  • Causa: el diálogo nativo de confirmación (window.confirm) que aparece al cambiar de conexión deja, en Electron, la ventana sin foco de teclado al cerrarse.
  • Arreglo: se sustituyen TODOS los diálogos nativos del renderer (window.confirm, alert, prompt) por diálogos in-app (HTML): confirmInApp / alertInApp / promptInApp. Sin diálogo nativo, la ventana nunca pierde el foco.
  • Refuerzo: tras conectar y tras cerrar un diálogo se restaura el foco de teclado de la ventana (window:focus en el proceso principal) y de la caja.
  • Test de regresión: src/tests/no-native-dialogs.test.js [CHAT-07] — impide que vuelvan a colarse diálogos nativos en el renderer.

2026.05.30.02 - 2026-05-30

Arreglos de usabilidad (evaluación heurística — hallazgos HAL-01…09)

  • El estado de conexión y el modelo activo ya no se truncan ("sin conexión", "Sin modelo activo" se ven completos).
  • El panel "Nueva conexión" abre con altura usable (≥400px) en vez de quedar apretado.
  • Lenguaje: se quita jerga visible ("DPAPI" → "sistema de Windows"; "agente SSH" → "agente de claves del sistema").
  • Prevención: sin un modelo de IA activo, el botón de enviar al chat queda deshabilitado.
  • Errores: un fallo de interfaz no controlado muestra un mensaje humano, no el volcado técnico.
  • La pestaña Ayuda incorpora un buscador.
  • Verificado: borrar conexión/modelo ya pedía confirmación; un único botón "Conectar" visible.
  • Cada arreglo tiene su test de regresión [HAL-xx] (src/tests/e2e-hal.test.js).
  • La versión visible sube a 2026.05.30.02.

2026.05.30.01 - 2026-05-30

Tareas guiadas: requisito de conexión o IA

  • Sin conexión SSH ni un modelo de IA activo, pulsar una tarea guiada ya no copia el prompt al panel de IA; la interfaz avisa de que se conecte o active un modelo.
  • La version visible sube a 2026.05.30.01.

Pruebas

  • Nuevo E2E [TASK-04] que verifica el comportamiento.

2026.05.29.02 - 2026-05-29

Correccion - la ventana no se podia arrastrar

  • La barra de titulo personalizada (titleBarStyle: hidden) no tenia region arrastrable: faltaba -webkit-app-region: drag en .window-titlebar-drag. La ventana no se podia mover entre monitores. No se notaba porque la app arranca siempre maximizada.
  • Anadido -webkit-app-region: drag a la zona de arrastre; los controles (min/max/cerrar) mantienen no-drag.
  • La version visible sube a 2026.05.29.02.

Pruebas

  • renderer-vendor.test.js cubre ahora que la barra de titulo declara region de arrastre.

2026.05.29.01 - 2026-05-29

Seguridad y uso responsable

  • Aniadido aviso de uso bloqueante en el primer arranque: ShellGenius ejecuta comandos reales, la IA asiste pero no decide, y el usuario asume la responsabilidad de entender cada comando antes de ejecutarlo.
  • El consentimiento se guarda en settings.json (disclaimerAcceptedAt) y el aviso no reaparece tras aceptarlo.
  • Anadida seccion "Aviso de uso y riesgos" en la pagina legal publica (legal-licencia.html).
  • La version visible sube a 2026.05.29.01.

Correccion - arranque en dev roto por el split a workspaces

  • El renderer cargaba xterm/marked/dompurify desde ../../node_modules, que tras mover los ficheros a app/ apuntaba a app/node_modules (vacio por el hoisting de npm-workspaces). El arranque cascaba con Terminal is not defined y nunca pintaba la UI.
  • Las librerias del renderer se vendorizan ahora a src/renderer/vendor/ mediante scripts/copy-renderer-vendor.js, ejecutado en prestart/predev/predist. El index.html las carga con ruta estable vendor/..., identica en dev y empaquetado.

Pruebas

  • Anadido disclaimer.test.js: verifica el markup y el copy del aviso, la persistencia del consentimiento y el aviso en la pagina legal.
  • Anadido renderer-vendor.test.js: garantiza que el HTML no vuelve a cargar libs desde ../../node_modules y que todo vendor/ referenciado lo genera el script de copia.
  • npm run app:test: 60/60 pruebas pasando.

2026.05.05 - Normalizacion de nombre

Proyecto

  • Creada copia oficial candidata en C:\Users\juan\appstoyou.io\Win_ShellGenius.
  • Win_ShellGenius_Next queda como respaldo temporal sin borrar.
  • Renombrado interno de paquete a shellgenius.
  • ProductName y AppId normalizados a ShellGenius e io.appstoyou.shellgenius.
  • Configuracion migrada por copia a C:\Users\juan\AppData\Roaming\shellgenius\settings.json.

Verificacion

  • npm test: 55/55 pruebas pasando.
  • npm run dist:win: build correcto.
  • ShellGenius.exe arranca y conserva perfiles migrados.
  • Conexion validada manualmente por Juan.

2026.05.04.05 - 2026-05-04

Entrega - MVP distribuible

  • La version visible sube a 2026.05.04.05.
  • El artefacto Windows pasa a llamarse ShellGenius.exe para que la entrega no exponga nombres internos ni version en el nombre del ejecutable.
  • Aniadidos doc/MANUAL_USUARIO.md y doc/MANUAL_TECNICO.md.
  • Actualizado README_MVP.md para la entrega 2026.05.04.05.

Pruebas

  • Actualizada la prueba de distribucion para fijar el nombre final ShellGenius.exe.

2026.05.04.04 - 2026-05-04

UI/UX - barra superior propia

  • La version visible sube a 2026.05.04.04 antes de probar el cambio.
  • Sustituida la barra nativa blanca de Windows por una barra propia oscura con icono real, nombre, version y controles de minimizar, maximizar/restaurar y cerrar.
  • La ventana mantiene el arranque maximizado en el monitor guardado.
  • La terminal muestra una marca compacta del icono bajo el ASCII art antes de la version y la frase.

Pruebas

  • Actualizadas pruebas de distribucion para fijar barra propia, controles de ventana e icono real.
  • Actualizadas pruebas del banner para fijar la marca bajo el ASCII art.

2026.05.04.03 - 2026-05-04

UI/UX - logo limpio de aplicacion

  • Regenerado el set completo de app_icons con una marca limpia sin caja, borde ni lineas alrededor.
  • El logo mantiene el lenguaje visual de terminal: prompt verde, cursor horizontal verde y estrella azul de inteligencia artificial.
  • La version visible sube a 2026.05.04.03 para validar este cambio.

2026.05.04.02 - 2026-05-04

UI/UX - arranque maximizado por monitor

  • La version visible sube en cada cambio que se vaya a probar: 2026.05.04.02.
  • La ventana guarda el monitor donde se cierra y vuelve a abrir maximizada en ese mismo monitor.
  • Si el monitor guardado no existe o no hay estado previo, la ventana arranca maximizada en el monitor principal.

Pruebas

  • Actualizada la prueba de distribucion para fijar version de build y apertura maximizada por monitor guardado.

2026.05.04.01 - 2026-05-04

UI/UX - icono real y tareas contraidas

  • El icono visible del sidebar usa el icono real de ShellGenius desde app_icons, no el sparkle generico.
  • La ventana Electron usa el .ico real de ShellGenius para mejorar el icono de barra de titulo y aplicacion.
  • El logo del sidebar se simplifica a una marca limpia sin caja ni lineas alrededor.
  • La ventana arranca maximizada siempre.
  • La pestania Tareas arranca contraida: solo muestra los tres bloques padre Tareas de administracion, Tareas de IA local y Tareas de Productividad.
  • El banner compacto de terminal evita partir la version y la frase en terminales estrechas.

Pruebas

  • Aniadida prueba para fijar que el arbol de tareas no abra nodos por defecto.
  • Actualizada prueba de distribucion para exigir icono real en ventana y sidebar.
  • Aniadida prueba para evitar wrapping del banner compacto con version completa.
  • npm test: 55 pruebas pasando.

2026.05.03.07 - 2026-05-03

Entrega - paquete Windows

  • Aniadido icono real de ShellGenius al ejecutable Windows y a la ventana Electron.
  • Generado app_icons/shellgenius.ico multi-resolucion a partir de los iconos creados en app_icons.
  • El build Windows incluye app_icons/**/* y mantiene excluidos .env*, pruebas, documentacion y carpetas locales.
  • Generado portable con npm run dist:win: dist/ShellGenius-2026.05.03.07-portable.exe.
  • Probado arranque fuera del entorno de desarrollo: el portable lanza ShellGenius.exe y abre ShellGenius - v2026.05.03.07.

Pruebas

  • Aniadida prueba de configuracion de distribucion, icono Windows e inclusiones/exclusiones del paquete.
  • Revisado app.asar: no contiene .env, settings.json, src/tests, doc ni carpetas locales.
  • npm test: 53 pruebas pasando.

2026.05.03.06 - 2026-05-03

Fix - banner ASCII de terminal

  • Corregida la detección inicial de ancho del terminal para evitar que el banner caiga al modo compacto cuando xterm.cols aún no está listo.
  • El banner ahora combina las columnas reportadas por xterm con el ancho real del contenedor, manteniendo el ASCII art en ventanas normales.

Pruebas

  • Añadida prueba para cubrir el caso de columnas de xterm bajas con contenedor ancho.
  • npm test: 52 pruebas pasando.

2026.05.03.05 - 2026-05-03

UI/UX - orden de bloques de tareas

  • Corregido el orden visual de la pestaña Tareas para respetar la secuencia pedida: Tareas de administración, Tareas de IA local y Tareas de Productividad.
  • Actualizada la prueba del catálogo para fijar ese orden y evitar regresiones.

Pruebas

  • npm test: 51 pruebas pasando.

2026.05.03.04 - 2026-05-03

UI/UX - tareas de productividad

  • Añadido el bloque Tareas de Productividad dentro de la pestaña Tareas, situado entre Tareas de administración y Tareas de IA local.
  • El bloque cubre preparación de entorno de desarrollo, base técnica SaaS, bases de datos locales, Docker, verificaciones de calidad, dependencias, errores frecuentes y automatización diaria.
  • Aplicaciones web y Docker quedan representados en productividad, no en administración de servidores.
  • Al pulsar una tarea de productividad solo se rellena la caja de chat; instalaciones, actualizaciones, cambios de PATH, bases de datos, Docker y lockfiles exigen revisión y confirmación explícita.

Pruebas

  • Añadidas pruebas para validar el bloque de productividad SaaS y sus prompts seguros antes de cambios de entorno.
  • npm test: 51 pruebas pasando.

2026.05.03.03 - 2026-05-03

UI/UX - feedback por correo

  • Los enlaces Proponnos mejoras e Informar de un error de la pestaña Ayuda abren un correo dirigido a juan.cristobal.mm@googlemail.com.
  • Cada enlace prepara un asunto específico y un texto inicial para facilitar el envío de propuestas o errores.
  • El proceso principal permite abrir enlaces mailto: validados, manteniendo bloqueados esquemas no permitidos.

Pruebas

  • Añadida prueba para permitir solo enlaces externos web o mailto: seguro.
  • Actualizada la prueba de Ayuda para fijar los dos enlaces de correo.
  • npm test: 49 pruebas pasando.

2026.05.03.02 - 2026-05-03

UI/UX - tareas de IA local

  • Añadido el bloque Tareas de IA local dentro de la pestaña Tareas, junto a Tareas de administración.
  • El nuevo bloque cubre preparación de entorno, instalación de motores como Ollama, gestión de modelos, pruebas de rendimiento, integración con desarrollo y mantenimiento.
  • Al pulsar una tarea de IA local solo se rellena la caja de chat; no instala, descarga modelos ni levanta servicios sin revisión y confirmación explícita.

Pruebas

  • Añadidas pruebas para validar el nuevo bloque de IA local, tareas de Ollama/modelos y prompts con comprobaciones previas.
  • npm test: 48 pruebas pasando.

2026.05.03.01 - 2026-05-03

UI/UX - banner ASCII de terminal

  • Anadido banner responsive en la terminal: Shell se pinta en verde terminal y Genius en azul inteligencia artificial.
  • En terminales anchas se muestra el ASCII art completo en una linea visual; en anchos medios se apila para no cortar texto; en anchos estrechos se usa fallback compacto.
  • Anadida la frase de posicionamiento: Entiende antes de ejecutar.

Pruebas

  • Anadida prueba del banner para validar colores ANSI, fallback responsive y ancho visible.
  • npm test: 46 pruebas pasando.

2026.05.02.16 - 2026-05-02

UI/UX - sistema visual base

  • Refinado el sistema visual de ShellGenius: superficies oscuras mas limpias, bordes neutrales, sombras contenidas y estados de color reservados para conexion, error, aviso y accion.
  • La terminal gana protagonismo visual y los paneles laterales reducen ruido cromatico para que el estado real se lea mejor.
  • Pulidos sidebar, arbol de tareas, panel de inteligencia artificial, mensajes, controles, formularios inline y cards de modelos/conexiones.

Pruebas

  • npm test: 43 pruebas pasando.
  • App arrancada en Electron y captura visual revisada tras la pasada CSS.

2026.05.02.15 - 2026-05-02

Fix - migracion de frases de paso SSH legacy

  • Corregida la lectura de perfiles Secure Shell importados desde ShellGenius que tenian passphrase legacy en claro en vez de passphraseEnc.
  • La app migra esas frases de paso a safeStorage al arrancar y conserva la conexion de perfiles que ya funcionaban.
  • Reparado el perfil local Node.js 2 (Lucuhost): la frase legacy se migro a passphraseEnc y ya no queda en claro en settings.json.

Pruebas

  • Anadidas pruebas para lectura de frase de paso legacy y migracion a almacenamiento cifrado.
  • Verificada conexion SSH sin ejecutar comandos remotos: SSH_READY.

2026.05.02.14 - 2026-05-02

Fix - frase de paso en claves PPK

  • Corregido el flujo de perfiles con clave privada: si la frase de paso no está guardada, se pide siempre al conectar, aunque el perfil esté configurado para no guardarla.
  • Normalizados los errores visibles de PPK para usar frase de paso en vez de passphrase.
  • Los errores mostrados en terminal, card de conexión y trazas técnicas pasan por normalización de texto visible.

Pruebas

  • Añadidas pruebas para PPK cifrada sin frase de paso y para evitar reintroducir prompts visibles con passphrase.
  • Añadida prueba para garantizar que el perfil de clave privada pide frase de paso aunque no se guarde.

2026.05.02.13 - 2026-05-02

UI/UX - ayuda desde los temores del usuario

  • Reescrito el bloque Qué puede hacer ShellGenius por ti para priorizar seguridad y control antes que ahorro de tiempo.
  • El texto responde a miedos habituales de desarrolladores con poca práctica de sistemas: tocar producción, ejecutar comandos que no entienden e interpretar salidas largas.
  • Conservado el ahorro cuantificado en diagnósticos: 10-30 min por incidencia.

Pruebas

  • Actualizada la prueba de contenido de Ayuda para fijar el nuevo enfoque: trabajar sin ir a ciegas, entender antes de ejecutar y reducir errores en producción.

2026.05.02.12 - 2026-05-02

UI/UX - ayuda orientada a valor

  • Reordenada la pestaña Ayuda en tres bloques: Qué puede hacer ShellGenius por ti, Ayúdanos a mejorar y Atajos de teclado.
  • Añadida explicación cuantificada de ahorro estimado: 5-15 min en revisiones básicas y 10-30 min en diagnósticos.
  • La ayuda recalca la reducción de riesgo: comandos revisables, explicación de flags y ejecución solo tras confirmación.
  • Añadidos enlaces separados para Proponnos mejoras e Informar de un error.

Pruebas

  • Añadida prueba de orden y contenido de la pestaña Ayuda.

2026.05.02.11 - 2026-05-02

UI/UX - árbol de tareas

  • El árbol de tareas adopta una estructura visual tipo explorador, con nodo padre Tareas de administración.
  • Eliminados Aplicaciones web y Docker del bloque de administración; quedan reservados para un futuro bloque de productividad.
  • Al pulsar una tarea, el prompt se inserta en la caja de chat y la persona usuaria decide cuándo enviarlo.

Pruebas

  • Añadida prueba para asegurar que el click de tarea solo rellena el prompt y no llama a envío automático.

2026.05.02.10 - 2026-05-02

UI/UX - tareas guiadas de servidor

  • Sustituida la pestaña visible Historial por Tareas.
  • Añadido árbol de dos niveles con grupos de administración de servidores y tareas hijas clicables.
  • Al pulsar una tarea se envía un prompt seguro al chat; la app no ejecuta nada directamente y mantiene el flujo normal de propuesta y confirmación.

Pruebas

  • Añadidas pruebas del catálogo de tareas y de prompts con ejecución detrás de confirmación.
  • Ampliada la prueba de copia visible para evitar que vuelva la pestaña Historial.

2026.05.02.09 - 2026-05-02

UI/UX - refinamiento DALIA de microcopy

  • Sustituida jerga visible residual: safeStorage pasa a "cifrado del sistema", "Reportar un bug" a "Informar de un error" y "Ver changelog" a "Ver cambios".
  • Normalizado el botón de explicación de comando a "Explicar".
  • Cambiada la etiqueta de comando peligroso a "Riesgo alto" para describir el estado de forma más precisa.

Pruebas

  • Ampliada la prueba de copia visible para evitar reintroducir esos textos mixtos.
  • npm test: 33 pruebas pasando.

2026.05.02.08 - 2026-05-02

UI/UX - normalizacion DALIA de textos

  • Sustituido texto visible mixto por terminologia en espanol: IA, clave de API, frase de paso, agente SSH, proveedor en la nube y proveedor local.
  • Cambiado el placeholder del chat a "Pregunta o pide un comando...".
  • Ajustados mensajes de error de proveedor y clave privada para usar "clave de API" y "frase de paso".

Pruebas

  • Anadida prueba de copia visible para evitar reintroducir Continue..., AI, API key, Passphrase o SSH agent.
  • npm test: 33 pruebas pasando.

2026.05.02.07 - 2026-05-02

Seguridad - secretos fuera del renderer

  • ai:get-profiles devuelve perfiles saneados: conserva hasApiKey y keyStatus, pero ya no envia apiKey ni apiKeyEnc a la interfaz.
  • La carga de modelos de perfiles guardados usa ai:list-profile-models; la clave se descifra y usa solo en el proceso principal.
  • ssh:profiles-get devuelve perfiles saneados: conserva hasPassword y hasPassphrase, pero no envia password, passwordEnc, passphrase ni passphraseEnc.
  • Anadido ssh:connect-profile para conectar perfiles guardados con credenciales descifradas en el proceso principal.
  • La passphrase SSH se persiste cifrada cuando la persona usuaria elige guardarla.
  • La contrasena heredada de settings ya no se devuelve ni se persiste desde el formulario antiguo.
  • DevTools solo se abre automaticamente en modo desarrollo o con openDevTools.

Pruebas

  • Anadidas pruebas de saneado de perfiles IA y SSH.
  • npm test: 32 pruebas pasando.

2026.05.02.06 — 2026-05-02

Fix — Escape y cursor de terminal

  • La terminal intercepta Escape con attachCustomKeyEventHandler, antes de que xterm consuma la tecla.
  • La terminal recibe foco al abrirse y al hacer click sobre ella.
  • El cursor de xterm tiene parpadeo CSS forzado para que sea visible aunque el parpadeo nativo no se aprecie.

Pruebas

  • npm test: 30 pruebas pasando.

2026.05.02.05 — 2026-05-02

Fix — Cancelación desde interfaz

  • Escape ahora se captura a nivel de documento durante comandos asistidos, aunque el foco no esté en el textarea del chat.
  • Si el foco está en la terminal, la pulsación Escape recibida por xterm también solicita cancelAssisted().
  • La cancelación mantiene bloqueada la entrada hasta que el backend devuelve el resultado cancelado y luego vuelve a estado listo.

Terminal

  • Verificado cursor parpadeante en xterm mediante cursorBlink: true y estilo de barra.

Pruebas

  • npm test: 30 pruebas pasando.

2026.05.02.04 — 2026-05-02

Nuevo — Cancelación de comandos asistidos

  • CommandQueue puede cancelar el comando asistido activo con AbortController.
  • SSHManager.execute() acepta una señal de cancelación y cierra el stream exec activo.
  • Nuevo IPC ssh:cancel-assisted, expuesto al renderer como cancelAssisted().
  • La interfaz permite solicitar cancelación con Escape mientras hay ejecución asistida y muestra el estado en terminal/chat.

Pruebas

  • Añadidas pruebas de cancelación activa en CommandQueue.
  • Añadida prueba de cierre del stream exec al abortar SSHManager.execute().
  • npm test: 30 pruebas pasando.

2026.05.02.03 — 2026-05-02

Cambiado — Estado real de proveedores de inteligencia artificial

  • Los perfiles de modelos usan estado explícito de clave (hasApiKey, keyStatus) calculado en el proceso principal.
  • La galería de modelos ya no depende solo de apiKey plano para decidir si falta clave.
  • Añadida acción de probar proveedor en cada card de modelo.
  • Los errores transitorios o de cuenta (402, 429, 5xx) se guardan como warning del perfil, por ejemplo "Cuota alcanzada" para OpenAI con HTTP 429.

Pruebas

  • Añadidas pruebas de clasificación de warnings de proveedor y detección de clave utilizable sin exponer la clave.
  • npm test: 28 pruebas pasando.

2026.05.02.02 — 2026-05-02

Nuevo — Cola real de comandos asistidos

  • Añadido src/main/command-queue.js para serializar comandos asistidos en el proceso principal.
  • Nuevo IPC ssh:execute-assisted, separado de la shell interactiva.
  • El resultado asistido incluye comando, salida estándar, error estándar, código de salida, hora de inicio, hora de fin, estado final, completitud y señal interna de finalización.
  • La interfaz ejecuta comandos asistidos por la cola, refleja la salida en la terminal y envía a la inteligencia artificial un resultado estructurado.

Pruebas

  • Añadidas pruebas de cola para éxito, código de salida distinto de cero, serialización y conexión ausente.
  • npm test: 25 pruebas pasando.

2026.05.02.01 — 2026-05-02

Nuevo — Base de pruebas y modelo de estados

  • npm test deja de depender de Jest y usa el runner nativo de Node: node --test src/tests/*.test.js.
  • Nuevo módulo puro src/core/runtime-state.js con estados explícitos para conexión remota, proveedor de inteligencia artificial, ejecución de comandos y bloqueo de entrada manual.
  • Añadidas pruebas unitarias del modelo de estados.
  • Reescritas las pruebas de AIAssistant para la implementación actual basada en fetch y perfiles.
  • Reescritas las pruebas de SSHManager para inyectar un cliente SSH falso sin depender de ssh2 durante unit tests.

Cambiado

  • SSHManager expone getStatus() con estado de conexión observable.
  • AIAssistant expone getStatus() sin devolver API keys al renderer.
  • El proceso principal expone app:get-runtime-state para consultar estado de conexión y proveedor.
  • La terminal bloquea entrada manual mientras un comando asistido está marcado como ejecutándose o capturando salida.

Verificado

  • npm test: 21 pruebas pasando.

Pendiente

  • npm install se quedó bloqueado en este entorno y fue detenido manualmente. El árbol node_modules local sigue requiriendo limpieza fuera de esta ejecución.

2026.04.28.29 — 2026-04-28

Cambiado — Formulario de Nueva/Editar conexión

  • Swatches de color en línea con el label, tamaño 14px con gap 12px aplicado vía JS.
  • Placeholder Alias: "Descripción de tu conexión".
  • Host/IP + Puerto en una fila (3:1). Usuario en fila propia debajo.
  • Nota safeStorage reducida a una línea: "Cifrado con safeStorage (DPAPI). Nunca en texto plano."
  • 4 botones con iconos: Cancelar / Probar / Guardar (solo guarda) / Conectar (guarda y conecta).
  • Botones con flex-wrap para que no se monten cuando el panel es estrecho.
  • Cancelar desde "Mis conexiones" vuelve al panel de lista. Guardar sin conectar también.

Fix — Rojo de error consistente entre terminal y UI

  • xterm red: #ff7b72 alineado a --danger: #f85149.

Fix — Mensaje de conexión en chat IA

  • Al conectar muestra el trace en el chat. Errores SSH solo van al card y terminal.

Fix — Botón Modelos mismo alto que Conexiones

  • Quitado align-items: center de .ai-header-buttons. Padding del sidebar-card-header igualado al del panel IA.

Fix — Cancelar en formulario vuelve a Mis conexiones

  • openConnAddPanel recibe returnToList=true cuando se abre desde la lista. Cancelar y Guardar sin conectar restauran el panel de lista.

2026.04.28.13 — 2026-04-28

Cambiado — Iconos de acción en cards de conexión simétricos a los de modelos IA

  • Los botones "Probar / Editar / Borrar" en los cards del panel "Mis conexiones" eran texto plano. Ahora usan los mismos iconos SVG que los cards del panel "Mis modelos" (lápiz para editar, papelera para borrar) reutilizando makeCardActionBtn().
  • Añadido icono test (señal wifi) para el botón Probar; estados visuales is-busy / is-ok / is-fail durante el TCP probe sin perder el icono.
  • Click en el card sigue activando el perfil; click en cualquier action button es independiente.

2026.04.28.12 — 2026-04-28

Cambiado — Header del card de Conexiones simétrico al panel IA

  • Añadido icono de enchufe vertical (SVG) al inicio del header del card, paralelo al sparkle violeta del panel IA. Color azul #58a6ff para que case con los acentos del card.
  • El label de servidor activo (.conn-active-label) ahora usa la misma tipografía que .ai-active-model del panel IA: font-size: 0.9rem, font-weight: 700, color blanco cuando hay conexión activa. Antes era 0.78rem y 600.

2026.04.28.11 — 2026-04-28

Fix — Rojo de error consistente entre terminal y UI

  • xterm tenía red: '#ff7b72' (más rosado/coral) hardcodeado en el theme, mientras el resto de la app usa --danger: #f85149 (más vivo). Resultado: el Error: … de la terminal se veía distinto al título de error del card de Conexiones. Alineado a #f85149.

2026.04.28.10 — 2026-04-28

Cambiado — Card de Conexiones aporta valor humano (no es eco de la terminal)

Estado de error

  • En lugar de volcar el trace técnico (que ya está en la terminal), el card muestra:
    • Diagnóstico claro: traduce errores conocidos a lenguaje humano (timeout, ECONNREFUSED, ENOTFOUND, ECONNRESET, auth fallida, clave no parseable, passphrase incorrecta, keyboard-interactive…). Mapeo en diagnoseConnError().
    • Acciones: botón "Reintentar" (repite el último connect) y "Editar perfil" (abre el form con los datos del perfil activo).
    • Detalles técnicos colapsables con <details> para los devs que quieran ver el trace.

Estado conectado

  • En lugar de "Conectado a {host}", el card muestra:
    • usuario@hostname · cwd
    • OS (uname) · shell · …
    • Tiempo de handshake (ms) — calculado del trace SSH (getHandshakeMs).
    • Botón "Desconectar".
  • fetchServerContext() ahora también captura hostname y normaliza el shell (bash en vez de /bin/bash); al volver, re-renderiza el card con los datos.

2026.04.28.09 — 2026-04-28

Fix — El chat de la IA ya no recibe los traces SSH

  • connect() dejaba caer el trace de conexión y los errores como mensajes del chat de la IA. Era duplicación con el card de Conexiones (que ya muestra el mismo trace) y ensuciaba la conversación. Eliminadas las dos addChatMessage de connect(). El estado SSH sigue llegando a la IA por el system prompt dinámico cuando lo necesita.

2026.04.28.08 — 2026-04-28

Cambiado — Card de Conexiones reorganizado

  • Header del card unificado: dot de estado + alias activo (o "sin conexión") + botón "Conexiones" + botón "+". Eliminada la duplicación "🔌 Conexiones / Sin conexión / Conexiones / +" que repetía la palabra tres veces.
  • Body del card es ahora una única zona de mensajes (#conn-message-zone) que muestra uno de tres estados:
    • Idle: instrucción "Sin conexión activa. Pulsa + para crear una o Conexiones para elegir una guardada".
    • Conectando: "Conectando a usuario@host:port…" (label del header con dot ámbar pulsante).
    • Conectado: "Conectado a usuario@host:port" en verde.
    • Trace: log de eventos SSH (start/banner/handshake/error) con timestamps relativos + Error si lo hubo. Sustituye al banner rojo "⚠ Sin conexión SSH".
  • El trace queda visible en el card hasta el siguiente intento o conexión exitosa.

2026.04.28.07 — 2026-04-28

Fix — Comportamiento real del splitter del sidebar

  • Sin paneles abiertos: el wrapper de Conexiones queda en su altura natural (solo el card) y Historial/Ayuda absorbe todo el espacio disponible. Sin huecos vacíos.
  • Al abrir un panel desplegable: aparece debajo del card con su altura guardada (default 280 px) empujando Historial/Ayuda hacia abajo.
  • El splitter (#sidebar-splitter) ahora redimensiona el panel abierto (no el wrapper completo). Es la frontera viva entre el panel y Historial/Ayuda. Sin panel abierto el splitter es no-op.
  • La altura ajustada se persiste en settings.json:inlinePanelHeight y se reaplica al abrir el panel en sesiones siguientes.

2026.04.28.06 — 2026-04-28

Fix — Panel "Mis conexiones" se quedaba pegado al splitter (segunda iteración)

  • Reescritura: card "Conexiones" + paneles desplegables ahora viven dentro de un wrapper #connections-area. El splitter del sidebar controla la altura del wrapper completo, así el panel queda pegado al card superior (no flotando junto al splitter) y al arrastrar el splitter hacia abajo el panel "Mis conexiones" gana espacio (sus cards de servidores se ven mejor).
  • El intento de la .05 (meter los paneles dentro del card-body) provocaba scroll interno en vez de empujar Historial/Ayuda — corregido.

2026.04.28.05 — 2026-04-28

Fix — Splitter del sidebar no englobaba los paneles inline

  • Los paneles inline (#conn-add-panel y #conn-list-panel) eran hermanos del #connections-card en el <aside>. Al arrastrar el splitter solo el card se redimensionaba — los paneles flotaban entre el card y el splitter en vez de pertenecer al área superior. Movidos dentro del sidebar-card-body para que el splitter englobe todo.
  • Ajuste CSS: cuando el panel inline vive dentro del card-body, sin max-height: 50% artificial; el scroll lo gestiona el propio body que ya tiene overflow-y:auto. Añadido borde y margin-top para separación visual.

2026.04.28.04 — 2026-04-28

Fix — ssh2 rechazaba el PEM PKCS#8 generado por el converter PPK

  • El converter exportaba -----BEGIN PRIVATE KEY----- (PKCS#8) y ssh2 decía Cannot parse privateKey: Unsupported key format. Cambiado a -----BEGIN RSA PRIVATE KEY----- (PKCS#1) que sí acepta. Verificado contra ssh2.utils.parseKey() con la PPK real del usuario.

2026.04.28.03 — 2026-04-28

Fix — PPK con espacios accidentales en la passphrase

  • main.js aplica trim() a la passphrase antes de pasarla al converter PPK. Causa raíz del bug visto en el VPS Node.js 2: la passphrase guardada en settings.json tenía un espacio al final, lo que hacía que Argon2 derivara una clave AES distinta y la decripción produjera bytes basura. Verificado end-to-end con la PPK real del usuario.
  • ppk-converter.js ahora detecta decripción fallida (primer mpint con longitud disparatada) y lanza Passphrase incorrecta para la clave PPK en lugar de un críptico offset out of range.

2026.04.28.02 — 2026-04-28

Nuevo — PPK v3 cifradas (Argon2)

  • Añadido descifrado de claves PPK v3 protegidas con passphrase (KDF Argon2id / Argon2i / Argon2d) usando @noble/hashes (pure JS, sin builds nativos).
  • Cubre todas las claves generadas por PuTTY/PuTTYgen 0.75+ por defecto.
  • Nueva dependencia: @noble/hashes ^2.2.0.

2026.04.28.01 — 2026-04-28

Nuevo — Soporte nativo de claves PPK (PuTTY)

  • El selector de clave privada ya acepta ficheros .ppk y los convierte a OpenSSH en memoria antes de pasárselos a ssh2. El fichero original no se modifica.
  • Soporta PPK v2 y v3 sin passphrase (RSA y Ed25519).
  • PPK v2 con passphrase: descifrado AES-256-CBC con KDF SHA1 de PuTTY.
  • PPK v3 cifrada: rechazada con instrucción de convertir con PuTTYgen (resuelto en .02).
  • Nuevo módulo src/main/ppk-converter.js — sin dependencias externas, solo crypto de Node.

Fix — Arranque desde Claude Code

  • Añadido unset ELECTRON_RUN_AS_NODE al flujo de arranque de desarrollo. Claude Code inyecta esta variable que hacía que Electron arrancara como Node puro, rompiendo require('electron').

2026.04.23.02 — 2026-04-23

Nuevo — Sidebar reorganizado en 4 áreas

  • Header fijo con icono sparkle violeta #9333ea + "ShellGenius" bold + versión en pequeño. Altura 50 px alineada con el header del panel IA
  • Card de Conexiones (arriba) con botones Conexiones (lista) y + (nueva) en el header, siguiendo el mismo patrón que el panel de Modelos
  • Splitter vertical redimensionable entre Conexiones y la zona de tabs. Altura del card superior persistida en settings.json (connectionsCardHeight)
  • Tabs Historial / Ayuda (abajo) — el Historial ya existente + nueva pestaña Ayuda con:
    • Atajos de teclado (Ctrl+Enter, Ctrl+Shift+Enter, Ctrl+Shift+E, Esc)
    • Capacidades de la IA
    • Enlaces externos (Reportar bug, Ver changelog) que abren en el navegador del sistema vía shell.openExternal

Nuevo — Gestión multi-conexión SSH

  • Los perfiles SSH son ahora cards con color identificador, igual patrón visual que los modelos IA
  • + Nueva conexión (panel inline): alias, 8 swatches de color (verde, azul, violeta, ámbar, rojo, teal, rosa, gris), host, puerto, usuario, sección de autenticación
  • Conexiones (panel inline): grid de cards con dot del color + alias + user@host:port + botones Probar/Editar/Borrar. Click en card = activa (con confirm si hay otra conectada)
  • Indicador de conexión activa en el header del card con dot del color del perfil
  • Los paneles inline empujan Historial/Ayuda hacia abajo al abrirse; al cerrar vuelven a su posición (flex-shrink)

Nuevo — Autenticación SSH completa

  • 3 métodos soportados vía selector de radio:
    • Contraseña: como antes, opción de guardar cifrada con safeStorage
    • Clave privada: selector nativo de archivo (dialog.showOpenDialog filtrado por .pem .key .ppk id_rsa id_ed25519 id_ecdsa) + passphrase opcional. Se guarda solo la ruta — la clave nunca sale del archivo
    • SSH agent: usa Pageant en Windows (agent: 'pageant') — útil si ya tienes la clave cargada
  • Passphrase encriptada con safeStorage si marcas guardar
  • Prompts interactivos cuando el perfil no tiene password/passphrase guardada
  • Nuevo handler IPC ssh:profile-test: TCP probe a host:port (no autentica, solo verifica que el puerto responde)

Cambiado

  • SSHManager.buildConnConfig soporta agent además de password y privateKey
  • connect() acepta override de config — el form legacy queda solo como compatibilidad
  • Los atajos Esc y [data-close] cierran también los nuevos paneles inline de conexiones
  • El indicador clickable del estado SSH ahora abre el panel de añadir conexión en vez de hacer scroll al form

Persistencia

  • Nuevos campos en settings.json:
    • sshProfiles: array de {id, alias, color, host, port, user, authMethod, passwordEnc?, privateKeyPath?, passphraseEnc?}
    • activeSshProfileId: perfil en uso
    • connectionsCardHeight: altura del card de conexiones

2026.04.23.01 — 2026-04-23

Nuevo — Proveedores IA

  • Google Gemini añadido como proveedor (prefijo AIza, endpoint OpenAI-compat /v1beta/openai). Filtra variantes no-chat (live, tts, embedding)
  • Ollama y LM Studio añadidos como proveedores locales (sin API key). Auto-detección por probe a /api/tags o /v1/models
  • Entrada única para añadir modelo con dos secciones: Servicio pagado (API key) o Gratis (en tus máquinas) (URL). Botones preset para Ollama y LM Studio. Aviso explícito de que "no es el VPS que administras por SSH"

Nuevo — Control de estado

  • Pre-check de modelo al enviar chat: si no hay perfil activo o falta API key, muestra burbuja de error con botón "Cambiar modelo", sin borrar el input para poder retocar
  • Indicador de modelo vacío en header: pulso rojo + clickable → abre panel de añadir modelo
  • Pre-check de SSH en Ejecutar: si no hay conexión SSH, burbuja "🔌 Sin conexión SSH" antes de mandar comando al vacío
  • Indicador SSH en sidebar: rojo pulsante cuando desconectado, verde con host cuando conectado. Clickable → enfoca el input del host
  • System prompt dinámico con estado SSH: la IA sabe si hay servidor activo y adapta sus respuestas (advierte en la explicación si no hay SSH)

Nuevo — UX del chat

  • Cancelar durante "pensando...": click sobre el spinner cancela la petición (UI local — el HTTP sigue pero el resultado se descarta). Hover muestra ✕ con delay de 400 ms para evitar cancelaciones accidentales
  • Menú contextual (botón derecho) en todo el panel — copiar, cortar, pegar, seleccionar todo. Context-aware (editable vs solo lectura)
  • URLs en ámbar #f2cc60 con subrayado punteado. Destacan frente al texto gris perla
  • Errores con contexto local: si falla conexión con Ollama/LM Studio, el mensaje dice "¿Está corriendo en {url}?" en vez del genérico de red

Cambiado — Gestión de modelos

  • Labels renombrados para desambiguar "local": "En la nube" → "Servicio pagado", "En local" → "Gratis (en tus máquinas)"
  • Dropdown por card con botón Guardar: el cambio de modelo solo se persiste al pulsar ✓ explícito
  • Iconos edit/borrar siempre visibles en esquina inferior derecha de cada card
  • Texto de proveedor sin mayúsculas forzadas en las cards
  • Sparkle del header IA: emoji reemplazado por SVG violeta #9333ea para que sea recolorable

Refinamientos

  • Label "Comando:" en azul #58a6ff, +2 px, sin mayúsculas
  • Respuestas IA con color suavizado #c9d1d9 y bolds blanco puro #ffffff
  • Iconos Gemini (rombo 4 puntas oficial de Simple Icons), Anthropic (triángulo "A" oficial)
  • Tamaño/color del modelo activo en header (blanco, bold, +2 px)
  • Botón "Modelos" con texto y borde azul en vez del icono de 3 rayas
  • Teclas de atajo bajo cada botón del panel de confirmación usan el estilo <kbd> de la línea de ayuda
  • Ejecutar: click simple + confirm() extra si el comando está marcado como dangerous

Fixes

  • Bug crítico de perfiles locales: ai:add-profile hardcodeaba requiresKey: true ignorando lo que enviaba el renderer. Los perfiles Ollama/LM Studio aparecían como "Falta API key" y fallaban al chatear. Respeta ahora el flag del renderer
  • Migración automática: al arrancar, cualquier perfil Ollama/LM Studio guardado con requiresKey: true corrupto se corrige a false
  • Gemini model IDs: stripping del prefijo models/ (el endpoint OpenAI-compat lo rechaza)
  • Textarea disabled si no conectado por SSH era un error de diseño. Ahora siempre activo — la IA permite chat conceptual sin servidor
  • Panel inline empujaba chat fuera de vista: flex-shrink: 1 + min-height: 0 en chat-messages. Al cerrar panel, foco automático al textarea
  • Test con error transitorio (402/429/5xx) ahora permite guardar el perfil y marca la card con warning ámbar — antes bloqueaba el save aunque la config fuera válida

Seguridad

  • API keys encriptadas con safeStorage (DPAPI en Windows). Migración automática de apiKey plano existente a apiKeyEnc. El settings.json ya no contiene keys en claro

Persistencia

  • Posición y tamaño de la ventana guardados (con validación multi-monitor)
  • Posición de DevTools guardada cuando se usa en modo detach

2026.04.22.17 — 2026-04-22

Nuevo — Panel IA

  • Identidad completa en system prompt: ShellGenius se presenta con nombre, modelo dinámico (leído del perfil activo), año 2026 y autoría de appstoyou.io. Tono cercano, didáctico, tuteo
  • Dos modos estrictos en SYSTEM_INTERPRET y SYSTEM_OUTPUT: cualquier comando ejecutable → JSON → panel de confirmación. Prohibido presentar comandos como bloques ```bash en modo conversación
  • SYSTEM_OUTPUT ahora también puede devolver JSON para proponer un follow-up command cuando el output quedó corto o hace falta verificar algo
  • Burbujas "Pensando..." / "Analizando el resultado..." con 3 puntos animados (CSS keyframes, cascada) durante las llamadas a la IA. Aparece al instante al pulsar Ejecutar
  • Tiempo de respuesta ⏱ tras cada mensaje de la IA (icono reloj SVG + segundos, color azul)

Nuevo — Panel de confirmación

  • Botón Explícame (reemplaza a Dry Run): desglosa el comando paso a paso usando SYSTEM_EXPLAIN — qué hace, cada flag, riesgos, alternativas. No ejecuta nada
  • Atajos por botón debajo de cada uno: Ctrl+Shift+Enter ejecutar · Ctrl+Shift+E explicar · Esc cancelar
  • Click = foco, doble-click = acción en los 3 botones (evita ejecuciones accidentales por clic errante)
  • Confirmación extra (window.confirm) al usar el atajo si el comando está marcado como dangerous
  • Tooltips descriptivos con delay de 300 ms al hover sobre cada botón
  • Label "Comando:" ahora en azul #58a6ff, sin mayúsculas, tamaño +2 px

Nuevo — Caja de entrada y UX

  • Botón de enviar embebido en la esquina inferior derecha del textarea (estilo ChatGPT), SVG con stroke grueso
  • Grip de redimensión custom en la parte superior del textarea (barra azul clara, siempre visible, arrastrable entre 40–400 px)
  • Spinner en el botón de enviar mientras procesa
  • Iconos de acciones (copiar, 👍, 👎) bajo cada respuesta como SVG outline en azul con hover intensificado y tooltips personalizados
  • Cards con focus intensity: bordes sutiles (40% opacidad) que se saturan con :focus-within. Verde para sidebar/terminal, azul para panel IA. El panel IA además muestra un glow al enfocarse

Nuevo — Persistencia

  • Window state guardado automáticamente (posición, tamaño, monitor, maximizado) en settings.json con debounce de 400 ms. Al reabrir valida que los x,y caen en algún monitor actual; si el monitor se desconectó, conserva solo el tamaño

Cambiado — Output hacia la IA

  • formatOutputForAi(): ANSI strip + head (30%) + marcador de truncado + tail (70%), cap 12 000 chars. Antes solo se enviaban los últimos 2 000–3 000 chars del raw con códigos de color, lo que desperdiciaba tokens
  • Eliminado el segundo slice(-3000) en ai-assistant.js para evitar doble truncado

Refinamientos tipográficos

  • Respuestas IA: color suavizado a #c9d1d9, line-height 1.45, white-space: normal (antes pre-wrap creaba espacios grandes entre elementos)
  • Negritas en respuestas IA: blanco puro #ffffff para contraste con el body
  • Teclas de atajo con el mismo estilo <kbd> que la línea de ayuda
  • Botón Ejecutar: verde #3fb950 idéntico al borde del terminal en foco, texto blanco, sin brightness(1.1) en hover
  • Interlineado compacto entre li y p en mensajes

Limpieza

  • Carpetas ShellGenIA/ y shellgenia_web/ eliminadas (planificación abandonada / scaffold Next.js vacío)
  • Método dryRunCommand y botón "Dry Run" eliminados

2026.04.22.16 — 2026-04-22

Cambiado

  • Rebrand del proyecto: WARP_BIS / Unix AI TerminalShellGenius
    • package.json: name, productName, appId (io.appstoyou.warpbisio.appstoyou.shellgenius)
    • Título de ventana (main.js), <title> del HTML, banner del terminal, document.title del renderer
    • Header X-Title y HTTP-Referer enviados a OpenRouter
    • CLAUDE.md, .cursorrules, README, spec, pendientes, scripts/build-exe.js
  • Los settings del portable antiguo (%APPDATA%\WARP_BIS\settings.json) no se migran al nuevo appId; los perfiles IA y datos de conexión tendrán que reintroducirse la primera vez
  • Pendiente (manual por el usuario): renombrar la carpeta del proyecto de WARP_BIS a ShellGenius

2026.04.22.15 — 2026-04-22

Nuevo

  • Paneles como cards: los 3 paneles (sidebar, terminal, IA) ahora tienen border-radius: 8px, borde completo y 6px de gap entre ellos sobre fondo negro. Look más desktop-app moderno
  • Splitters draggables entre paneles: dos resizers de 4px (gris transparente → azul al hover) para redimensionar sidebar y panel IA. Anchos persistidos en settings.json (sidebarWidth, aiPanelWidth). Durante el drag el xterm se re-ajusta (fitAddon.fit())
  • Scrollbars minimales (::-webkit-scrollbar 6px, thumb gris translúcido con hover)
  • Barra de menú de Electron oculta (Menu.setApplicationMenu(null) en main.js) — ya no aparece File/Edit/View/Window/Help
  • Editor de API key colapsable: cuando hay key guardada, el input + botón Guardar están ocultos. Botón 🔑 en el header del panel IA toggle la edición; se auto-activa (naranja/acento) si falta la key del perfil activo
  • Nombres cortos en el dropdown de modelo (OpenRouter, OpenAI, Ollama, LM Studio — el title del option mantiene el nombre largo con modelo)

Cambiado

  • #app: gap: 6px y padding: 6px sobre fondo negro para dar la sensación de cards separadas
  • #sidebar, #terminal-area, #ai-panel: borde completo + radius-lg en vez de borders laterales
  • #ai-panel-header: layout del header compactado (brand ✨ AI pequeño, dropdown, botón 🔑)

2026.04.22.14 — 2026-04-22

Nuevo

  • Rediseño "Wave AI" del panel de chat:
    • Mensajes de IA a full-width sin bubble, separados por border-bottom subtle entre turnos
    • Mensajes de usuario como bubble sutil (fondo azul al 10%, borde al 22%) alineados a la derecha, colores legibles (ya no azul chillón)
    • Code blocks con header: etiqueta del lenguaje (bash, js, python, etc. detectada de la classlist de marked) + botón Copiar que copia al portapapeles con feedback ✓ Copiado durante 1.5s
    • Row de acciones bajo cada respuesta IA (visible al hover): 👍 Like, 👎 No me sirve (placeholders visuales), 📋 Copiar respuesta (funcional, texto plano)
    • Botón submit del chat circular 34×34px con icono flecha centrada
    • Placeholder del textarea: Continue...
    • Fondo del panel IA más oscuro (--bg-chat: #0b0f14) para look terminal
    • Tokens nuevos: --bg-chat, --bg-code, --border-subtle
  • Build portable de Windows vía electron-builder:
    • Config build en package.json target portable x64, output dist/
    • Scripts npm run dist / npm run dist:win
    • Exclusión de src/tui/, src/tests/, .env* del empaquetado
    • Artifact: dist/WARP_BIS-2026.04.22.14-portable.exe (~150 MB, auto-contenido, no requiere instalación)

Cambiado

  • renderer.js: addChatMessage llama a postProcessCodeBlocks(msg) tras innerHTML = renderMarkdown(text) y añade buildMsgActions(text) para rol ai. Nuevas funciones módulo-nivel: postProcessCodeBlocks, buildMsgActions, makeActionBtn
  • main.css: rediseño completo de .chat-msg* (sin bubble para ai), nuevas clases .code-block* y .msg-actions*, submit circular

2026.04.22.13 — 2026-04-22

Corregido

  • Chat respondía "No pude interpretar la petición" ante preguntas generales: el system prompt obligaba a JSON solo, el modelo contestaba en lenguaje natural a preguntas tipo "cómo obtener X", JSON.parse fallaba, y el fallback infoNeeded se priorizaba sobre el explanation, descartando la respuesta real del modelo
  • ai-assistant.js: system prompt ahora es dual-modo — JSON solo cuando el usuario pide ejecutar un comando, markdown libre para conversación/preguntas. El modo conversación es el default ante dudas
  • tryExtractJson() tolera code fences ```json...```, JSON embebido entre prosa, y primer objeto {...} balanceado; si nada parsea, el texto crudo se devuelve como isChat: true con explanation: text
  • renderer.js: eliminada la rama needsInfo que cortocircuitaba el mensaje; ahora si no hay command, se muestra explanation directamente (renderizado como markdown en la burbuja de IA)

2026.04.22.12 — 2026-04-22

Nuevo

  • Markdown en respuestas de IA: las burbujas de rol ai y system renderizan markdown (negrita, cursiva, listas, headers, blockquotes, enlaces, bloques de código) con marked + DOMPurify para sanitización XSS
  • Estilos CSS propios para elementos markdown en .chat-msg (code, pre, listas, blockquotes)
  • Ctrl+Enter envía la petición al chat (antes: Enter plano); Enter plano ahora inserta salto de línea porque el input pasa a <textarea> con rows=2, redimensionable verticalmente
  • Leyenda bajo el input del chat: Ctrl+Enter para enviar · Enter inserta un salto de línea con <kbd> estilizados
  • Persistencia de contraseña SSH cifrada con safeStorage de Electron (DPAPI en Windows, Keychain en macOS, Secret Service en Linux): se guarda como base64 en settings.json bajo passwordEnc y se descifra al cargar. Si el sistema no soporta cifrado, no se guarda (nunca en texto plano)

Cambiado

  • index.html: <input> del chat → <textarea>; añadidos scripts de marked.min.js y purify.min.js
  • renderer.js: nuevo helper renderMarkdown(); addChatMessage usa markdown para ai/system, textContent para user/error (inputs crudos); initPersistListeners y loadConnectionData ahora incluyen password
  • main.js: settings:get descifra passwordEnc; settings:set cifra password antes de persistir; importa safeStorage de Electron
  • main.css: textarea redimensionable, estilos markdown, .chat-hint con <kbd>

Dependencias

  • marked@^14.1.0 y dompurify@^3.1.6 añadidas a package.json

2026.04.22.11 — 2026-04-22

Nuevo

  • Perfiles de IA seleccionables en caliente con 4 proveedores OpenAI-compatibles por defecto:
    • OpenRouter — anthropic/claude-sonnet-4.6 (requiere key)
    • OpenAI — gpt-4o (requiere key)
    • Ollama local — llama3.2 en http://localhost:11434/v1 (sin key)
    • LM Studio local — http://localhost:1234/v1 (sin key)
  • Dropdown en cabecera del panel IA para cambiar perfil al vuelo
  • Editor de API key inline: aparece solo para perfiles que la requieren; al cambiar a uno sin key, la app bloquea el switch hasta guardarla
  • Contexto preservado al cambiar de modelo: history vive en el main process y es neutral al endpoint; al rotar de proveedor se re-envía intacto al nuevo
  • Seed automático en primer arranque: .env:OPENROUTER_API_KEY se copia al perfil OpenRouter

Cambiado

  • ai-assistant.js: constructor ahora recibe un profile ({baseUrl, model, apiKey, requiresKey, ...}) en vez de una apiKey suelta; añadido setProfile() para cambios en caliente; headers específicos de OpenRouter solo si baseUrl contiene openrouter
  • main.js: seed de aiProfiles en settings.json en primer boot; 3 IPC nuevos: ai:get-profiles, ai:set-active-profile, ai:update-profile
  • preload.js: expone aiGetProfiles / aiSetActiveProfile / aiUpdateProfile
  • index.html + main.css: cabecera del panel IA con select + input password + botón Guardar

2026.04.22.10 — 2026-04-22

Corregido

  • Chat sin memoria entre turnos: ai-assistant.js mandaba solo [system, user] en cada llamada, la IA no sabía nada de mensajes previos. Añadido this.history (array de {role, content}), que se envía completo en cada /chat/completions junto al system prompt del turno actual
  • Historial acotado a 20 turnos (40 mensajes) — se recorta por la cabeza cuando se supera
  • interpretPrompt, interpretOutput y explainCommand comparten la misma conversación; cada turno añade par user/assistant
  • Nuevo método resetHistory() y IPC ai:reset, expuesto en preload como api.resetChat()
  • renderer.js: disconnect() llama a api.resetChat() para limpiar contexto al desconectar SSH

2026.04.22.09 — 2026-04-22

Corregido

  • Persistencia de datos SSH rota: localStorage no sobrevivía al relanzamiento del proceso Electron en file://. Migrado a fichero JSON en disco (userData/settings.json) vía IPC settings:get / settings:set
  • main.js: lee/escribe settings.json en app.getPath('userData'); logea la ruta al arrancar
  • preload.js: expone api.settingsGet() / api.settingsSet(patch)
  • renderer.js: initPersistListeners guarda host/port/user en fichero; loadConnectionData lo recupera
  • Contraseña sigue sin persistir, igual que antes

2026.04.22.08 — 2026-04-22

Cambiado

  • Migración de proveedor IA de Anthropic directo a OpenRouter (API compatible OpenAI)
  • ai-assistant.js: reescrito para hablar con https://openrouter.ai/api/v1/chat/completions vía fetch global (Node 18+), sin SDK — cero dependencias nuevas
  • Modelo por defecto: anthropic/claude-sonnet-4.6 (configurable con OPENROUTER_MODEL)
  • Base URL configurable con OPENROUTER_BASE_URL
  • main.js y tui/main.js: la API key se lee de OPENROUTER_API_KEY (antes ANTHROPIC_API_KEY)
  • .env.example: actualizado con variables OPENROUTER_*
  • package.json: eliminada dependencia @anthropic-ai/sdk

Pendiente

  • src/tests/ai-assistant.test.js seguía mockeando @anthropic-ai/sdk y no se ha reescrito aún — los tests fallarán hasta adaptar mocks a fetch

2026.04.22.07 — 2026-04-22

Corregido

  • Segunda causa raíz (el renombrado a window.api no bastó): Electron arranca los preload en modo sandbox por defecto, y en sandbox require('../../package.json') falla silenciosamente, abortando todo el preload y dejando window.api como undefined
  • main.js: añadido sandbox: false en webPreferences → el preload recupera require() completo de Node
  • main.js: listener webContents.on('preload-error', ...) para que cualquier fallo futuro del preload salga en stderr del main process en lugar de comerse el error

2026.04.22.06 — 2026-04-22

Corregido

  • Causa raíz de todos los síntomas anteriores (versión v?, banner roto, Connect inerte, onShellData is not a function): el <div id="terminal"> del HTML se exponía como window.terminal vía DOM clobbering y pisaba el objeto expuesto por contextBridge.exposeInMainWorld('terminal', ...) del preload. El renderer accedía al <div> en lugar de a la API IPC
  • preload.js: renombrado el puente de window.terminal a window.api
  • renderer.js: 15 referencias window.terminal.*window.api.*

2026.04.22.05 — 2026-04-22

Nuevo

  • DevTools siempre abierto en modo detached al arrancar (hasta estabilizar v04.*)
  • Captura global de errores JS: window.addEventListener('error' / 'unhandledrejection') vuelca mensajes al #connection-status (en rojo) y al panel de chat como burbuja error. Así cualquier fallo del renderer es visible sin abrir DevTools

2026.04.22.04 — 2026-04-22

Corregido

  • Crash en arranque v03: el banner ASCII del xterm hacía .repeat(Math.max(0, 17 - v.length)); cuando window.terminal.version no resolvía a tiempo (carrera preload/renderer), v.length lanzaba TypeError, abortando initTerminal() y — por cascada — dejando sin enganchar initEventListeners(). Resultado: badge de versión vacío, título sin versión, banner cortado a la mitad y botón Conectar inerte
  • Banner del xterm simplificado (sin cálculo de padding; separadores ═══ en lugar de caja con esquinas)
  • Asignación de this.appVersion, document.title y badge movidas al principio del constructor (antes de initTerminal), con fallback a '?' si window.terminal aún no está listo

2026.04.22.03 — 2026-04-22

Mejorado

  • Versión visible en 3 sitios (antes estaba casi oculta en gris 0.68rem):
    • Título de la ventana del SO: Unix AI Terminal — vYYYY.MM.DD.RR
    • Badge azul destacado en el sidebar bajo el título
    • Banner ASCII del terminal al arrancar (línea verde junto al nombre)
  • main.js: BrowserWindow recibe title con versión; importado APP_VERSION desde package.json
  • renderer.js: document.title se sobrescribe con la versión al arrancar para que Electron no la pise
  • main.css: .app-version rediseñado como badge con fondo y borde de acento

2026.04.22.02 — 2026-04-22

Mejorado

  • Host / puerto / usuario SSH se persisten en localStorage en tiempo real (evento input) en lugar de solo al pulsar Conectar, así los datos se recuerdan aunque no se complete la conexión
  • renderer.js: nuevo initPersistListeners(); eliminadas llamadas redundantes a setItem dentro de connect()
  • La contraseña sigue sin guardarse (ni en localStorage ni en disco)

2026.04.22.01 — 2026-04-22

Nuevo

  • Trace SSH al pulsar Conectar: se muestra en el terminal y en el chat la secuencia de eventos (start, banner, handshake, ready, error, close...) con timestamps relativos, tanto si la conexión tiene éxito como si falla
  • ssh-manager.js: connect() devuelve { events } en resolución y adjunta error.events en rechazo
  • main.js: handler ssh:connect propaga events en la respuesta IPC
  • renderer.js: nuevo método renderConnectTrace() y helper formatTrace() para volcado en chat
  • main.css: .chat-msg con white-space: pre-wrap para soportar multilínea

Mejorado

  • ssh-manager.js: connect() troceado en attachTraceListeners / attachResultListeners / buildConnConfig para mantener funciones <30 líneas (r0200)
  • package.json: main apunta a src/main/main.js (Electron) en vez de src/tui/main.js

2026.03.09.04 — 2026-03-09

Nuevo

  • Versión visible en UI: se muestra vYYYY.MM.DD.RR en la cabecera del sidebar, leída de package.json via preload.js

2026.03.09.03 — 2026-03-09

Nuevo

  • Auto-interpretación de output: tras ejecutar un comando, la IA interpreta el resultado automáticamente y lo muestra en el panel de chat derecho (sin que el usuario tenga que pedirlo)
  • ai-assistant.js: nuevo método interpretOutput(command, output, context) con SYSTEM_OUTPUT prompt dedicado
  • main.js: nuevo IPC handler ai:interpret-output
  • preload.js: expuesto interpretOutput en contextBridge
  • renderer.js: scheduleOutputInterpretation() con detección de silencio (2.5s sin nuevo output) y fallback de 15s

2026.03.09.02 — 2026-03-09

Nuevo

  • Rediseño UI estilo Warp: layout 3 columnas (sidebar SSH | terminal central | panel chat IA derecha)
  • Panel de chat con burbujas por rol: usuario, IA, sistema, error
  • Input del chat fijo en la parte inferior del panel derecho
  • Captura automática del output del terminal en buffer lastOutput
  • Persistencia de host/puerto/usuario SSH en localStorage
  • main.css reescrito para el nuevo layout de 3 columnas

2026.03.09.01 — 2026-03-09

Nuevo

  • Estructura de proyecto organizada en src/main/ y src/renderer/
  • preload.js creado con puente IPC via contextBridge (faltaba)

Mejorado

  • ai-assistant.js: modelo actualizado a claude-sonnet-4-6, constantes en UPPER_SNAKE_CASE, prompts de sistema extraidos como constantes
  • ssh-manager.js: 'use strict', simplificacion de dryRun
  • main.js: 'use strict', parametros de evento prefijados con _ donde no se usan
  • renderer.js: constantes HISTORY_MAX/HISTORY_KEY, renderHistory usa DocumentFragment y replaceChildren, fetchServerContext en paralelo con Promise.all, classList.toggle en lugar de if/else
  • main.css: design tokens CSS (--radius-*, --space-*), clase .sr-only para accesibilidad, comentarios de secciones
  • index.html: <label> para todos los inputs, aria-label y role en elementos clave, rutas corregidas a node_modules
  • package.json: version actualizada al formato YYYY.MM.DD.RR
  • .cursorrules creado con stack, estructura y reglas activas
  • .gitignore creado