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
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
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
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:
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
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
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_*
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
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