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.33.13

    🎨 Logos nivel diseñador (rediseño completo /logos)

    Galería /logos rehecha con criterio "designer brand brief": 14 lockups con texto + 14 símbolos sin texto. Paletas curadas (un solo acento por logo), tipografía con contraste de pesos y kerning ceñido, conceptos legibles (monogramas G, brackets dev, slash divider, two-tone, italic editorial, glitch, single-stroke, soundwave, …). Cards con crop marks decorativos para estética de diseño.

    Mejorado

    • 🎨 14 nuevos lockups con texto (540×180): monogram G, period signature, italic editorial, hex token, typing dots, two-tone divider, brackets wrap, underline arc, GB monograma, slash, outline, version badge, orb, dot-matrix
    • 🎨 14 nuevos iconos sin texto (200×200): G burbuja, token hex, orb premium, rings concéntricos, GB mono, dots square, single-stroke G, diamond cut, quantum orbit, glitch G, dot mesh, arrow G, soundwave, brackets ⟨G⟩
    • 🎨 Paletas curadas: amber, electric blue, pink, mint, violet, cyan, rose — UN solo acento por logo (sin rainbow)
    • 🎨 Tipografía: contraste de pesos (300/700/800), letter-spacing negativo, mixed weights con tspan
    • 🎨 Crop marks decorativos en cada card (estética de pliegos de diseño)
  2. v8.33.12

    🎵 Spotify: detección ampliada · 🛠️ Maintenance rediseñada · 🎨 Logos solo icono

    Tres mejoras: (1) La detección de intent de Spotify ahora cubre muchas más formas de pedir crear una playlist (haz/arma/monta sin "me", patrón "playlist con N canciones de X" sin verbo, etc.), antes fallaba con frases comunes. (2) Página de mantenimiento totalmente rediseñada: mesh gradient animado, timeline de progreso, reloj en vivo, polling automático, subscribe email, status cards. (3) /logos ahora tiene tabs: "Con texto" (24 wordmarks) y "Solo icono" (24 símbolos sin texto, perfectos para favicon, app icon, redes sociales).

    Nuevo

    • 🎵 Spotify: regex de intent ampliada (verbos: haz, arma, monta, pon, dame, quiero, necesito, …)
    • 🎵 Nuevo patrón: "playlist con 20 canciones de Sabina" detectado sin necesidad de verbo
    • 🎵 System prompt más directivo: el LLM ya NO puede decir "no puedo crear playlists"
    • 🛠️ Maintenance: mesh gradient animado + grid + scanlines
    • 🛠️ Timeline de 4 pasos (Iniciado → Aplicando → Validando → Volvemos)
    • 🛠️ Reloj en vivo, contador de "tiempo en mantenimiento", auto-recarga cuando termina
    • 🛠️ Polling cada 8s para detectar cuando se desactiva el modo
    • 🛠️ Suscribir email para avisar cuando vuelva

    Mejorado

    • 🎨 /logos: tab "Solo icono" con 24 variantes cuadradas 200×200 sin texto

    Arreglado

    • 🎵 Fix mojibake "álbum" en client → ahora se normaliza con NFD-strip de acentos
  3. v8.33.11

    🔧 Fixes mantenimiento: /garmantenimiento + URL real + versión visible

    Tres fixes al sistema de mantenimiento de v8.33.10: (1) /garmantenimiento rechazaba a admins legítimos porque la query SELECT incluía columna inexistente `email` en profiles → role=null → acceso restringido. (2) Header (chat + mobile) seguía mostrando v8.33.7, ahora muestra v8.33.11. (3) El middleware redirigía con cambio de URL a /maintenance; ahora hace REWRITE (la URL del navegador no cambia, el usuario sigue viendo el dominio normal).

    Nuevo

    • 🛠️ Nueva versión visible discreta en la página de login
    • 🌐 Mantenimiento ya NO cambia la URL: rewrite interno en lugar de redirect
    • El usuario en /chat sigue viendo "/chat" en la barra pero ve la página de mantenimiento

    Arreglado

    • 🛠️ Fix: /garmantenimiento accesible para admins (eliminada referencia a profiles.email inexistente)
    • 🛠️ Fix: APP_VERSION bumped a 8.33.11 en chat/Header.tsx y mobile/MobileHeader.tsx
  4. v8.33.10

    🔧 Modo mantenimiento global + conocimientos privados + Unidades de Red desactivadas

    Nuevo modo mantenimiento controlable desde /admin → Mantenimiento (o vía bypass /garmantenimiento). Cuando está activo, todos los usuarios ven /maintenance (página pro con aurora + estado en vivo) y /api/* devuelven 503; solo /garmantenimiento sigue accesible para el admin. Nueva opción "🔒 Solo yo (privado)" en conocimientos: marcadas así, solo las ve y usa su creador. La pestaña "Unidades de Red" se oculta del panel (código intacto).

    Nuevo

    • 🛠️ Pestaña /admin → Mantenimiento con toggle ON/OFF + mensaje personalizable
    • 🔑 URL secreta /garmantenimiento como bypass para reactivar el sitio
    • 🛡️ Middleware redirige todo a /maintenance excepto bypass + /api/admin/maintenance + /api/auth
    • 🚫 Pestaña Unidades de Red oculta del menú (código backend intacto)

    Mejorado

    • 🎨 Página /maintenance con aurora, status pills y CTA — diseño profesional dark mode

    Arreglado

    • 🚫 APIs durante mantenimiento devuelven 503 con { error: "MAINTENANCE_MODE" } en lugar de redirect

    Seguridad

    • 🔒 Conocimientos privados: checkbox "Solo yo" + filtro en API admin y pública

    Maintenance mode

    • DB: app_settings(maintenance_mode) jsonb {enabled, message}
    • src/lib/maintenance.ts: readMaintenanceState() + writeMaintenanceState() con caché 5s
    • src/app/api/admin/maintenance/route.ts: GET (público) + POST (admin)
    • src/app/maintenance/page.tsx: página pública con aurora + grid + mensaje editable
    • src/app/garmantenimiento/page.tsx + GarMantenimientoClient.tsx: bypass admin
    • src/components/admin/MaintenancePanel.tsx: panel dentro de /admin (tab "Mantenimiento", grupo Sistema)
    • src/lib/supabase/middleware.ts: chequeo de maintenance antes de auth, con bypass de rutas críticas

    Conocimientos privados

    • DB: knowledge_collections.is_private BOOLEAN NOT NULL DEFAULT FALSE + índice parcial
    • API admin GET/POST/PATCH/DELETE: filtro (is_private=false OR created_by=me) + guards de ownership
    • API pública /api/knowledge/collections: mismo filtro
    • UI: checkbox "🔒 Solo yo (privado)" en el formulario + badge 🔒 en la lista

    Limpieza

    • Tab "Unidades de Red" oculta en /admin (comentada, no eliminada)
    • Si se quiere reactivar: descomentar la línea en AdminPageClient.tsx
  5. v8.33.9

    📤 Subidas de conocimiento en segundo plano + galería /logos

    Las subidas de archivos al panel de conocimientos ahora viven en un store Zustand global, así que sobreviven a cambios de pestaña sin abortar ni perder el progreso. Un widget flotante muestra el avance desde cualquier sección de /admin. Además, nueva página /logos con 24 logos vectoriales descargables para elegir la identidad del producto.

    Nuevo

    • 🧠 Store global useUploadQueueStore: la cola y el bucle de subida viven fuera del componente
    • ⏯️ Cambiar de pestaña (Modelos, Usuarios, etc.) ya NO interrumpe ni pierde uploads en curso
    • 🛰️ Widget flotante UploadProgressWidget en /admin: progreso por colección, expand/colapsar, descartar
    • 🧹 Botón "Limpiar" para descartar uploads completados (solo aparece cuando no hay activos)

    Mejorado

    • 🎨 Nueva página /logos con 24 variantes de logo SVG (descargables + copiables al portapapeles)
    • 🎨 Logos incluyen: bot-head, brain-circuit, spark, neural-net, hex-chip, monograma G, wordmark, pixel, cubo iso, escudo, llama, hoja, aurora, infinito, ojo IA, …

    Background uploads

    • src/store/upload-queue-store.ts: nuevo store Zustand global con startUpload(), clearCompleted(), removeItem()
    • src/components/admin/UploadProgressWidget.tsx: widget flotante con barra de progreso, agrupado por colección, expandible
    • src/components/admin/KnowledgeManagement.tsx: estado uploadQueue/uploading/syncing movido al store; uploadFilesToCollection ahora delega
    • src/components/admin/AdminPageClient.tsx: monta el widget al final del layout (visible en todas las pestañas)

    Galería /logos

    • src/app/logos/page.tsx: metadata + layout
    • src/app/logos/LogosGallery.tsx: 24 logos SVG inline con descarga + copia
    • Cada logo es vectorial puro (sin assets externos), escala a cualquier tamaño
    • Botón Descargar genera archivo garbotgpt-<id>.svg
    • Botón Copiar lleva el código SVG al portapapeles
  6. v8.33.8

    📱 TWA Android: AAB generado y firmado

    Generado el proyecto Android TWA (Trusted Web Activity) completo y compilado el AAB firmado para subir a Google Play Store. Bypass de los prompts interactivos de bubblewrap CLI mediante script programático que usa @bubblewrap/core directamente. Keystore creado, SHA-256 fingerprint añadido a /.well-known/assetlinks.json.

    Nuevo

    • 📦 scripts/generate-twa.cjs: generador programático del proyecto Android (bypassa prompts CLI)
    • 🔑 android-twa/android.keystore (alias=android, password=garbotgpt-android-2026)
    • android-twa/app-release-bundle.aab (2.08 MB, firmado, listo para Play Console)
    • 🔐 SHA-256: 83:EB:05:92:15:41:90:CA:00:E5:22:BE:6F:AA:38:9A:CA:45:FC:05:47:9E:43:E1:D6:33:A6:97:35:28:32:0F
    • 🌐 public/.well-known/assetlinks.json con Digital Asset Links verification
    • ⚙️ gradle.properties: heap reducido a 768m + MaxMetaspaceSize=256m (para evitar JVM OOM)
  7. v8.33.7

    🔧 Fix middleware bloqueaba /manifest.json y /.well-known/ + arranque TWA

    El middleware redirigía /manifest.json y /.well-known/assetlinks.json a /auth/login para usuarios no autenticados, rompiendo Lighthouse, PWA install y la verificación Digital Asset Links que necesita la app Android (TWA). Matcher actualizado para excluir todas las rutas estáticas críticas. Setup inicial TWA en marcha (Bubblewrap CLI + JDK 17 + Android SDK instalados).

    Nuevo

    • 📦 public/.well-known/assetlinks.json placeholder (se rellenará con sha256 del keystore Android)
    • 📱 android-twa/ añadido a .gitignore (proyecto Android local, keystore privado no debe commitearse)
    • 🚀 Bubblewrap CLI v1.21 instalado globalmente con JDK 17 + Android SDK
    • ⏭️ Siguiente paso: bubblewrap init para generar el AAB Android publicable en Play Store

    Arreglado

    • 🚫 Fix: manifest.json + .well-known/* + sw.js + site.webmanifest + robots.txt + sitemap.xml ya no se redirigen
    • 🚫 Fix: extensiones .ico .json .webmanifest .xml .txt .mp4 .mp3 .wav .webm .woff .woff2 .ttf también excluidas
  8. v8.33.6

    🎨 Nuevo logo "GarBotGPT" wordmark + Video como "Próximamente"

    Logo actualizado al nuevo diseño "NewLogoV2.png" (wordmark "GarBotGPT" con gradient en la "o", fondo transparente). Regenerados todos los assets PNG: logo, mark, square, favicons (16/32/96), apple-touch-icon, android-chrome 192/512. La feature de Video Generation se marca temporalmente como "Próximamente" (toggle visible pero deshabilitado con badge).

    Nuevo

    • 🛠️ scripts/generate-logo.cjs reescrito: ahora consume NewLogoV2.png en lugar de generar el G monogram con canvas
    • 📦 Regenerados todos los assets: logo.png/transparent/mark/mark-transparent/square + 6 favicons
    • 🎬 Video Generation toggle marcado como "Próximamente":
    • - Visible en menú pero disabled + opacity-50 + cursor-not-allowed
    • - Badge gradient violet→amber "Próximamente"
    • - tooltip "Próximamente disponible" al hover
    • - Pipeline backend completa (queda solo conectar RUNWAY_API_KEY cuando esté listo)

    Mejorado

    • 🎨 NewLogoV2.png como nueva fuente (wordmark transparent 1254×1254)
    • 🎯 Favicons pequeños (≤48px): crop centrado al 55% para enfatizar la gradient "o" (mejor reconocimiento)

    Logo / assets visuales

    • NewLogoV2.png en raíz como source canónica del logo
    • public/logo.png (512×512 transparent) — wordmark
    • public/logo-transparent.png — alias
    • public/logo-square.png (1024 hi-res)
    • public/logo-mark.png (512 con fondo blanco)
    • public/logo-mark-transparent.png
    • public/favicon-{16,32,96}.png (transparent, crop al 55% para tamaños chicos)
    • public/apple-touch-icon.png (180 fondo blanco)
    • public/android-chrome-{192,512}.png (fondo blanco)
    • public/favicon.ico (48 PNG renombrado)
    • src/app/favicon.ico (copia auto-sync para Next App Router)

    Video Generation → "Próximamente"

    • src/components/chat/ChatInput.tsx: el toggle de Video Generation en el menú desktop pasa a disabled + badge "Próximamente"
    • onClick reemplazado por no-op
    • El backend mantiene la pipeline completa para activarla en cuanto pongas RUNWAY_API_KEY en producción
    • Sin breaking changes: meta_json.video_generation sigue persistiendo si llega a ejecutarse
  9. v8.33.5

    🎬 Video Generation — Runway Gen-3 + card embebida

    Feature 5/7 del roadmap. Nueva tool de generación de video usando Runway Gen-3 (text-to-video, 5-10s, 16:9/9:16/1:1). Toggle en el menú del ChatInput debajo de "Generar Imagen". El video se renderiza embebido en una card con descarga + abrir + estados loading/error.

    Nuevo

    • 🎬 Tool video-generation provider-agnostic (Runway/Sora/Veo/Luma)
    • 📦 meta_json.video_generation persistido en el assistant message
    • 🚨 Si falta RUNWAY_API_KEY: status skipped + mensaje en systemPromptAddition
    • 🧪 Typecheck verde

    Mejorado

    • Default: Runway Gen-3 (RUNWAY_API_KEY) con polling 60s + fallback "processing"

    Arreglado

    • 🎨 VideoGenerationCard: header gradient + <video> embebido + descarga + abrir + estados ready/processing/error

    Seguridad

    • 🪪 Toggle "Generar Video" en el menú de tools (sólo si tiene permiso de imageGeneration)

    Nuevo: src/lib/server/chat/tools/video-generation.ts

    • runVideoGenerationTool({ prompt, durationSec, aspectRatio })
    • runRunwayGeneration: POST /v1/text_to_video → poll /v1/tasks/{id}
    • Devuelve { status: ready | processing | error, video_url, thumbnail_url, provider, prompt, duration_s, task_id, error }
    • Sin API key → status: skipped (no bloquea, informa al LLM)

    Nuevo: src/components/chat/VideoGenerationCard.tsx

    • 3 estados: ready (video embebido + downloads), processing (loader), error (rojo + sugerencia)
    • Botón descarga via fetch + Blob + a.click
    • Botón abrir en pestaña nueva

    Integración chat

    • chat-store: videoGeneration boolean + setVideoGeneration
    • src/app/api/chat/route.ts: parámetro video_generation + effectiveVideoGeneration + invocación + persistencia
    • src/components/chat/ChatInput.tsx: toggle "Generar Video" en menú desktop (icono Film)
    • src/components/chat/MessageBubble.tsx: getter videoGenerationMeta + render VideoGenerationCard

    Configuración requerida

    • Env var: RUNWAY_API_KEY (https://app.runwayml.com/account)
    • Pricing aproximado: ~$0.05/segundo de video Gen-3 turbo
    • Sin la env var, la tool devuelve "skipped" + el LLM informa al user
  10. v8.33.4

    📌 Web Capture — Chrome extension + endpoint /api/capture

    Feature 4/7 del roadmap. Extensión de Chrome (Manifest V3) que envía cualquier página web o selección de texto a GarBotGPT con un click derecho. Crea una conversación nueva con el contenido capturado pre-cargado como primer mensaje del usuario.

    Nuevo

    • 📦 Nueva carpeta chrome-extension/ con la extensión completa
    • 🖱️ 3 entradas en context menu: página completa / selección / enlace
    • 🪟 Popup en la toolbar con 3 botones
    • 🔐 Auth vía cookie del navegador (debes estar logueado en ai.garbotgpt.com)
    • 📝 README con install + uso + troubleshooting

    Mejorado

    • Endpoint /api/capture (Next.js route) con fetchPageContent para extraer contenido
    • 🎨 Iconos 16/32/48/128 generados con node-canvas (script reproducible)

    chrome-extension/

    • manifest.json — Manifest V3, host_permissions ai.garbotgpt.com, action popup + icons
    • background.js — service worker con context menus + chrome.action click + badge progress
    • popup.html + popup.js — UI con 3 botones (página/selección/abrir app)
    • generate-icons.cjs — script node-canvas que regenera icons/icon-{16,32,48,128}.png
    • README.md — install / uso / troubleshooting

    src/app/api/capture/route.ts

    • POST endpoint con auth Supabase cookie
    • Body: { url, title?, selection?, full_page? }
    • Si full_page=true, fetcha el HTML via fetchPageContent (cap 6000 chars)
    • Crea conversación con título "📌 <título>" + participant entry
    • Inserta primer message del user con: URL + selección + contenido + meta_json captured_*
    • sources_json incluye chunk con source_type: web para el SourcesPanel
    • Devuelve { conversation_id, url: "/chat/<id>" }
    • maxDuration 25s (fetchPageContent puede tardar)

    Flujo de usuario

    • 1. Instala la extensión (chrome://extensions → cargar descomprimida → chrome-extension/)
    • 2. Estás logueado en ai.garbotgpt.com
    • 3. Click derecho en cualquier web → "Enviar página a GarBotGPT"
    • 4. La extensión llama POST /api/capture con cookie
    • 5. Backend crea conv + 1er mensaje con el contenido + redirige al chat
    • 6. El AI ve el contenido y puede analizarlo/resumir/responder preguntas
  11. v8.33.3

    ✨ Smart Suggestions v2 — sugerencias proactivas con anti-spam

    Feature 3/7 del roadmap. La WelcomeScreen ahora muestra 2-3 cards con sugerencias proactivas generadas por LLM basándose en el historial reciente del usuario (últimos 7 días). Click → crea conversación nueva con el prompt pre-cargado.

    Nuevo

    • 🧠 Backend lee conversaciones recientes (últimos 7 días, hasta 12 convs) y resume con últimos mensajes user/assistant
    • Anti-spam: dismissal persistido en localStorage por hash
    • 😴 Fatigue: 2 dismissals/día → silencio total las próximas 24h
    • 👁️ Skip si está en streaming (no distraer mid-respuesta)
    • 📝 Draft pickup: click envía el prompt al ChatInput vía sessionStorage

    Mejorado

    • LLM gpt-4o-mini genera 2-3 sugerencias variadas (continuar, revisar, crear)
    • 💾 Cache 24h por usuario en memoria → 1 LLM call/día máximo (coste controlado)
    • 🎨 Cards bonitas en grid 2-col con icono sparkle + título + razón

    Nuevo: src/lib/server/proactive-suggestions.ts

    • loadRecentConversations: query convs activas + sus últimos 2 user messages + 1 assistant
    • buildUserPrompt: estructura el contexto temporal con fechas
    • callLlm: gpt-4o-mini con response_format JSON estricto, parsea + valida
    • Cache in-memory Map per-user, TTL 24h

    Nuevo: src/app/api/suggestions/proactive/route.ts

    • GET endpoint, query param ?force=1 para saltar cache (debug)
    • maxDuration 15s (LLM puede tardar)

    Nuevo: src/components/chat/ProactiveSuggestions.tsx

    • Renderiza en WelcomeScreen encima del ChatInput
    • localStorage para dismissals (hash del texto)
    • Fatigue counter (2 dismissals/24h → hide all)
    • Click → crea conv + sessionStorage draft → router push

    Integración con ChatInput existente

    • Draft pickup desde sessionStorage tiene prioridad sobre localStorage
    • Key: garbotgpt:draft:<convId>
    • Se consume y limpia tras leer
  12. v8.33.2

    🎨 Splash screen 2s + fix PWA start_url para iOS

    Pantalla de bienvenida con logo + animaciones suaves en cold-start (una vez por sesión). Plus fix del quirk de iOS donde añadir la PWA desde /auth/login dejaba al user atascado en login — ahora si hay sesión activa, redirige a /chat automáticamente.

    Nuevo

    • 🎬 SplashScreen.tsx — logo + glow pulsante + spinner + fade-out 400ms (2s total)
    • 📦 sessionStorage flag para mostrar solo en cold-start (no en cada navegación)
    • Respeta prefers-reduced-motion (sin animaciones)

    Mejorado

    • 🔧 manifest.json: start_url con ?source=pwa para tracking, id="/", display_override=[standalone, minimal-ui]
    • 🎨 themeColor unificado a #7C3AED (era #8B5CF6, ahora coincide con el manifest)

    Arreglado

    • 🐛 Override: `?splash=1` fuerza el splash para debug
    • 🍏 Fix PWA iOS: si /auth/login se abre con sesión activa → redirect a /chat (o nextPath)

    Nuevo: src/components/ui/SplashScreen.tsx

    • Mesh gradient backdrop con paleta del logo (indigo/magenta/ámbar)
    • Logo 100-120px con scale-up + glow pulsante
    • Spinner sutil debajo del wordmark
    • Fade-out 400ms tras 2000ms
    • sessionStorage key: garbotgpt:splash:shown:v1

    Fix PWA quirk de iOS

    • src/app/auth/login/page.tsx: useEffect que llama supabase.auth.getSession() al mount; si hay session.user, router.replace(nextPath)
    • public/manifest.json: start_url "/?source=pwa", id "/", display_override
    • src/app/layout.tsx: themeColor unificado a #7C3AED

    Por qué pasaba el bug PWA

    • iOS Safari respeta el `start_url` del manifest cuando lanza el PWA desde home screen
    • PERO en algunos casos guarda como bookmark la URL exacta donde se hizo "Añadir a pantalla de inicio"
    • Si añadiste desde /auth/login, el PWA abría en /auth/login aunque hubieras sido logueado
    • Fix: detectar sesión activa en login → redirect inmediato
  13. v8.33.1

    ✨ Custom GPTs / Saved Workflows — plantillas reutilizables

    Feature 2/7 del roadmap. Crea plantillas con nombre + icono + system prompt + modelo + tools por defecto + starter prompts. Aparecen en la sección "Mis GPTs" del sidebar. Activar un GPT crea una conversación nueva con su config aplicada automáticamente (system prompt inyectado, tools forzados, modelo preseleccionado).

    Nuevo

    • 🆕 Columna `conversations.active_gpt_id` (FK con ON DELETE SET NULL)
    • 🔌 API: GET /api/gpts, POST /api/gpts, PATCH /api/gpts/[id], DELETE /api/gpts/[id]
    • 💾 Zustand store `useCustomGptsStore` con CRUD + modal state
    • 📋 Sidebar: sección "Mis GPTs" con icon + nombre, botón "+", edit on hover
    • 🚀 Activar GPT: aplica modelo + tools + crea conv con active_gpt_id
    • 🧠 Chat route: carga active_gpt, inyecta su system_prompt como bloque prioritario, fuerza tools_json marcados, RPC increment_usage
    • 🧪 Typecheck verde

    Mejorado

    • 🎨 Editor modal completo: name, descripción, emoji, color (12 paletas), system prompt, modelo, 9 toggles de tools, hasta 8 starters

    Seguridad

    • 🆕 Nueva tabla `custom_gpts` con RLS per-user + función increment_custom_gpt_usage

    Nueva infrastructure

    • supabase/migrations/077_custom_gpts.sql (tabla + RLS + función + columna en conversations)
    • src/lib/types.ts: CustomGpt + CustomGptToolsConfig + Conversation.active_gpt_id
    • src/app/api/gpts/route.ts + [id]/route.ts
    • src/store/custom-gpts-store.ts
    • src/components/gpts/CustomGptEditorModal.tsx (~400 lineas)
    • src/components/sidebar/CustomGptsList.tsx (~170 lineas)

    Integración con chat existente

    • src/components/sidebar/sleek/SidebarSleek.tsx: sección "Mis GPTs" arriba de Carpetas
    • src/components/chat/ChatShell.tsx: <CustomGptEditorModal /> global
    • src/store/chat-store.ts: createConversation acepta options.activeGptId
    • src/app/api/conversations/route.ts: pasa active_gpt_id al INSERT
    • src/app/api/chat/route.ts: carga active_gpt, aplica system_prompt + tools_json + increment_usage

    Próximos features del roadmap v8.33.x

    • v8.33.2 — Smart Suggestions v2 (proactivas con anti-spam)
    • v8.33.3 — Web Capture (Chrome extension + endpoint /api/capture)
    • v8.33.4 — Video Generation (Runway/Sora/Veo)
    • v8.33.5 — Voice Cloning (ElevenLabs per agent)
    • v8.34.0 — API pública (api.garbotgpt.com)
  14. v8.33.0

    ⚡ Slash commands inline (/) — comandos rápidos en el ChatInput

    Al escribir "/" al inicio del input aparece un menú flotante con comandos rápidos (summarize, explain, improve, translate, code, clear, help). Navegación con ↑↓ + Enter o Tab. Cada comando construye un prompt inteligente y lo envía automaticamente al chat. Feature #1 del roadmap v8.33.x.

    Nuevo

    • 🔍 Filtrado por substring: "/sum" deja solo /summarize
    • ⌨️ Keyboard nav: ↑↓ navegar, Enter o Tab para seleccionar, Esc salir
    • 🎯 Dark mode + accent violet, accesible
    • 📝 /help muestra toast con la lista completa
    • 🚫 Enter normal NO envía "/comando" crudo — el menú lo intercepta
    • 🧪 Typecheck verde

    Mejorado

    • 7 comandos built-in: /summarize, /explain, /improve, /translate, /code, /clear, /help
    • 🎨 Menú flotante con icon + descripción + arg hint

    Nuevo: src/components/chat/SlashCommandMenu.tsx

    • Detecta "/" al inicio del input + filtra por substring del query
    • Cada SlashCommandDef tiene name, trigger, description, icon, argHint, buildPrompt()
    • Acciones especiales (clear, help) gestionadas por el padre vía cmd.special
    • Keyboard navigation con event listener global (capture phase)
    • Position above|below (default above)

    src/components/chat/ChatInput.tsx

    • Textarea ahora envuelto en <div className="relative min-w-0 flex-1"> para que el menú floate encima
    • handleSlashCommandSelect callback que construye QueuedMessageItem y lo envía via handleSend
    • handleKeyDown bloquea Enter cuando el input es un comando incompleto (sin match exacto)
    • /help → toast informativo con todos los comandos
    • /clear → vacía el input

    Próximos pasos del roadmap v8.33.x

    • v8.33.1+ — Saved Workflows / Custom GPTs (templates de prompt + tools + memoria)
    • v8.33.x — Smart Suggestions v2 (proactivas con anti-spam)
    • v8.33.x — Web Capture (Chrome extension + endpoint)
    • v8.33.x — Video Generation (Runway/Sora)
    • v8.33.x — Voice Cloning (ElevenLabs per agent)
    • v8.34.0 — API pública (api.garbotgpt.com)
  15. v8.32.7

    🌐 Migración de dominio: gia.gesem.es → ai.garbotgpt.com

    Actualizadas todas las referencias hardcodeadas al dominio antiguo (gia.gesem.es y gia.fgarola.es) por el nuevo ai.garbotgpt.com. Esto afecta los fallback URLs cuando faltan los env vars de producción: OAuth redirects (Google, Microsoft, Spotify, GitHub, Monday), invite emails de registro, auth callbacks. El comportamiento normal sigue priorizando NEXT_PUBLIC_APP_URL / NEXT_PUBLIC_SITE_URL si están definidos.

    Nuevo

    • 🔗 src/lib/app-base-url.ts: DEFAULT_FALLBACK_ORIGIN actualizado
    • 🔐 src/lib/integration-oauth-state.ts: PRODUCTION_FALLBACK actualizado (afecta TODOS los OAuth callbacks)
    • 📧 src/app/api/admin/users/create/route.ts: invite emails y action_links
    • 📧 src/app/api/admin/registration-requests/route.ts: redirect tras aprobar registro
    • 🎙️ src/app/api/voice/transcribe/route.ts: vocabulary hint actualizado
    • 📝 .env.example: ejemplos actualizados (Spotify, GitHub, Monday redirect URIs)

    ⚠️ Pasos manuales necesarios (no automatizables)

    • 1. Vercel/hosting: actualizar env vars NEXT_PUBLIC_APP_URL y NEXT_PUBLIC_SITE_URL → https://ai.garbotgpt.com
    • 2. Google Cloud Console → OAuth 2.0 Client → Authorized redirect URIs: añadir https://ai.garbotgpt.com/api/integrations/google/callback
    • 3. Microsoft Azure Portal → App registrations → Redirect URIs: añadir https://ai.garbotgpt.com/api/integrations/microsoft/callback
    • 4. Spotify Dashboard → App settings → Redirect URIs: añadir el callback correspondiente
    • 5. GitHub OAuth App → Authorization callback URL: actualizar
    • 6. Monday CRM app → Redirect URI: actualizar
    • 7. Supabase Dashboard → Authentication → URL Configuration: Site URL = https://ai.garbotgpt.com + Additional Redirect URLs incluir el callback
    • Hasta que estos cambios estén hechos en cada consola, los nuevos OAuth flows seguirán fallando aunque el código apunte al dominio correcto.

    Notas

    • Los cookies internos (gia_google_integration_state, etc.) NO se renombran — son identificadores internos, no dominios.
    • Las referencias a tika.fgarola.es se mantienen — es un servicio backend separado (Apache Tika), no la app.
    • src/lib/changelog.ts mantiene las menciones históricas al dominio antiguo (historial inmutable).
  16. v8.32.6

    🎨 Logo v2 super pro + PNG transparente + suite favicon completa

    Rediseño mayor del logo: gradiente iridiscente 5-stop (purple → violet → magenta → coral → ámbar), G refinada con sparkle accent estilo Gemini/Claude, depth real con inner shadow + highlight cenital, y suite completa de assets: 5 variantes de logo + 7 favicons regenerados. Manifest actualizado a marca GarBotGPT (antes seguía con "GIA").

    Nuevo

    • 🌈 Gradiente iridiscente 5 stops: #4F46E5 indigo → #7C3AED violet → #EC4899 magenta → #F97316 coral → #FBBF24 ámbar
    • Sparkle accent (4-point star) dentro del counter de la G — toque AI/intelligence
    • 🌑 Inner shadow real en el bottom del mark (depth 3D, no solo highlight top)
    • 🎯 G refinada: gap 52° (más estrecho), crossbar 62% del radio, rounded caps
    • 🪟 5 variantes de logo:
    • • logo.png (512, fondo blanco)
    • • logo-transparent.png (512, FONDO TRANSPARENTE)
    • • logo-mark.png (512, solo mark)
    • • logo-mark-transparent.png (512, solo mark transparent)
    • • logo-square.png (1024 hi-res)
    • 📱 Suite favicon completa regenerada con el nuevo design:
    • • favicon-16x16.png, favicon-32x32.png, favicon-96x96.png (transparent)
    • • apple-touch-icon.png (180×180, fondo blanco)
    • • android-chrome-192x192.png, android-chrome-512x512.png
    • • favicon.ico (también copiado a src/app/favicon.ico para Next App Router)
    • 📦 manifest.json: nombre "GarBotGPT" (antes "GIA"), theme #7C3AED, iconos correctos
    • 📦 site.webmanifest: actualizado a GarBotGPT

    Nuevos assets generados

    • public/logo.png — full logo, fondo blanco
    • public/logo-transparent.png — full logo, alpha real
    • public/logo-mark.png — mark only
    • public/logo-mark-transparent.png — mark only transparent
    • public/logo-square.png — hi-res 1024
    • public/favicon-16x16.png — transparent
    • public/favicon-32x32.png — transparent
    • public/favicon-96x96.png — transparent (nuevo)
    • public/apple-touch-icon.png — 180×180
    • public/android-chrome-192x192.png
    • public/android-chrome-512x512.png
    • public/favicon.ico — 48×48 PNG renombrado
    • src/app/favicon.ico — copia auto-sincronizada para Next

    Manifests actualizados

    • public/manifest.json: name "GarBotGPT", theme #7C3AED, icons → android-chrome-* (purposes any + maskable)
    • public/site.webmanifest: name "GarBotGPT", theme #7C3AED

    scripts/generate-logo.cjs

    • Refactor completo: 1 script genera los 13 assets
    • Soporte transparent para PNG + variants
    • Auto-copia favicon.ico a src/app/ para Next App Router
    • Tokens de diseño centralizados (palette + gradient + glyph dims)
  17. v8.32.5

    🐛 Fix: Network RAG ya no se auto-activa por menciones del assistant

    Cuando un turno previo (sobre todo Deep Research) mencionaba archivos de red en su respuesta (ej: Manual_Interno_GESEM.txt), el SIGUIENTE turno corto del usuario auto-activaba network_drive_rag aunque el usuario no lo hubiera pedido. La intención de consultar la unidad de red debe venir de lo que el usuario escribió, no de lo que el assistant mencionó en respuestas anteriores.

    Nuevo

    • 🚫 extractRecentNetworkFileReferences ahora solo escanea mensajes del usuario
    • 🗑️ Eliminado el boost x1.5 para mensajes del assistant (era el responsable principal)
    • Si el usuario escribe "consulta el Manual_X.pdf" → network RAG se activa correctamente
    • Si el assistant menciona "Manual_X.pdf" en su respuesta → NO contamina el siguiente turno
    • 🧪 Typecheck verde

    Mejorado

    • 📝 Nota: web_search y deep_research badges siguen siendo "sticky" (persisten entre turnos por diseño). Si no quieres usarlos en un turno, desactivalos manualmente en el menú.

    src/lib/server/chat/helpers/network-rag-helpers.ts

    • extractRecentNetworkFileReferences: guard `if (message.role !== "user") continue`
    • roleBoost eliminado (ya no hay distinción usuario/assistant — solo usuario cuenta)
    • recencyBoost se mantiene como única señal de ranking
  18. v8.32.4

    🎨 Logo nuevo nivel diseñador: app-icon G monogram + wordmark

    Logo completamente rediseñado para GarBotGPT. Reemplaza el wordmark plano "garbotgpt" por una composición premium: app-icon rounded square (estilo iOS, radius 22.5%) con gradiente indigo→magenta→ámbar, "G" custom blanca con stroke geométrico (arc abierto + crossbar) dentro del mark, drop shadow suave para elevación, highlight cenital sutil, y wordmark "GarBotGPT" debajo en Inter Semibold con letter-spacing optical.

    Nuevo

    • 📱 App-icon mark estilo iOS premium (rounded square 22.5% radius)
    • ✍️ G custom dibujada con stroke-geometry: 304° arc + crossbar inner, rounded caps
    • 🌫️ Drop shadow indigo suave (premium feel) + highlight cenital top-down
    • 🎯 Wordmark "GarBotGPT" en Inter Semibold con tracking optical -0.025em
    • 📦 3 variantes generadas: logo.png (512, full), logo-square.png (1024, hi-res), logo-mark.png (512, mark sin wordmark)
    • 🛠️ Script reproducible (scripts/generate-logo.cjs) — edita y regenera con `node scripts/generate-logo.cjs`

    Mejorado

    • 🎨 Gradiente 3-stop sofisticado: #5B47FF indigo → #EC4899 magenta → #FBBF24 ámbar (vs. el flat magenta-naranja del antiguo)

    Composición del logo

    • Mark rounded square con app-icon proportions (iOS standard)
    • Drop shadow: dy=4%, blur=13% del size, color del propio gradient
    • Inner stroke 1.2px rgba(0,0,0,0.08) para definir borde
    • G glyph: stroke 11.5% del mark size, white, rounded caps
    • G opening: 56° gap a la derecha (28° arriba + 28° abajo del eje X)
    • Crossbar inner: 55% del radio, alineado con el borde inferior de la apertura

    Outputs

    • public/logo.png (512×512) — logo completo (mark + wordmark)
    • public/logo-square.png (1024×1024) — versión hi-res para redes sociales
    • public/logo-mark.png (512×512) — solo el mark, sin texto, para favicons/avatares
    • public/logo.svg — fuente vectorial editable
    • scripts/generate-logo.cjs — generador reproducible (node-canvas)
  19. v8.32.3

    🎨 Logo nuevo: "garbotgpt" con la estética del antiguo "gia"

    Reemplazado el logo "gia" antiguo por uno nuevo de "GarBotGPT" manteniendo exactamente la misma estética visual: charcoal lowercase bold + dot icónico con gradiente magenta→naranja. El nombre se distribuye en 2 líneas ("garbot" / "gpt") para preservar la compacidad del square format, y el dot del acento se coloca sobre la "o" central de "garbot" como homenaje al dot del "i" del logo original.

    Nuevo

    • Misma tipografía: Arial Black 900, letter-spacing apretado
    • 🔘 Dot iconico sobre la "o" de "garbot" — posición calculada midiendo el ancho del texto
    • 📄 SVG fuente en public/logo.svg para futuras ediciones manuales
    • 🛠️ scripts/generate-logo.cjs reproducible — regeneración con `node scripts/generate-logo.cjs`

    Mejorado

    • 🎨 Logo PNG 512×512 generado vía script con node-canvas
    • 🎯 Misma paleta: charcoal #2a2a2e + gradiente magenta→coral→naranja

    Archivos nuevos / reemplazados

    • public/logo.png — reemplazado (gia → garbotgpt)
    • public/logo.svg — nuevo (fuente vectorial editable)
    • scripts/generate-logo.cjs — nuevo (script reproducible)
  20. v8.32.2

    ✨ Sources estilo OpenWebUI + 2 bugs (mobile selector + auto-model al editar)

    Reemplazada la lista plana de chips de fuentes al final de cada mensaje del assistant por una card colapsable estilo OpenWebUI: pill con favicons apilados + contador, click para expandir la lista numerada con cada fuente clicable. Plus 2 bugfixes: (1) los modelos Ollama no se mostraban como seleccionados al clicarlos en el selector móvil, y (2) al editar un mensaje, la badge del modelo mostraba el predefinido en lugar del auto-elegido por el auto-router.

    Nuevo

    • 🔗 SourcesPanel: pill colapsable con stack de 3 favicons + "N fuentes" + chevron
    • 📜 Expandido: lista numerada con [1] [2] [3]… cada fuente clicable (web → URL, RAG → file preview, network → download inline)
    • Dark mode soportado, accesible (aria-expanded, keyboard)
    • 🧪 Typecheck verde

    Mejorado

    • 🎨 Inspirado en Citations.svelte de OpenWebUI (favicons overlapping + accent color por tipo de fuente)

    Arreglado

    • 🐛 Fix mobile selector: comparación isSelected extendida a m.id || m.config_id || m.provider_model_id (como ya hacía MobileHeader). Ollama models ahora muestran check al seleccionarlos.
    • 🐛 Fix auto-model al editar: persistir publicModelId (modelo realmente usado tras auto-routing) en lugar del model crudo del body. La badge del mensaje regenerado ahora refleja el modelo auto-elegido.

    Nuevo: src/components/chat/SourcesPanel.tsx

    • Dedupe automático por (kind + key) — RAG dupes del mismo file_id se consolidan
    • Web → favicon de google.s2 + abre en pestaña nueva con noopener
    • RAG → icono FileText emerald + onClick → openFilePreview(file_id)
    • Network → icono HardDrive purple + abre /api/network-files/<id>/download?inline=1
    • Pill con 3 favicons + "+N" badge si > 3 fuentes
    • Lista numerada [1] [2]…, accent color por tipo, line-clamp 2 en título

    src/components/chat/MessageBubble.tsx

    • Eliminada la grid plana de chips inline (web blue, rag emerald, network purple).
    • Sustituida por <SourcesPanel sources={sources} onOpenFile={openFilePreview} />.

    src/components/chat/Header.tsx

    • Línea 636 (mobile bottom sheet): isSelected ahora comprueba m.id || m.config_id || m.provider_model_id (antes solo m.id).

    src/app/api/chat/route.ts

    • Líneas 6681-6687 (regenerate principal): model: model → model: publicModelId.
    • Líneas 5799-5812 (regenerate del network_full_dump): mismo cambio.
    • message_versions inserts también usan publicModelId.
  21. v8.32.1

    🐛 Fix bugs al editar mensaje: PDFs de red fantasma + respuesta solapada

    Dos bugs al editar un mensaje ya enviado: (1) reaparecían los PDFs de unidad de red como fuentes (mismo bug que arreglamos en v8.31.8 pero por otro path no cubierto). (2) Solapamiento — la respuesta vieja del assistant reaparecía sobre el chat mientras la nueva se generaba, especialmente notable con web search por su mayor latencia. El bug afectaba a TODAS las herramientas y al modo sin herramientas — web search solo lo hacía más visible por el tiempo extra.

    Nuevo

    • 👁️ Mensaje solapado: poll de 15s en ChatArea pisaba el stream local con la versión vieja de la DB
    • 🎯 Causa raíz: durante un regenerate, el server actualiza el assistant message AL FINAL del stream, no durante. Cualquier loadMessages mientras streamea trae la versión vieja.
    • 🧪 Typecheck verde

    Mejorado

    • Mismo fix para el fast-sync de 250ms en conversaciones compartidas

    Arreglado

    • 🚫 Network drive: 2 puntos de auto-enable adicionales fixed (line 2342, 2347 de route.ts) que NO respetaban regenerate_message_id

    src/app/api/chat/route.ts

    • Línea 2332: `if (!regenerate_message_id && ...)` añadido al guard que escaneaba conversación histórica buscando refs a PDFs.
    • Línea 2352: `if (!regenerate_message_id && ...)` añadido al forced-enable basado en `effectiveExplicitFileReferences`.

    src/components/chat/ChatArea.tsx

    • Poll de 15s (5s si hay task pendiente): si isStreaming && streamingConversationId === activeConversationId → skip refetch.
    • Fast-sync de 250ms (cuando hay foreign user awaiting assistant): mismo guard.
  22. v8.32.0

    🔬 Deep Research reconstruido — multi-step plan-visible (MVP)

    Paso 2/2 de la reconstrucción de Deep Research. Nueva arquitectura: planner (LLM barato genera 3-5 sub-preguntas) → searcher (Tavily en paralelo) → scraper (fetchPageContent extrae texto) → synthesizer (inyecta fuentes citables [1][2] en el systemPrompt). El plan + fuentes consultadas se renderizan en una card colapsable encima de la respuesta.

    Nuevo

    • 🎯 Planner: gpt-4o-mini con response_format JSON → goal + rationale + 3-5 sub-queries
    • 🔍 Searcher: Tavily paralelo (3-4 resultados por sub-query) + dedupe round-robin
    • 📖 Scraper: fetchPageContent con concurrency 4, timeout 12s/URL, cap 4.5k chars
    • 🧠 Synthesizer: systemPrompt con plan + 6-8 fuentes [1][2]… + instrucciones de citación
    • 📦 Persistencia: meta_json.deep_research = { plan, sources, telemetry } en el assistant message
    • 🟡 Mode "exhaustive" pide 4 sub-queries y 8 URLs (vs 3/6 del modo "standard")
    • 🧪 Typecheck verde, ~600 líneas nuevas

    Mejorado

    • 🎨 UI: DeepResearchCard colapsable (header con goal + chips de stats; abierta muestra rationale + plan + lista de fuentes clicables)

    Nuevos archivos (src/lib/server/chat/tools/deep-research/)

    • types.ts — DeepResearchPlan, DeepResearchSourceLite, DeepResearchEvent, DeepResearchResult
    • planner.ts — generateDeepResearchPlan() + fallback determinista si el LLM falla
    • searcher.ts — searchSubQueries() paralelo + dedupeAndLimit() round-robin
    • scraper.ts — scrapeCandidates() con worker pool de 4 + timeout 12s
    • index.ts — runDeepResearch() orquestador con event emitter

    Nuevo componente UI

    • src/components/chat/DeepResearchCard.tsx — card colapsable amarillo-ámbar
    • Header: icono FlaskConical + goal truncado + chips (sub-preguntas, fuentes, duración)
    • Cuerpo (abierta): rationale italic, lista numerada de sub-queries, grid de fuentes con hostname + título + snippet
    • Footer telemetry: URLs leídas / candidatas / k-chars

    Wire-up en route.ts

    • Import runDeepResearch del nuevo módulo.
    • Ejecutado donde estaba el placeholder de v8.31.9 (antes del DB query tool).
    • systemPrompt += drResult.systemPromptAddition (incluye fuentes citables [1][2]…).
    • meta_json.deep_research persistido si DR completó.
    • recordTool('deep_research', start, status, detail) para telemetría.

    MessageBubble.tsx

    • getDeepResearch() extractor de meta_json.deep_research.
    • useMemo para evitar re-parsing en cada render.
    • <DeepResearchCard> renderizado encima del MusicPlayer y del contenido principal.
  23. v8.31.9

    🧨 Deep Research desmantelado (paso 1 de la reconstrucción)

    Paso 1/2: eliminado todo el pipeline antiguo de Deep Research (planificación con sub-preguntas, cache, evidence matrix, SSE de progreso, componentes de UI). El toggle del menú sigue visible pero ahora actúa como un "Web Search extendido". En v8.32 se reconstruye con arquitectura multi-step plan-visible (planner → sub-queries → scrape → synthesize → citations) que ya quedó decidida.

    Nuevo

    • 🗑️ Eliminados 3 componentes: DeepResearchProgress, DeepResearchInlineViewport, DeepResearchFloatingWindow
    • 🗑️ Eliminado endpoint SSE /api/chat/research-events y lib/chat/research-live-events.ts
    • 🗑️ Eliminado openResearchEventsSource + researchEventsSourceRef de ChatInput.tsx
    • 🎚️ Toggle "Deep Research" sigue visible — al activarlo se comporta como Web Search extendido (sin las directivas DR)
    • 🧪 Typecheck verde

    Mejorado

    • 🗑️ Eliminado el bloque DR de route.ts (~350 líneas: planning, follow-up searches, ranking, cache, evidence matrix)
    • 🗑️ Eliminado deepResearchProgress + setDeepResearchProgress de ui-store

    Archivos eliminados

    • src/lib/chat/research-live-events.ts
    • src/app/api/chat/research-events/route.ts
    • src/components/chat/DeepResearchProgress.tsx
    • src/components/chat/DeepResearchInlineViewport.tsx
    • src/components/chat/DeepResearchFloatingWindow.tsx

    route.ts

    • Bloque DR (lines ~5186-5514) → comment placeholder.
    • publishLiveResearchEvent → no-op stub (web-search.ts y youtube.ts siguen llamándolo sin efectos).
    • reset call al inicio del request eliminado.
    • Imports de research-helpers reducidos a las utilidades aún en uso fuera del DR.

    research-helpers.ts (NO eliminado)

    • Se mantiene porque web-search.ts y youtube.ts lo importan.
    • route.ts conserva imports de rankWebSources, runWithConcurrency, parseRerankScores, buildFocusedResearchQuery, extractYouTubeVideoIds, etc.
    • En v8.32 las funciones DR-only de aquí se podrán retirar.
  24. v8.31.8

    🐛 Fix: PDFs de red fantasma + mensaje desaparece en Web Search

    Dos bugs arreglados: (1) la IA inyectaba PDFs de unidad de red como fuentes en respuestas que NO los pedían (ej: "hazme una imagen de Barcelona" → adjuntaba 01-26-FerranGarola.pdf, 02-25-FerranGarola.pdf). (2) Al enviar mensaje desde Welcome con Búsqueda Web activa, el mensaje del usuario desaparecía durante varios segundos antes de que la IA respondiera.

    Nuevo

    • 🚫 Eliminado el auto-enable global de network_drive_rag (cualquier mensaje con 3+ palabras lo activaba si el user tenía drives sincronizados)
    • 🎯 Ahora network_drive_rag respeta solo el flag explícito del cliente (el client ya hace intent detection via hasNetworkDriveIntent)
    • 👁️ Optimistic user message se preserva al cambiar de activeConversation si pertenece a la nueva conv
    • 🧪 Typecheck verde

    Mejorado

    • ⏱️ Especialmente notable en web search por su latencia mayor — antes se veía un gap visual de 5-15s

    src/app/api/chat/route.ts (líneas ~1717-1741)

    • Eliminado el bloque que auto-activaba effectiveNetworkDriveRag basándose en hasInput + 3+ palabras + drives sincronizados.
    • Reemplazado por un comentario explicativo. El client (ChatInput.handleSend, WelcomeScreen.handleSend) ya hace hasNetworkDriveIntent() y solo manda network_drive_rag=true cuando la frase realmente sugiere consultar la red.

    src/store/chat-store.ts (setActiveConversation)

    • Antes: `messages: []` borraba TODO al activar una nueva conversación.
    • Ahora: preserva los mensajes optimistic_local que pertenecen a la nueva conv (filtrados con isOptimisticLocalMessage).
    • mergeServerMessagesWithOptimistic + dedupeMessagesByContentWindow ya manejan los duplicados cuando el servidor responde con la versión persistida.
  25. v8.31.7

    📱 Music player: versión móvil super-adaptada

    Bloque CSS @media (max-width: 520px) y un fallback (max-width: 360px) que reescriben la card del reproductor para pantallas pequeñas: cover centrada, controles touch-friendly (≥44px), waveform compacto, crossfade oculto, descripción y greeting ocultos, playlist con filas reducidas y scroll corto.

    Nuevo

    • 🎯 Cover centrada con max-width 230px (200px en ≤360px)
    • 👆 Botón play 64px + secundarios 44px — todos los tap targets ≥44px
    • 🎚️ Crossfade oculto en móvil (poco usado, libera espacio)
    • 🚫 Sin parallax 3D en touch — evita ángulos raros con tap-drag
    • 🔍 Botón fullscreen del cover siempre visible (no hay hover)
    • 📜 Playlist max-height 320px (260px en ≤360px), filas 38px
    • 🔇 Descripción y greeting del footer ocultos (recuperan vertical)
    • 〰️ Waveform 44px (vs 56px desktop) con padding tap-area 12px

    Mejorado

    • 🎨 Topbar minimalista: sin source-tag, sin subtitle del brand

    src/components/chat/MusicPlayer.tsx

    • Nuevo bloque @media (max-width: 520px) con ~60 reglas mobile.
    • Bloque adicional @media (max-width: 360px) para ultra-narrow.
    • No requiere cambios de JSX: solo CSS.
  26. v8.31.6

    🎤 +14 canciones Suno de Ferran Garola en el music player

    Añadidas las 14 pistas de la playlist Suno (ad3cf70f-…) de Ferran Garola al DEFAULT_PLAYLIST. Los MP3 se sirven directamente desde cdn1.suno.ai con CORS abierto.

    Nuevo

    • 🎵 Rumba de Verano, Baila Hasta el Sol, Ella No Dice Nada
    • 🎵 La Chica del Club, Silencio de Verano, Qué Nos Está Pasando
    • 🎵 Corazón Traicionero, Fiesta Portuguesa, Costa Dorada
    • 🎵 No pares de Bailar, A ti, Corazón Partido
    • 🎵 Vem Encosta Devagar, Qué Está Pasando
    • 🌐 URLs verificadas (200 OK + Access-Control-Allow-Origin: *)
    • 🖼️ Covers desde cdn2.suno.ai (image_<id>.jpeg)
  27. v8.31.5

    🎶 Music player: arreglado el corte a 7s + waveform mucho mas vivo

    Bug crítico: el reproductor se detenía a los ~7 segundos. Causa: el useEffect de MusicPlayer dependía de `initialPlaylist`, cuya referencia cambia cada vez que el padre (MessageBubble) re-renderiza tras refrescar el mensaje del stream — la cleanup ejecutaba audio.pause() + audio.src = "". Ahora el efecto depende solo de `playerId` (message.id es estable). Además, la waveform ahora baila con todas las barras y múltiples frecuencias superpuestas (rápida + lenta + flicker) para parecerse a audio real.

    Nuevo

    • 🎵 useEffect deps reducidas: [initialPlaylist, crossfadeMs, playerId] → [playerId]
    • 🌊 Waveform: las 56 barras bailan (antes solo 4 cerca del playhead)
    • 🎚️ Amplitud proporcional a la distancia al playhead (max cerca, residual lejos)

    Mejorado

    • 🔊 3 frecuencias mezcladas: rápida (90ms), lenta (230ms), flicker (55ms)
    • Eliminado `transition: height 0.12s` para que la danza sea fluida (RAF la maneja)
    • will-change: height + min-height: 4px (mas dinámico visualmente)

    Arreglado

    • 🛑 Fix: audio ya no se detiene a los ~7s por la cleanup del useEffect

    src/components/chat/MusicPlayer.tsx

    • updateWavefill: combina sin(now/90) + sin(now/230) + sin(now/55) por barra.
    • proximityBoost: factor 0.3-1.0 según distancia al playhead.
    • CSS: removido transition de height; gestionado por RAF directo.
    • min-height 6px → 4px para permitir picos más expresivos.
  28. v8.31.4

    🎵 Reproductor de música ahora aparece como chip activo

    Al activar la herramienta "Reproductor de música" desde el menú del ChatInput, ya aparece su chip rosa en el composer y se cuenta en el badge "N actives". Antes el toggle se marcaba con check pero no se reflejaba ni en la cuenta ni en los chips visibles.

    Nuevo

    • 🎵 musicPlayer añadido al array activeToolsCount
    • 🩷 Chip rosa con icono <Music> y botón X para desactivar
    • 🧹 setMusicPlayer(false) añadido a clearActiveTools

    Mejorado

    • Sin cambios de comportamiento del propio reproductor — solo UI
  29. v8.31.3

    📎 Cite mode siempre activo + toggle eliminado del Header

    El botón de "Citar fuentes" (icono Quote) se ha eliminado del Header. citeMode queda activo por defecto (su default ya era true en el store) — las respuestas con RAG citan siempre las fuentes recuperadas sin que el usuario tenga que activarlo manualmente.

    Nuevo

    • 🗑️ Botón Quote eliminado del Header
    • citeMode default sigue siendo true (siempre cita fuentes)
    • 🧹 Removido citeMode/setCiteMode del destructuring de useChatStore
    • 🧹 Removido Quote del import de lucide-react
  30. v8.31.2

    📚 RAG siempre activo + toggle eliminado del Header

    El sistema RAG ahora está activado por defecto en modo "assisted" y el toggle de RAG (off/assisted/strict) se ha eliminado del Header del chat. El botón de "citar fuentes" sigue visible para alternar citaciones.

    Nuevo

    • 🟢 ragMode default: "off" → "assisted" (siempre activo)
    • 🗑️ Toggle RAG eliminado del Header (chat desktop y mobile)
    • 📝 Botón citeMode ahora siempre visible (antes solo si ragMode !== "off")
    • 🧹 Limpiados imports y destructuring de ragMode/setRagMode en Header

    src/store/chat-store.ts

    • Default ragMode pasa de "off" a "assisted".
    • Conversation loader sigue respetando conv.rag_mode persistido.

    src/components/chat/Header.tsx

    • Eliminado el botón <BookOpen> que ciclaba off → assisted → strict.
    • CiteMode button independiente, siempre visible.
    • Removido ragMode/setRagMode del destructuring de useChatStore.

1036 versiones publicadas · página 31 de 35. Míralo dentro de la app.