Novedades · Changelog

Cada semana, un poco mejor.

Mejoramos GarBotGPT casi a diario. Estas son las novedades más recientes: nuevas herramientas, mejoras de velocidad y arreglos, contadas en claro.

  1. v8.55.0

    🧩 Extensión Chrome: iconos actualizados con el nuevo logo

    La extensión Chrome "GarBotGPT — Web Capture" tenía sus iconos generados procedurally con canvas (gradient + G glyph dibujado a mano). Ahora usan el logo oficial NewLogoV2 (mismo source que /logo.png y todos los favicons). generate-icons.cjs reescrito de canvas a sharp con el mismo pipeline trim + padding 4% que usamos para los favicons. Iconos 16/32/48/128 regenerados. manifest.json version 1.0.0 → 1.1.0.

    Nuevo

    • 🧩 Source: scripts/NewLogoV2-source.png (mismo que favicons/logo)
    • 🧩 sharp con kernel lanczos3 + trim alpha + padding 4%
    • 🧩 Iconos 16/32/48/128 regenerados (~92% del canvas vs ~55% del dibujado anterior)
    • 🧩 manifest.json version 1.0.0 → 1.1.0 (para forzar update al reinstalar)

    Mejorado

    • 🧩 Coherencia visual: extensión + favicons + iconos PWA usan el mismo logo
  2. v8.54.1

    🔍 Favicons: logo más grande (trim del padding alpha)

    El PNG source NewLogoV2 (2).png tenía un padding alpha generoso alrededor del logo (visible: 683×704, archivo: 1254×1254 — el 45% era espacio transparente). Al hacer resize directamente, ese padding se escalaba también y el logo se veía pequeño en el favicon. Ahora con sharp.trim({ threshold: 10 }) se eliminan los bordes transparentes antes del resize y se añade un padding visual del 4% para no tocar bordes. Resultado: el logo ocupa ~92% del canvas (antes ~55%). Más visible en pestañas del navegador, home screen iOS/Android y todos los favicons.

    Nuevo

    • 🔍 sharp.trim({ threshold: 10 }) elimina padding alpha del PNG
    • 🔍 Logo ahora ocupa ~92% del canvas (antes ~55%)
    • 🔍 favicon.ico multi-size regenerado con el logo más grande

    Mejorado

    • 🔍 Padding visual del 4% del lado para balance visual
    • 🔍 Mejora visible en pestaña navegador + apple-touch-icon + android-chrome
  3. v8.54.0

    🖼️ Nuevo logo + favicons regenerados

    Reemplazado el logo de toda la app (sidebar, chat avatar, splash, login, etc.) con NewLogoV2 (2).png. Square 1254×1254 RGBA con alpha. Regenerados todos los assets de marca + favicons usando sharp con kernel lanczos3 (anti-aliasing premium): logo.png, logo-mark.png, logo-mark-transparent.png, logo-transparent.png, logo-square.png. Favicons 16/32/96/180/192/512. favicon.ico multi-size con png-to-ico. Source guardado en scripts/NewLogoV2-source.png para futuras regeneraciones. Nuevo script reutilizable scripts/generate-favicons-v3.cjs.

    Nuevo

    • 🖼️ Logo nuevo en TODAS las superficies (sidebar/chat/splash/login/menus)
    • 🖼️ 5 variantes generadas: logo, logo-mark, logo-mark-transparent, logo-transparent, logo-square
    • 🖼️ 6 favicons: 16/32/96/180 + android-chrome 192 + 512
    • 🖼️ favicon.ico multi-resolución (16+32+96) con png-to-ico
    • 🖼️ Resize con sharp kernel lanczos3 (mejor anti-aliasing)
    • 🖼️ PNG quality 95 + compressionLevel 9 (peso reducido)
    • 📝 scripts/generate-favicons-v3.cjs reutilizable para futuras actualizaciones
    • 📝 +png-to-ico ^3.0.0 devDependency
  4. v8.53.1

    🐛 Login: versión actualizada + logo nuevo

    Dos fixes en /auth/login. (1) El badge de versión arriba a la derecha mostraba "6.3.0" HARDCODED. La constante APP_VERSION existía y se actualizaba en cada release, pero el badge no la usaba. Ahora muestra "v{APP_VERSION}" dinámico. (2) El logo cargaba desde un WordPress externo (tecnofgb.com), inestable y lento. Cambiado a /logo.png local. Cuadrado 128-160px con drop-shadow violet sutil. Eliminada la versión duplicada del footer del card.

    Nuevo

    • 🖼️ Logo: WordPress externo → /logo.png local
    • 🖼️ Logo container w-32 h-32 (mobile) / w-40 h-40 (desktop), aspect 1:1
    • 🖼️ Drop-shadow violet (99,102,241,0.4) para resaltar sobre fondo oscuro
    • 🧹 Versión duplicada en el footer del card eliminada (ya estaba en el badge top)

    Arreglado

    • 🐛 Badge top-right: "6.3.0" hardcoded → v{APP_VERSION} dinámico
  5. v8.53.0

    ✨ SplashScreen rediseñado — premium pro

    Rediseño completo del splash al estilo de apps premium (Linear / Cron / Vercel). Antes: fondo blanco con un mesh sutil + logo + spinner. Ahora: fondo oscuro #0b0b14 con mesh gradient ANIMADO (3 orbs grandes con paths sinusoidales 8-10s), grain texture SVG, 12 partículas flotantes con animation paths, logo en card de liquid glass con halo pulsante + shine sweep diagonal que cruza cada 2.6s, wordmark "GarBotGPT" que aparece letra a letra con cascading + gradient text, tagline aleatorio de 4 opciones, progress bar real (0%→100%) con gradient indigo/violet/pink, version badge + skip hint en footer. Duración subida a 2.6s. Tap anywhere para saltar. Exit smoother con scale-down del logo + bg fade.

    Nuevo

    • Background dark #0b0b14 con vignette radial
    • 3 orbs mesh gradient (indigo/pink/orange) con paths animados
    • Grain texture SVG turbulence sutil (opacity 0.04)
    • 12 partículas flotantes con animation paths individuales
    • Logo card con liquid glass + border + halo pulsante
    • Shine sweep diagonal que cruza el logo cada 2.6s
    • Wordmark cascading: cada letra entrada con blur(4px)→0 + translateY
    • Gradient text en el wordmark (white → 70% white)
    • Tagline aleatorio de 4 ("Asistente IA empresarial" / "Tu segundo cerebro" / "Más que un chat" / "Inteligencia que crea")
    • Progress bar gradient indigo→violet→pink (no spinner)
    • Version + skip hint en footer con safe-area-inset-bottom
    • Tap/click anywhere → skip + exit animation
    • Duración 2s → 2.6s para apreciar la animación
    • prefers-reduced-motion: todo se desactiva
  6. v8.52.3

    🎬 Menú contextual: misma animación que el menú de 3 puntos del header

    Aplicada la animación mobile-header-menu-in al menú contextual de burbujas de chat. Es la misma que tiene el menú de 3 puntos del header móvil: bloom desde la esquina superior con clip-path round 999px → round 30px (efecto "burbuja que se expande"), scale 0.98→1.01→1, filter blur(3px)→0, total 340ms con cubic-bezier(0.2, 0.92, 0.22, 1). transform-origin: top right para que crezca desde la esquina del lado de la burbuja. Cada item dentro tiene stagger animation con delays 140/180/220/260ms para que aparezcan en cascada.

    Nuevo

    • 🎬 Clase mobile-header-popover aplicada al menú
    • 🎬 mobile-header-menu-in 0.34s con clip-path + scale + blur
    • 🎬 transform-origin: top right (lado de la burbuja propia)
    • 🎬 Contenido con animación mobile-header-menu-content-in (140ms delay)
    • 🎬 Cada item con mobile-header-menu-row-in (stagger 140-260ms)
    • 🎬 Mismo lenguaje cinético que el resto de overlays móviles
  7. v8.52.2

    📐 Menú contextual móvil: usar CSS right/left + margin 6px

    Sigue v8.52.1: el menú aún quedaba con espacio visible a la derecha. Cambio de estrategia: en lugar de calcular `left = viewportWidth - menuWidth - margin` (que depende de window.innerWidth correcto), uso CSS `right: 6px` o `left: 6px` directamente. Esto ancla el menú al edge de forma 100% fiable independientemente de viewport, zoom o safe areas. Margen reducido de 12px → 6px para quedar casi pegado al borde.

    Nuevo

    • 📐 Estrategia cambiada: CSS right/left directo en vez de cálculo aritmético
    • 📐 sideMargin 12 → 6px para casi tocar el borde
    • 📐 isOwnUserMessage: { right: 6px, left: auto }
    • 📐 !isOwnUserMessage: { left: 6px, right: auto }

    Arreglado

    • 📐 Independiente de bugs/inconsistencias de window.innerWidth
  8. v8.52.1

    💧 Menú contextual móvil: liquid glass + alineamiento al edge

    Dos refinamientos sobre v8.52.0. (1) Alineamiento: antes el menú se anclaba al borde de la burbuja, dejando un hueco en blanco entre el menú y el borde derecho del viewport si la burbuja no llegaba al edge. Ahora se ancla al BORDE DEL VIEWPORT (con margen 12px) — el menú siempre toca el lado del que viene la burbuja. (2) Aplicado liquid glass real con la nueva clase mobile-message-context-glass: gradientes radiales + lineales, backdrop-filter blur(28px) saturate(1.4) brightness(1.08) contrast(0.82), inset shadows con highlights blancos y subtle tinte violeta, edge highlight 95% white, sheen interno con linear-gradient para volumen. Mismo lenguaje que mobile-header-floating-control / bottom-nav-shell.

    Nuevo

    • 📐 left = viewportWidth - menuWidth - margin (para burbujas right-aligned)
    • 📐 Margen horizontal 16 → 12px
    • 💧 Nueva clase .mobile-message-context-glass en globals.css
    • 💧 Gradientes radial + linear apilados
    • 💧 backdrop-filter blur(28px) saturate(1.4) brightness(1.08) contrast(0.82)
    • 💧 Edge highlight 95% white + inset shadows con tinte violeta sutil
    • 💧 Pseudo-elementos ::before (sheen vertical) y ::after (rim light)
  9. v8.52.0

    📱 Menú contextual móvil estilo ChatGPT

    Rediseñado el menú de acciones que aparece al long-press en mensajes del usuario en móvil. Antes: aparecía un menú flotante + DUPLICADO de la burbuja en una posición arbitraria del touch, dejando la original borrosa detrás. Look raro. Ahora estilo ChatGPT mobile: la burbuja ORIGINAL se queda en su sitio (con un leve scale + ring blanco como destaque), aparece un scrim translúcido detrás, y el menú de acciones se ancla DEBAJO (o ENCIMA si no cabe) pegado al borde de la burbuja, alineado horizontalmente con ella. Sin duplicados.

    Nuevo

    • 📱 useRef en la burbuja del user para capturar getBoundingClientRect
    • 📱 mobileUserMenuPosition calcula left/top relativos a la burbuja
    • 📱 Espacio below vs above: elige el lado con más espacio
    • 📱 Right-aligned bubbles → menu alineado a la derecha; left → left
    • 📱 Burbuja sube z-[146] cuando menú abierto (encima del scrim)
    • 📱 Burbuja gana ring-2 white/40 + scale 1.005 + shadow elevated
    • 📱 Scrim bg-black/20 con blur-[2px] sutil
    • 📱 Eliminado el duplicado mobileUserMenuPreviewText y referencias
    • 📱 Animations mctx-fade + mctx-pop con cubic-bezier(0.22, 0.9, 0.24, 1)
    • 📱 Menu width 280px (antes 328px) más compacto
  10. v8.51.1

    ↩️ Revert: Sidebar vuelve al diseño anterior

    A petición del usuario, revertido el rediseño del sidebar de v8.51.0 al estado anterior (v8.50.0). El bug fix de clearActiveTools (la X que cerraba herramientas activas) SE MANTIENE — eso no se revierte porque resuelve un bug real. Solo se vuelve atrás el cambio visual del sidebar: buscar separado de filter, Apps section arriba, footer con email visible, ChatRow sin avatares ni preview.

    Nuevo

    • ↩️ git checkout 31a1398 -- SidebarSleek.tsx
    • ↩️ Vuelven: Buscar (botón) + Filter (input) separados
    • ↩️ Vuelve: Imágenes/Canales/Apps en el top
    • ↩️ Vuelve: footer con email visible debajo del nombre
    • ↩️ Vuelve: ChatRow compacto (h-9) con pin button + título

    Arreglado

    • Se MANTIENE el fix de clearActiveTools (no es regresión)
  11. v8.51.0

    🎨 Sidebar rediseñado · 🐛 Fix X tool no cerraba

    Dos paquetes. (1) BUG FIX: la X que limpia herramientas activas del composer no funcionaba cuando tenías App Builder/PPT/Imagen→Código/Mapa Mental/Quiz activos. clearActiveTools() no incluía los setters de las herramientas nuevas. (2) SIDEBAR rediseñado: buscar + filter unificados en un solo input con búsqueda inline + Enter para modal completa; Imágenes/Canales/Apps movidos al BOTTOM para dar espacio vertical a chats; footer compacto (solo avatar+nombre, email se ve en dropdown); avatares auto-generados por chat (hash del título → color HSL pastel + letra) en lugar de pin button. Preview opcional con context_summary o relative time bajo el título.

    Mejorado

    • 🎨 Sidebar: input buscar + filter unificados (placeholder "Buscar chats…")
    • 🎨 Enter en input → abre modal de búsqueda completa
    • 🎨 ⌘K hint visible dentro del input
    • 🎨 Apps section movida al footer (encima del user card)
    • 🎨 Footer compacto: avatar + nombre solo. Email visible en el dropdown
    • 🎨 ChatRow con avatar auto-generado (hash → HSL pastel + letra)
    • 🎨 Pin overlay 14×14 en esquina inferior derecha del avatar cuando anclado
    • 🎨 Row height 36px → 44px para dar espacio a título + sub-text
    • 🎨 Sub-text con context_summary (si existe) o relative time short (ahora/5m/2h/ayer)
    • 🎨 Mini-bar colapsado al hacer click en PanelLeftClose (ya existía, verificado)

    Arreglado

    • 🐛 clearActiveTools incluye setAppBuilder, setSlidesGeneration, setImageToCode, setMindMap, setQuizGeneration
  12. v8.50.0

    🧠 3 nuevas herramientas: Imagen→Código · Mapa Mental · Quiz

    Tres nuevas herramientas en el menú GENERAR del ChatInput. (1) IMAGEN → CÓDIGO: subes una screenshot/wireframe/mockup → la IA reproduce el diseño en React+Tailwind como artifact html. Killer para devs que quieren prototipar rápido (lo que hace v0.dev). (2) MAPA MENTAL: cualquier respuesta se devuelve como mindmap Mermaid en artifact navegable con jerarquía visual. Ideal para research y aprendizaje. (3) GENERADOR DE QUIZ: cualquier tema → 10 preguntas tipo test con 4 opciones y respuesta colapsable en <details>. Útil para estudiantes y profesores.

    Nuevo

    • 📸 Imagen → Código: usa GPT-4o vision con prompt específico → artifact html React+Tailwind via htm
    • 📸 Chip cyan en composer + icono ScanLine
    • 🧠 Mapa Mental: artifact type=mermaid con sintaxis mindmap → render SVG navegable
    • 🧠 Chip emerald + icono Network. 4-7 ramas, 8-30 nodos máx para legibilidad
    • 🎓 Quiz: markdown estructurado con 10 preguntas tipo test, respuestas en <details>
    • 🎓 Chip amber + icono GraduationCap. Dificultad progresiva, explicaciones
    • ⚙️ Pattern idéntico a App Builder/PPT: state + chip + body flag + system prompt
  13. v8.49.1

    🐛 Submenú "Más": fix clipping superior en viewports pequeños

    El submenú "Más" del ChatInput está anclado al bottom del trigger (bottom-0) y crece hacia arriba. Con las 4 secciones nuevas + 11 items, en viewports cortos los items de la sección "GENERAR" (los del tope) se salían por encima del viewport. Fix: useEffect que mide bounding rect del trigger y calcula maxHeight dinámico = rect.bottom - 16px. Si el contenido excede, scroll interno con scrollbar fino.

    Arreglado

    • 🐛 useRef + getBoundingClientRect del trigger "Más"
    • 🐛 useEffect recalcula maxHeight al abrir + en resize del viewport
    • 🐛 maxHeight = max(220, rect.bottom - 16) — siempre 220px mínimo
    • 🐛 overflow-y-auto + scrollbar fino + overscroll-contain
    • 🐛 Resultado: en cualquier viewport, todos los items del submenú visibles
  14. v8.49.0

    🧰 Menú de herramientas reorganizado por secciones

    El submenú "Más" del ChatInput desktop estaba desordenado — mezcla de items de generación, datos, avanzado e integraciones sin ningún agrupamiento visual. Ahora reorganizado en 4 secciones temáticas con cabeceras pequeñas en mayúsculas: GENERAR, DATOS Y ARCHIVOS, AVANZADO, INTEGRACIONES. Items relacionados juntos. Width 274px → 296px para más comodidad. Separadores 1px más finos.

    Nuevo

    • 🧰 4 secciones con cabeceras uppercase tracking-wider
    • 🧰 GENERAR: Documento, Presentación PPT, App Builder
    • 🧰 DATOS Y ARCHIVOS: Conocimientos, Hoja cálculo, Unidad red, BD
    • 🧰 AVANZADO: Modo agente, Reproductor música
    • 🧰 INTEGRACIONES: Google, Spotify, Microsoft
    • 🧰 Width submenú 274 → 296px, padding más cómodo (1.5 → 2)
    • 🧰 Separadores condicionales: solo aparecen si hay items en la sección
    • 🧰 "Más" button highlight cuando cualquier item de submenú activo
  15. v8.48.3

    🐛 Parser de artifacts tolera <artifact> sin cerrar

    Bug detectado en producción: el LLM (sobre todo App Builder con HTML largo) a veces emite la apertura <artifact id="..." type="html"> pero NO cierra con </artifact> al final (se queda corto en tokens, se trunca, o simplemente lo olvida). El parser regex strict no matcheaba sin closing tag → todo el HTML quedaba como texto crudo en el chat. Nuevo extractor extractArtifactBlocks() basado en índices: encuentra todas las aperturas, para cada una busca el </artifact> más cercano antes de la siguiente apertura o del fin del texto; si NO hay cierre, captura igual el contenido. Replaza de atrás hacia adelante para mantener índices válidos.

    Arreglado

    • 🐛 extractArtifactBlocks(): index-based scanner que tolera tags abiertas
    • 🐛 Si </artifact> no aparece, captura hasta siguiente <artifact ...> o EOF
    • 🐛 Case-insensitive en el closing tag
    • 🐛 Replace en orden reverso para que los índices no se descuadren
    • 🐛 Resultado: incluso si el LLM trunca/olvida el closing, no se filtra HTML al chat
  16. v8.48.2

    🐛 App Builder: HTML ya no se cuela en el chat (solo en artifact)

    Bug: cuando el usuario usaba el toggle App Builder, el LLM a veces ignoraba las tags <artifact> y envolvía el HTML completo en ```html ``` markdown, lo que hacía que TODO el código apareciera como bloque gigante en el chat además de (o en vez de) la card del artifact. Causa: el prompt usaba un ejemplo con ```html``` fence como ilustración y el LLM lo copiaba literalmente. Fix doble: (1) prompt rediseñado con ❌/✅ explícitos, ejemplos WITH <artifact> tags, sin ```html``` en ningún sitio. (2) Fallback parser server-side: si detecta un ```html``` fence con documento HTML completo (DOCTYPE/&lt;html&gt;) y NO hay <artifact> tag, lo convierte automáticamente en artifact. Igual para SVG. Cleanup stream-side actualizado para ocultar también ```html``` durante el streaming.

    Arreglado

    • 🐛 prompt-builders.ts: App Builder prompt rediseñado con ❌ MAL / ✅ BIEN explícito
    • 🐛 artifact-parser.ts: pass 2 fallback que detecta ```html``` con doc completo → auto artifact
    • 🐛 Idem para ```svg``` fences con SVGs completos
    • 🐛 MessageBubble cleanAssistantStreamContent oculta ```html``` durante stream con placeholder "Generando aplicación…"
    • 🐛 Resultado: con App Builder activo, el chat solo muestra el texto presentación + card, nunca el código
  17. v8.48.1

    📊 Toggle dedicado "Generar PPT" en el menú

    Nueva herramienta independiente "Generar PPT" en el menú de herramientas. Antes había que escribir keywords ("presentación", "powerpoint", "ppt", "slides", etc.) para que la IA generara un .pptx. Ahora basta con activar el toggle y la siguiente respuesta de la IA se exporta como .pptx automáticamente, da igual el wording del prompt. Chip naranja con icono Presentation.

    Nuevo

    • 📊 Store: nuevo slidesGeneration flag + setter
    • 📊 ChatInput: menu desktop + móvil con icono Presentation
    • 📊 Chip activo naranja con etiqueta "PPT"
    • 📊 Body request envía slides_generation: boolean
    • 📊 Route: cuando true → fuerza requestedDocumentFormat=pptx + effectiveDocumentGeneration=true sin importar keywords del mensaje
    • 📊 Útil para "hazme algo sobre el café" + toggle PPT → genera ppt aunque no digas "presentación"
  18. v8.48.0

    🚀 App Builder + Deploy a Vercel 1-click

    Nueva herramienta en el menú: App Builder. Activas el toggle, describes una app, y la IA genera una mini-aplicación web COMPLETA en un solo archivo HTML (React 18 desde esm.sh + Tailwind via CDN + cualquier librería ESM). Aparece como artifact tipo html, se renderiza inmediatamente en el panel lateral, totalmente funcional. Iteras con mensajes ("añade dark mode", "cambia el azul a verde"). NUEVO botón Rocket en el panel: "Deploy to Vercel" sube el HTML como sitio estático y devuelve URL pública real tipo nombre-xxxx.vercel.app en ~30s. Requiere VERCEL_TOKEN en env.

    Nuevo

    • 🚀 Nueva herramienta "App Builder" en el menú (chip violet con Wrench)
    • 🚀 buildAppBuilderPrompt(): instrucciones específicas para single-file React+Tailwind+htm
    • 🚀 La app es funcional desde el primer render (no placeholders)
    • 🚀 Iteración chat-based — IA reusa el mismo artifact id → versionado automático
    • 🚀 POST /api/deploy/vercel: usa Vercel API v13 con proyecto compartido garbotgpt-apps
    • 🚀 Validación de tamaño 800KB max + auth gate
    • 🚀 Botón Rocket en ArtifactPanel solo cuando type=html
    • ⚙️ Env vars: VERCEL_TOKEN (required), VERCEL_TEAM_ID, VERCEL_DEPLOY_PROJECT_NAME (defaults garbotgpt-apps)

    Arreglado

    • 🚀 DeployVercelDialog: loading/error/success con copy URL + abrir
  19. v8.47.0

    🧪 /ios v10: Playground completo de Apple Liquid Glass

    Nueva variante v10 en /ios — port DEL TODO del index.html de liquid-glass-main con TODOS los controles editables en vivo. v9 (preset) sigue ahí. La v10 incluye: panel lateral collapsible con sliders para width/height/border-radius, glass thickness, bezel width, refractive index, scale ratio, blur, specular opacity/saturation, inner shadow (color/blur/spread), glass tint (color/opacity), outer shadow blur. 5 backgrounds preset (cielo/flores/bosque/vivo/mosaico) + opción de pegar URL custom. Glass arrastrable. Botón reset. Solo Chromium para refracción SVG real; en otros navegadores la card seguirá pero sin la refracción física.

    Nuevo

    • 🧪 AppleLiquidGlassCard extendido con 7 props nuevas (scaleRatio, tintColor, tintOpacity, innerShadowColor/Blur/Spread, outerShadowBlur)
    • 🧪 hexToRgb helper para convertir colores a CSS vars rgba
    • 🧪 AppleLiquidGlassPlayground: state local con ~15 sliders + 2 color pickers
    • 🧪 Panel collapsible (toggle button cuando cerrado)
    • 🧪 Botón reset que restaura los defaults de v9
    • 🧪 5 backgrounds preset con thumbnails + input URL custom
    • 🧪 Sliders accent-indigo, valor mostrado en mono font con tabular-nums
    • 🧪 Sección "Editor en vivo" propia antes del grid v1-v8
  20. v8.46.0

    ⚙️ Settings Modal: versión móvil nativa (estilo iOS Settings)

    Rediseño del SettingsModal para móvil. Antes: el modal usaba el mismo layout que desktop con tabs en scroll horizontal arriba (texto pequeño, mala UX). Ahora: estilo iOS Settings app. (1) BOTTOM SHEET 92vh con rounded-t-3xl + drag handle indicator + slide-up animation. (2) Lista de tabs FULL-SCREEN cuando entras (cards grandes con icono color + label + chevron right). (3) Click en tab → contenido full-screen con header back "← Ajustes" + título de la tab centrado. (4) Save button full-width grande con safe-area-inset-bottom. Desktop sin cambios.

    Nuevo

    • 📱 Bottom sheet 92dvh, rounded-t-3xl, animación slide-up cubic-bezier
    • 📱 Drag handle indicator estilo iOS
    • 📱 Tabs como cards verticales grandes (icono + label + chevron)
    • 📱 Drill-down: click tab → contenido full-screen + back button
    • 📱 Header centrado con título de tab (absolute left-1/2)
    • 📱 Save button full-width 3px padding + safe-area-inset-bottom
    • 📱 mobileTabSelected state controla la navegación
    • 🖥️ Desktop sin cambios (sidebar + content side-by-side)
  21. v8.45.0

    🔥 Racha + 📊 Stats + 🏆 Logros (3 nuevos tabs en Ajustes)

    Tres tabs nuevas en el modal de Ajustes para gamificación e insights personales. (1) RACHA: contador de días consecutivos activos, mejor racha, días totales activos. Estilo Duolingo con flama amber. (2) ESTADÍSTICAS: mensajes totales, conversaciones, imágenes/documentos/artifacts generados, hora más activa, tu chat más largo, modelos más usados con barras de progreso. (3) LOGROS: 22 achievements desbloqueables en 4 tiers (bronce/plata/oro/platino) cubriendo categorías: mensajes, imágenes, documentos, artifacts, voz, racha, conversaciones, días activos. Progress bar con % desbloqueado. Unlock automático en cada visita.

    Nuevo

    • 🔥 GET /api/user-stats agrega mensajes, calcula streak, dispara unlocks
    • 🔥 22 achievements definidos en lib/achievements.ts
    • 📊 Top conversation + top hour + model usage ranking con barras
    • 📊 Streak: día actual / longest / total active days / last active date
    • 🏆 Auto-unlock de achievements en cada GET /api/user-stats
    • 🏆 Progress bar global con % de logros desbloqueados
    • ⚙️ 3 nuevas tabs en SettingsModal con iconos Flame/BarChart3/Trophy

    Mejorado

    • 🔥 4 tiers: bronze, silver, gold, platinum (paleta distinta cada uno)

    Seguridad

    • 🔥 DB: user_streaks + user_achievements tables con RLS
  22. v8.44.1

    ⌨️ Inline autocomplete (ghost text) en el textarea

    Mientras escribes, una sugerencia gris aparece después del cursor con el final probable de tu frase. Tab para aceptar. Tipo Cursor / GitHub Copilot pero en el input del chat. Usa gpt-4o-mini con contexto de los últimos 4 mensajes de la conversación. Debounce 450ms. Solo cuando el input cabe en una línea. Toggle por usuario via localStorage. Coste ~$0.00002 por sugerencia, despreciable.

    Nuevo

    • ⌨️ POST /api/chat/autocomplete con gpt-4o-mini
    • ⌨️ Hook useInlineAutocomplete con debounce 450ms + AbortController
    • ⌨️ Mirror div con texto invisible + suggestion gris + chip "Tab"
    • ⌨️ Tab key handler en handleKeyDown intercepta antes de Enter
    • ⌨️ Auto-cancela peticiones obsoletas al seguir tipeando
    • ⌨️ No completa si frase termina en puntuación (.!?)
    • ⌨️ Toggle via localStorage garbotgpt:autocomplete
  23. v8.44.0

    📌 Pin messages · ✨ Reescribir para… · 📋 Auto-resumen

    Tres nuevas funciones de calidad de vida para el chat. (1) PIN MESSAGES: botón pin/unpin en cada mensaje. Los anclados aparecen en una barra sticky amber arriba del chat con preview clickeable que hace scroll smooth + flash. Útil para conversaciones de research largas. (2) REESCRIBIR PARA…: dropdown en respuestas IA con 8 audiencias: jefe, niño 8 años, experto, Twitter/X, email formal, casual, más corta, más detallada. Envía un nuevo prompt al chat con instrucciones de reformulación. (3) AUTO-RESUMEN: cuando el chat ≥50 mensajes, aparece icono FileText en el header. Click → modal con TL;DR estructurado (temas, decisiones, acciones pendientes) generado por gpt-4o-mini. Copy/regenerar/cerrar.

    Nuevo

    • 📌 meta_json.pinned guarda estado, optimistic update en store
    • 📌 PinnedMessagesBar: hasta 2 visibles + "+N más" expandible
    • 📌 Pin scroll-to-message con ring amber 1.5s flash al llegar
    • 📌 Ring amber permanente en mensajes anclados
    • RewriteMenu: dropdown con 8 opciones predefinidas + iconos
    • Custom event chatinput-send-prompt para comunicar con ChatInput
    • 📋 POST /api/conversations/[id]/summarize con gpt-4o-mini
    • 📋 ConversationSummaryModal con markdown structured (TL;DR/temas/decisiones/acciones)
    • 📋 Botón en header solo aparece cuando ≥50 mensajes
  24. v8.43.0

    🎯 Generación de presentaciones .pptx

    Nueva capacidad de generación de documentos: PowerPoint (.pptx). Junto a docx/pdf/xlsx/md/html/json/txt que ya teníamos. Detecta keywords "presentación, powerpoint, ppt, slides, diapositivas, deck, pitch deck" y genera un .pptx 16:9 con portada estilizada (gradient indigo→violeta lateral), slides H1/H2-driven, header bar de marca, footer con número de slide, paleta GarBotGPT consistente. El LLM recibe instrucciones específicas para estructurar el markdown por slides (cada ## es una slide, bullets cortos, 7-12 slides total).

    Nuevo

    • 📊 Librería pptxgenjs (4.0.1) para Node-compatible PPTX
    • 📊 GeneratedDocumentExt extendido con "pptx"
    • 📊 inferDocumentOutputFormat detecta presentación/powerpoint/ppt/slides/deck/pitch deck
    • 📊 Cada H1/H2 del markdown = nueva slide; bullets como bullets reales
    • 📊 Header bar "GarBotGPT" + footer con paginación
    • 📊 buildDocumentGenerationPrompt: instrucciones específicas para pptx
    • 📊 MessageBubble: icono Presentation naranja para .pptx

    Mejorado

    • 📊 buildPptxBufferFromMarkdown(): portada + slides 16:9, paleta indigo/violet/pink
  25. v8.42.2

    🎵 Spotify: cache 5min + cooldown global tras 429

    Los logs de Vercel confirmaron que el "no se encontró canciones" venía de Spotify devolviéndonos 429 Too Many Requests (rate-limit por app, compartido por todos los usuarios). El retry single-shot tampoco salvaba: ambos volvían 429. Ahora: (1) cache in-memory de 5min por búsqueda (query + filtro + count), evita hits repetidos cuando el usuario reintenta. (2) Cool-down global: cuando vemos 429 dos veces seguidas, marcamos RATE_LIMITED_UNTIL = now + Retry-After (o 60s default) y todas las búsquedas siguientes se cortocircuitan devolviendo [] sin pegarle a Spotify. (3) El mensaje al usuario diferencia: si fue rate-limit, dice "Spotify saturado, prueba en Xs"; si fue 0 resultados real, sugiere otro nombre. (4) Logs diagnósticos de v8.42.1 limpiados.

    Nuevo

    • RATE_LIMITED_UNTIL global, respeta Retry-After del header
    • Si search devuelve 429 dos veces, marca cooldown y devuelve []
    • isSpotifyRateLimited() expuesto al spotify tool
    • 💬 Mensaje al usuario diferencia rate-limit vs no-results
    • 💬 Mensaje rate-limit dice "Cooldown: Xs" con tiempo real restante
    • 🧹 Logs diagnósticos de v8.42.1 limpiados

    Mejorado

    • Cache LRU lite (max 100 entries, TTL 5min) en SEARCH_CACHE
  26. v8.42.1

    🔍 Spotify: logging diagnóstico temporal

    Logs temporales en searchSpotifyTracks para identificar por qué la búsqueda devolvía 0 tracks. Logs revelaron que era 429 Too Many Requests de Spotify. Limpiado en v8.42.2.

    Arreglado

    • 🔍 console.log + warn + error en fetchPage
  27. v8.42.0

    🧠 Spotify: LLM extrae artista/query/cantidad (sin depender de palabras clave)

    El clasificador LLM (gpt-4o-mini) ya devolvía la intención create/read/none, pero el regex de extracción de artista en deriveSpotifySearchIntent() seguía siendo el que decidía la búsqueda real. Eso fallaba con fraseología natural ("ponme algo de Rosalía", "música para correr", "mix de Bad Bunny en español"). Ahora el LLM extrae en la MISMA llamada: artist (nombre exacto capitalizado), searchQuery (semántico, traducido a inglés cuando no hay artista), y requestedCount. El spotify tool USA estos parámetros con prioridad absoluta. Fallback al regex solo si el LLM no extrajo nada o falla la llamada. Coste +1KB tokens output, ~$0.00005 por llamada.

    Nuevo

    • 🧠 Prompt LLM extiende JSON: action + confidence + artist + searchQuery + requestedCount
    • 🧠 LLM capitaliza ("michael jackson" → "Michael Jackson") y traduce queries a inglés
    • 🧠 SpotifyToolContext: nuevos llmArtist, llmSearchQuery, llmRequestedCount
    • 🧠 tools/spotify.ts: si hay llmArtist → query=`artist:"X"`; si solo llmSearchQuery → query libre
    • 🧠 Fallback automático al regex deriveSpotifySearchIntent() si LLM no aportó nada
    • 🧠 Ya no depende de palabras clave para fraseología natural
  28. v8.41.2

    🎵 Spotify: regex acepta "album/álbum/mix" como trigger

    Cambio MINIMAL sobre el revert de v8.41.1. El regex artistAfterDe en deriveSpotifySearchIntent() solo reconocía "playlist|lista|música|canciones|temas" como palabras que disparan la extracción del artista. Para "hazme un album de Michael Jackson" fallaba: no extraía el artista, caía al cleaned path con query="un Michael Jackson" sin artistFilter, Spotify devolvía mezcla rara o 0 tracks, y no aparecía la card. Ahora añadidas como triggers: album/albumes/álbum/álbumes/mix/recopilatorio/selección. NO se reintroduce el cache ni el 429 handling de la v8.33.26 anterior.

    Nuevo

    • 🎵 1 línea cambiada en deriveSpotifySearchIntent() (regex)
    • 🎵 "hazme un álbum de X" → ahora extrae X correctamente

    Mejorado

    • 🎵 Sin cache, sin rate-limit handling (lo demás sigue revertido)
  29. v8.41.1

    ↩️ Revert: Spotify a estado pre-v8.33.17

    A petición del usuario: Spotify revertido a su estado anterior a los cambios de v8.33.17 (estrategia artist-ID + top-tracks + albums). spotify-helpers.ts restaurado al commit 653fc80 (v8.33.15) y la reordenación de v8.40.0 en route.ts (effectiveSpotifyRead vs Create) deshecha. Resto del proyecto intacto.

    Nuevo

    • ↩️ spotify-helpers.ts: -439 líneas (vuelve a la implementación original)
    • ↩️ route.ts: effectiveSpotifyRead y Create vuelven a la lógica original

    Mejorado

    • ↩️ Sin ALBUM_CACHE, sin RATE_LIMITED_UNTIL, sin regex extendido de "album"

    Arreglado

    • ↩️ Resto del codebase intacto (artifacts, /ios showcase, bug fixes de edit, etc.)
  30. v8.41.0

    🎥 Fondo de vídeo en /ios + 🍎 v9 Apple iOS 26 (port oficial)

    Dos extensiones al showcase /ios para evaluar el liquid glass en condiciones reales: (1) nueva opción de fondo "Vídeo (movimiento real)" que usa el hero-bg.mp4 de la web para que la refracción se vea sobre contenido en movimiento. (2) Nueva variante v9 "Apple iOS 26" — port del repositorio liquid-glass-main de @lucasromerodb, con refracción física real usando SVG feDisplacementMap + perfil de refracción IOR calculado en canvas + specular highlights pre-renderizados. La card es ARRASTRABLE sobre el fondo para ver cómo refracta. Solo Chromium (Chrome/Edge); en Firefox/Safari fallback a blur normal.

    Nuevo

    • 🎥 Bg "Vídeo" usa <video> autoplay loop con hero-bg.mp4
    • 🎥 Overlay sutil top/bottom para legibilidad sin tapar movimiento
    • 🍎 v9 Apple iOS 26: AppleLiquidGlassCard.tsx (port de index.html)
    • 🍎 calculateRefractionProfile() con IOR + bezel + glass thickness
    • 🍎 generateDisplacementMap + generateSpecularMap en canvas
    • 🍎 SVG filter inyectado dynamically con dangerouslySetInnerHTML
    • 🍎 Drag handler: pointer events con clamp a parent bounds
    • 🍎 Sección "Destacado" propia antes del grid v1-v8
    • 🍎 Fallback elegante para navegadores sin backdrop-filter: url()

1118 versiones publicadas · página 32 de 38. Míralo dentro de la app.