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. v9.5.53

    ✨ Pulido de la interfaz de escritorio

    Mejoras visuales y de usabilidad centradas en el escritorio (PC). AJUSTES: el panel de ajustes se reorganiza en secciones para que se entienda mejor de cara a cliente. CABECERA: el menú de usuario se agrupa en "Cuenta" y "Más", y todas sus opciones (Suscripción, Mis archivos, Calendario, Cambiar de cuenta, Añadir cuenta) pasan por el sistema de idiomas en vez de estar fijas en español — así respetan el idioma elegido. BARRA LATERAL: arreglado el menú contextual del chat que salía cortado y no mostraba todas las opciones (p. ej. "Eliminar"); ahora se posiciona dinámicamente según el espacio disponible. Además se unificaron radios, tipografía y sombras de la barra lateral. ADMIN: los iconos de acción en Usuarios tienen más contraste; Modelos añade una leyenda visible para los badges de capacidad (S/V/T/J/D/W/R). LIMPIEZA: borrado el código admin antiguo que ya no se usaba (5 componentes "Modern*").

    Nuevo

    • ⚙️ Panel de ajustes reorganizado en secciones
    • 👤 Menú de usuario agrupado y traducible (ya no fija el español)
    • 🛡️ Admin: iconos de Usuarios con más contraste + leyenda de capacidades en Modelos
    • 🧹 Borrado código admin muerto (Modern*)

    Mejorado

    • 🎨 Barra lateral: radios, tipografía y sombras unificados

    Arreglado

    • 🐛 Fix: menú contextual del chat ya no sale cortado (se ven todas las opciones)
  2. v9.5.52

    ⚡ Chat más rápido + endurecimiento de seguridad

    Mejoras internas de rendimiento y seguridad. RENDIMIENTO: el arranque de cada mensaje (/api/chat) ahora lee perfil + conversación + permisos + ajustes de colaboración en UNA sola consulta a la base de datos (nueva RPC get_chat_bootstrap) en lugar de varias idas y vueltas — clave porque la BD está en el NAS de casa y cada consulta cuesta. Se añade caché de 30s de app_settings (modelo de imagen/visión). Los invitados ya entran a /chat sin la pantalla "Preparando GarBotGPT…" (la sesión anónima se crea en el servidor). SEGURIDAD: la tabla guest_usage ahora tiene RLS y solo se toca vía RPC (antes un invitado podía resetear su límite por IP); search_path fijo en 7 funciones; /api/db-query registra el usuario real. FIX: el límite mensual de tokens ahora cuenta bien (antes pedía columnas inexistentes y nunca se aplicaba). Migraciones 121 y 122 aplicadas al NAS. Aparte, se subió max_connections de Postgres 100→200 y se ajustó la memoria/caché del NAS para reducir la lentitud por disco.

    Nuevo

    • 🚪 Invitados entran a /chat sin pantalla de carga

    Mejorado

    • Arranque del chat en 1 sola consulta a BD (antes varias) → menos latencia
    • 🗂️ Caché de ajustes (imagen/visión) durante 30s

    Arreglado

    • 🐛 Fix: el límite mensual de tokens ahora se aplica de verdad

    Seguridad

    • 🔒 guest_usage con RLS — no se puede saltar el límite por IP
  3. v9.5.51

    🔧 Fix deploy: consolidación de rutas API de ubicación

    v9.5.49 y v9.5.50 añadieron 3 endpoints nuevos (/api/places/nearby, /api/user/location/home, /api/user/location/travel-mode) que cruzaron el límite de 12 Serverless Functions del plan Hobby de Vercel — el deploy fallaba después de "Build Completed". Ahora todo va en el endpoint existente /api/user/location: GET devuelve {location, home, travel, travel_mode_enabled}; PUT con body.target='home' o 'travel_mode' multiplexa; DELETE?target=home borra solo la casa. /api/places/nearby eliminado (el chat usa la lib directamente). Sin pérdida funcional para el user — las features de v9.5.49 (cerca de mí, modo viaje) siguen activas vía dynamic imports en /api/chat.

    Nuevo

    • Deploy restaurado (eran 3 funciones de más sobre el límite de 12)
    • 🔀 Endpoint unificado /api/user/location con parámetro target
    • 🗑️ Borrados /api/places/nearby, /api/user/location/home, /api/user/location/travel-mode
  4. v9.5.50

    🏠 Nueva pestaña "Ubicación" en Ajustes

    Pestaña dedicada en Ajustes → Tu cuenta → Ubicación. Tres tarjetas: (1) "Ubicación actual" muestra dónde estás según GPS guardado + zona horaria + fecha de actualización + botón "Refrescar GPS" que pide ubicación al navegador. (2) "Tu casa" muestra tu punto de referencia + botón "Usar ubicación actual como casa" + botón "Borrar". (3) Toggle "Detección automática de viaje" que activa/desactiva el modo viaje. Si estás de viaje, en la parte superior aparece un banner ámbar con la distancia a casa y badge "🌍 Extranjero" si has cambiado de país. Nota de privacidad al final. Nuevo endpoint /api/user/location/travel-mode (GET/PUT).

    Nuevo

    • 🗺️ Pestaña "Ubicación" en Ajustes → Tu cuenta
    • 🏠 Botón "Usar ubicación actual como casa"
    • 📡 Botón "Refrescar GPS" pide ubicación al navegador
    • ✈️ Toggle "Detección automática de viaje"
    • 🌍 Banner "Modo viaje activo" con distancia a casa y badge extranjero
  5. v9.5.49

    🗺️ "Cerca de mí" + Modo viaje automático

    Dos features nuevas conectadas con ubicación. (1) Búsqueda CERCA DE MÍ: ahora puedes preguntar "qué restaurantes hay cerca", "farmacia abierta", "gasolinera", "cajero", "supermercado", "hotel", "qué visitar", etc. El chat detecta la intención + categoría, consulta OpenStreetMap (Overpass API, gratis) en un radio de 2 km de tu ubicación guardada, y devuelve hasta 10 resultados con nombre, distancia, dirección, horario, teléfono y web cuando los hay. 14 categorías soportadas: restaurantes, cafés, bares, farmacias, hospitales, gasolineras, cajeros, bancos, supermercados, hoteles, aparcamientos, paradas de bus, estaciones de tren, lugares de interés. (2) MODO VIAJE automático: profiles.home_location_json guarda tu casa (separada de la ubicación actual). Si tu ubicación actual está >100 km de casa, el chat lo detecta y le dice a la IA "este usuario está de viaje en X, considera moneda local, idioma, cultura, embajadas si pregunta por emergencias". Si además es OTRO PAÍS, añade nota sobre cambio cultural. Endpoints nuevos: /api/places/nearby?category=X y /api/user/location/home (GET/PUT/DELETE). Migración 120 aplicada al NAS (copia location actual como home la primera vez).

    Nuevo

    • 🍽️ "Restaurantes cerca" / "farmacia abierta" / "gasolinera" → resultados reales
    • 🗺️ 14 categorías OSM gratis (Overpass API, sin API key)
    • ✈️ Modo viaje: si estás >100 km de casa, IA lo sabe
    • 🌍 Si estás en otro país: contexto cultural/idioma/moneda automático
    • 🏠 GET/PUT /api/user/location/home para gestionar la ubicación "casa"
  6. v9.5.48

    🛰️ Permiso ubicación TWA Android + header móvil mucho más rápido

    (1) En la TWA Android, activar el permiso de ubicación en "Ajustes de la app" NO bastaba: Chrome internamente tiene una capa por origen separada. El LocationPrompt ahora detecta el estado con navigator.permissions.query, distingue TWA de navegador, y muestra instrucciones específicas + botón "Abrir ajustes" que lleva a chrome://settings/content/siteDetails. Soporta también GPS apagado, timeout, position_unavailable con mensajes distintos. (2) Los 3 botones del MobileHeader (sidebar, modelo, ajustes) eran lo más visible del lag en gama baja: cada uno tenía backdrop-filter:blur(18px)+saturate+brightness+contrast, 6 box-shadows, 2 pseudo-elementos ::before/::after y 6 listeners onPointerMove que recalculaban CSS vars en cada movimiento del dedo. En móvil simplificado a blur(6px) + 1 box-shadow + 0 pseudo-elementos + 0 listeners de pointer. Visual menos llamativo pero suave.

    Nuevo

    • 🛰️ LocationPrompt detecta TWA vs navegador con instrucciones específicas
    • 🔘 Botón "Abrir ajustes de Chrome para este sitio" en TWA Android
    • 🎯 Cero listeners de pointer en móvil (eran 18 entre los 3 botones)

    Mejorado

    • MobileHeader botones: blur 18→6px, 6→1 shadows, sin pseudo-elementos
  7. v9.5.47

    ⚡ Optimización rendimiento móvil gama baja (Snapdragon 6xx, Helio, Exynos 8xx)

    En móviles gama alta la app va bien, en gama baja iba lenta. Audit identificó 6 culpables principales. Fixes aplicados en globals.css (cubre toda la app de una sola pasada) + auth pages. (1) backdrop-blur-3xl/2xl/xl en móvil capeado a 8px (antes 12px, v9.5.37 ya bajó de 24+). (2) backdrop-saturate quitado en móvil (compite por GPU sin ser perceptible). (3) animate-ping deshabilitado en móvil (ahorra 8-12ms/frame por dot). (4) animate-pulse ralentizado a 2.5s (menos repaints). (5) mix-blend-mode forzado a normal en móvil (era screen/overlay/multiply, todos hacen composite extra pass). (6) SVG feTurbulence + feDisplacementMap (liquid-refract en login/register) ocultos en móvil — son los más caros de GPU móvil. (7) filter:blur ≥70px capeado a 16px (MusicPlayer, image-gen). (8) will-change permanente solo se activa al hover/focus/active (libera VRAM en idle).

    Nuevo

    • animate-ping desactivado en móvil (status dots)
    • 🌊 SVG liquid-refract solo en desktop (auth pages)
    • 🎭 mix-blend-mode forzado a normal en móvil
    • 💾 will-change solo al interactuar (libera VRAM)
    • 📉 Estimado: 50-130ms menos por frame en Snapdragon 6xx

    Mejorado

    • 🎨 backdrop-blur móvil: 12→8px + saturate stripped
  8. v9.5.46

    ✅ Bug REAL del tema: Tailwind v4 seguía el modo oscuro del sistema

    Ahora sí: la causa raíz. Tailwind v4 (que es lo que usamos con @import "tailwindcss") por DEFECTO activa la variante `dark:` con DOS condiciones unidas por OR: (1) clase `.dark` en un ancestro, (2) `@media (prefers-color-scheme: dark)`. Resultado: en Android con el sistema en dark, TODAS las clases `dark:bg-*` se activaban aunque nosotros NO añadiéramos la clase `.dark`. Por eso la app salía oscura con el sistema en oscuro pese a haber elegido claro. Fix: @custom-variant dark redefine la variante para que SOLO atienda a la clase. + meta color-scheme + color-scheme:light en :root para que el WebView Android no aplique scrollbars/inputs oscuros del sistema.

    Nuevo

    • 🎯 @custom-variant dark — Tailwind ya solo reacciona a la clase, NO al sistema
    • 🌐 meta color-scheme="light dark" — controla auto-styling de UA

    Mejorado

    • 🎨 :root color-scheme:light — scrollbars/inputs nunca oscuros por sistema
  9. v9.5.45

    ⚡ Reset forzado del tema: todos a claro en el próximo load

    v9.5.44 cambió el default a claro pero no afecta a usuarios que ya tenían "dark" guardado (la mayoría, porque antes auto-detectaba del sistema). Ahora añadido un flag de migración (geia-theme-migrated-v3): en el primer load post-v9.5.45 se ignora cualquier preferencia previa y se fuerza claro. La migración se marca con localStorage flag → solo pasa UNA vez por dispositivo. Tras este reset, si el user vuelve a Ajustes y elige oscuro explícitamente, se respeta y no se vuelve a resetear.

    Nuevo

    • 🔁 Reset one-shot: todos a light en su próximo abrir la app
    • 🚩 Flag geia-theme-migrated-v3 evita re-resetear
    • 👤 Tras el reset, la elección manual del user prevalece
  10. v9.5.44

    ☀️ App siempre en claro por defecto (ya no sigue el modo oscuro del Android)

    Antes la app respetaba el modo oscuro del sistema operativo (prefers-color-scheme: dark) cuando el usuario no había elegido tema. Resultado: si tu Android está en oscuro, la app también, aunque quisieras claro. Cambio: default a CLARO siempre. Si quieres dark, lo activas explícitamente desde Ajustes → Apariencia. La cookie + localStorage se setean al "light" en cuanto cargues por primera vez, así no volverá a evaluar el sistema. Para los usuarios que ya tenían dark elegido y guardado, su preferencia se respeta — solo afecta a primera carga sin preferencia.

    Nuevo

    • ☀️ Default = light (no más auto-oscuro porque tu Android sea dark)
    • 🧠 Si elegiste dark explícitamente, se respeta
    • 🍪 Cookie geia-theme=light fijada al primer load
  11. v9.5.43

    🎨 Tema sincronizado: la app Android respeta tu modo claro/oscuro elegido

    Bug: en la app Android (TWA) el usuario veía siempre tema oscuro aunque tuviera "claro" elegido en el navegador. Causa: el tema se guardaba SOLO en localStorage, que la TWA no hereda del Chrome del sistema → al abrirse caía a `prefers-color-scheme` (Android en dark = app en dark). Fix triple: (1) guardamos también en cookie geia-theme (TWA sí comparte cookies vía Digital Asset Links). (2) Inline script en <head> con strategy=beforeInteractive aplica el tema ANTES del primer pintado leyendo cookie → localStorage → sistema (en ese orden de prioridad). Adiós flash de tema incorrecto. (3) Persistimos en profiles.settings_json.theme via /api/user/theme; al iniciar sesión un nuevo ServerThemeSync component sincroniza con el servidor → el tema viaja entre dispositivos del mismo usuario.

    Nuevo

    • 🍪 Cookie geia-theme además de localStorage (TWA Android comparte cookies)
    • ☁️ /api/user/theme guarda en profiles.settings_json (cross-device)
    • 🔄 ServerThemeSync sincroniza al login y en TOKEN_REFRESHED

    Mejorado

    • Script inline en <head> aplica tema antes del primer pintado
  12. v9.5.42

    🎯 Calidad de respuesta sobre documentos: 11 bugs arreglados

    Atacados los 11 bugs reales que afectaban a la calidad de la respuesta cuando preguntas algo del documento. Antes la IA podía decir "no encuentro esa información" aunque el dato estuviera en el PDF. (1) Extracto en contexto subido de 1800→6000 chars + indicador si trunca. (2) En modo búsqueda específica, contexto estructurado de 4→10 docs (antes elegía mal cuál inyectar entre muchos archivos). (3) Fallback raw chunks ya NO trae solo la portada: busca por keyword y distribuye por archivo desde la mitad del PDF. (4) Threshold similarity 0.58→0.45 (más permisivo, menos falsos negativos en preguntas en español). (5) RPC hybrid migrada a config "spanish" con stemming + peso keyword subido a 0.3 (migración 119 aplicada al NAS). (6) Regex fallback del clasificador con ~25 verbos nuevos (explica/analiza/detalla/cuenta/saca/etc). (7) Re-extract gate subido de 16k→100k chars. (8) looksLikeMashedTabular detecta también separación por múltiples espacios. (9) colGap mínimo absoluto 8→12pt para tickets/recibos estrechos. (10) Tesseract OCR sobre PDFs ahora renderiza páginas a PNG antes de pasárselas (antes crasheaba con "PDF reading is not supported"). (11) Prompt de visión exhaustivo: ahora le exigimos listar UNA A UNA cada línea de tabla (antes a veces resumía).

    Nuevo

    • 📜 Extracto en contexto: 1800→6000 chars (datos del final del PDF dejan de perderse)
    • 🎯 Modo búsqueda: 4→10 docs con contexto completo
    • 🔍 Raw fallback con búsqueda keyword + distribución por archivo
    • 🇪🇸 RPC hybrid en español + threshold 0.58→0.45
    • 🧠 Clasificador intent: +25 verbos en regex fallback
    • 👁️ Visión: prompt exige listar cada línea individual
    • 📸 OCR Tesseract PDF→imagen funcional (antes crasheaba)
  13. v9.5.41

    🔍 Tercer pase audit móvil: 1 bug real + tooltips de sidebar

    Tercer pase de audit móvil. El agente reportó 15 issues pero al verificar uno por uno la mayoría eran falsos positivos (números de línea inventados o el responsive ya estaba). Bug REAL arreglado: la última fila de "Accesos rápidos" en WelcomeScreen quedaba parcialmente tapada por el composer en algunos móviles porque el fallback CSS era 192px pero el composer real mide ~240-260px (mic + paperclip + tools). Subido el fallback a 240px y el margen extra a 16/48px. Como pulido: añadidos atributos title en truncates de SidebarSleek (nombres de carpeta y nombre/email del perfil) — long-press en móvil ahora muestra el texto completo.

    Nuevo

    • 🧱 WelcomeScreen padding-bottom: 192→240 px fallback (último card visible)
    • 🧹 Muchos hallazgos del audit eran falsos positivos verificados uno por uno

    Mejorado

    • 🏷️ SidebarSleek: titles en nombre carpeta + nombre/email del perfil
  14. v9.5.40

    🩹 Micro-fixes móvil: tooltips en truncates + type=button en chips

    Pase de pulido sobre los 12 micro-bugs del audit anterior. Añadidos atributos title en spans truncados de MobileHeader (modelo, email, nombre, Spotify track/artist, conversación) y WelcomeScreen (project context, quick action labels) — ahora con long-press aparece tooltip nativo con el texto completo. Añadido type="button" a 19 chips de cierre de tools (×) dentro de ChatInput para garantizar que NO submitean el formulario por accidente cuando estás dentro de un form.

    Nuevo

    • 🏷️ Tooltips en truncates: usuario puede ver email/modelo/título completos con long-press
    • 🔘 19 botones × de tools chip: type="button" → no envían el chat sin querer

    Seguridad

    • Sin cambios de funcionalidad, solo accesibilidad y seguridad de forms
  15. v9.5.39

    📊 Google Analytics unificado (G-1XXL8PDYBB) + tracking ampliado

    Había DOS Google Analytics IDs conflictivos en el código: G-59TNFB7ZJY (layout.tsx) y G-HJ8GEPD9NE (AnalyticsTracker). El segundo devolvía 404 en la consola del navegador → los page_views se enviaban a un property inexistente y se perdían. Unificado a G-1XXL8PDYBB (el ID nuevo que pediste). Helper centralizado src/lib/analytics.ts con track(), setAnalyticsUser() y constantes Events para evitar typos de nombre. Tracking añadido: user_id automático al cargar (con tipo guest/registered), session_start synthetic en primer load, pricing_viewed en /pricing y /landing/pricing, register_view, login_view, model_changed (con from/to). El tracking existente de chat_message_sent en ChatInput y WelcomeScreen sigue funcionando (alias trackEvent retro-compatible).

    Nuevo

    • 📍 GA ID unificado a G-1XXL8PDYBB
    • 👤 user_id automático tras login con user_type (guest/registered)
    • 💰 Eventos: pricing_viewed, model_changed, register_view, login_view
    • 🔧 Helper src/lib/analytics.ts con constantes Events para consistencia
  16. v9.5.38

    🪛 Audit móvil: 6 bugs visuales arreglados

    Audit de código de los componentes móviles (sin Playwright ni emulador, solo lectura). 6 bugs reales encontrados y arreglados: (1) Touch targets de MobileBottomNav eran ~26px de alto cuando Apple recomienda 44px mínimo → py-1 → py-2.5. (2) El @media móvil de v9.5.37 ponía transition-duration:120ms a TODO sin excluir animations, rompiendo la entrada bonita de SettingsModal y similares. Ahora solo afecta transitions, no @keyframes. (3) "Registrarte gratis · 500 créditos" se cortaba en iPhone SE (320px): label corto en <sm, completo en sm+, con "· 500 créditos" solo en md+. (4) UploadProgressWidget tenía w=340 + right-4 → se salía del viewport en pantallas <360px. Bajado a w=320. (5) LocationPrompt y LowCreditsBanner competían a z-40: el de ubicación sube a z-[45] para tener prioridad. (6) backdrop-blur móvil bajaba a 8px y los toasts con texto encima de contenido variado perdían legibilidad. Subido a 12px (suficiente para legibilidad sin matar el FPS).

    Nuevo

    • 👆 MobileBottomNav: touch targets 26px → 44px (botones Chats/Imágenes/etc)
    • 🎬 Animaciones de modales (SettingsModal sheet-up) ya no se rompen en móvil
    • 📏 Registro: etiqueta corta en <360px para no cortarse
    • 📦 UploadProgressWidget: ancho 340→320 para iPhone SE
    • 🔝 LocationPrompt z-index +5 sobre LowCreditsBanner

    Mejorado

    • 👓 backdrop-blur móvil 8→12px (mejor contraste de toasts)
  17. v9.5.37

    📱 Mejoras móvil: banner ubicación encima del input, recordar modelo, menos lag, ajustes agrupados

    Cinco arreglos de UX móvil reportados: (1) El banner "Comparte tu ubicación" se solapaba con el composer del chat — ahora se posiciona POR ENCIMA del composer + nav (usa --chat-bottom-space) y respeta el keyboard offset. Contraste mejorado en dark mode. (2) El modelo seleccionado no se persistía: cambiabas a GPT-5.5 y al recargar volvía a 5.2. Ahora se guarda en localStorage:geia:last-model y se restaura. (3) Animaciones laggy en móviles low-end: en viewports <768px reducimos transition-duration a 120ms y backdrop-blur a 8px (antes 24px+). Respeta prefers-reduced-motion global. (4) Pantalla Ajustes en móvil: antes lista plana de 15+ items, ahora agrupada en 5 secciones (Tu cuenta · Personalización IA · Tu contenido · Apariencia y voz · Progreso) con iconos 44px (antes 36px) y texto 16px (antes 15px). (5) Indirecto del fix 1: el banner ya no se solapa con texto del composer, contraste de azul más fuerte.

    Nuevo

    • 🗺️ Banner ubicación móvil: encima del composer, no encima
    • 💾 Modelo seleccionado persistido (localStorage)
    • 📋 Ajustes móvil: 5 secciones con iconos grandes en vez de lista plana

    Mejorado

    • Móvil: transitions 120ms + backdrop-blur 8px → menos lag
  18. v9.5.36

    💳 Admin billing: plan asigna créditos + planes temporales + más opciones

    Bug arreglado: cuando el admin asignaba un plan a un usuario (ej. "Pro"), solo se actualizaba la columna plan sin otorgarle los créditos correspondientes. El usuario quedaba con plan Pro pero 0 créditos. Ahora al asignar plan se calculan automáticamente los créditos del producto, se otorgan vía grant_credits (queda en ledger) y se setean monthly_credit_grant y status=active. Nuevas opciones añadidas al modal: (1) Planes temporales con N días configurables (1-3650). (2) Renovar +N días sin tocar el plan (extiende caducidad). (3) Resetear cuota mensual (re-otorga créditos del plan ahora mismo). (4) Quitar plan con checkbox "mantener créditos". (5) Notas internas del admin (cap 1000 chars) sobre el usuario. (6) Indicador visible de días restantes y badge "temporal". (7) Validación: si seleccionas un credit_pack en vez de subscription, devuelve error claro.

    Nuevo

    • Planes temporales con N días configurables
    • 📅 Renovar +N días sin cambiar el plan
    • 🔄 Resetear cuota mensual (re-grant ahora)
    • 🗑️ Quitar plan con opción "mantener créditos"
    • 📝 Notas internas del admin sobre el usuario

    Arreglado

    • 🐛 FIX: asignar plan ahora otorga sus créditos automáticamente
  19. v9.5.35

    🐛 Auditoría del sistema de análisis de docs: 4 bugs arreglados

    Auditoría completa del pipeline de análisis de documentos. Encontrados y arreglados 4 bugs (uno reportado era falso positivo): (1) Admin guardar config era DELETE→INSERT no atómico → ventana de 1-2s con config vacía si el INSERT fallaba. Ahora INSERT primero, DELETE viejos después. (2) Coords extractor usaba gap=15pt absoluto → en PDFs anchos las columnas con gap pequeño colapsaban. Ahora gap relativo al ancho de página (1.2%). (3) Vision en Vercel usaba useSystemFonts:true asumiendo fuentes del SO → en serverless no existen y el render salía en bloques grises. Ahora useSystemFonts solo en local, en Vercel usa las standard_fonts de pdfjs (Foxit, ~1.2MB bundladas). (4) Regex fallback del clasificador de intent perdía vocabulario común de nóminas/facturas/gastos. Ampliado con ganado/cobrado/percibido/devengado/líquido/deducciones/anual/mensual/etc. Reindex admin ya respetaba config (falso positivo del audit).

    Nuevo

    • 📐 Coords gap: relativo al ancho (1.2%) en vez de 15pt fijo
    • 🖼️ Vision Vercel: standard_fonts del paquete (no system fonts)
    • 🔤 Intent regex: +30 palabras de vocabulario financiero/RRHH

    Seguridad

    • 🔒 Admin config: INSERT antes que DELETE (atómico)
  20. v9.5.34

    📝 Docx/PDF generados sin <artifact> rotos + botones login/registro para invitados

    Dos cosas. (1) Cuando pedías "genérame un documento Word/PDF" la IA envolvía el contenido en <artifact type="markdown">…</artifact>, y el conversor markdown→docx no sabía stripear esas etiquetas → el archivo descargado contenía las etiquetas literales y se veía roto. Ahora cuando hay generación de documento activa: NO se añade el bloque de instrucciones de artifacts al prompt, en su lugar se le dice al modelo "devuelve markdown puro empezando por H1", y como red de seguridad el normalizador strippea cualquier <artifact>/[[ARTIFACT:id]] que cuele. (2) La pantalla de bienvenida no tenía CTA visible para que un invitado pasara a usuario real — solo veía el chat. Ahora arriba aparece una pill discreta: "Estás de invitado · [Iniciar sesión] [Registrarte gratis · 500 créditos]".

    Nuevo

    • 🎯 Welcome de invitados: pill con CTA "Iniciar sesión" + "Registrarte gratis"

    Arreglado

    • 🩹 Genera docx/pdf/xlsx/pptx limpios (sin etiquetas <artifact> dentro)

    Seguridad

    • 🛡️ Stripper de seguridad en normalizeMarkdownDocument
  21. v9.5.33

    🔧 Fix pdfjs en Vercel: extractor de coordenadas vuelve a funcionar en producción

    En local funcionaba todo, pero en Vercel los logs mostraban dos errores en cada ingest de PDF: "Cannot find module ./pdf.worker.js" (coords) y "The path argument must be of type string. Received type number" (vision). Causa: pdfjs-dist usa require() dinámico para cargar el worker, los cmaps y las standard fonts; Next/Turbopack solo bundlea lo que detecta importado estáticamente. Resultado: en serverless el worker no existía, pdfjs fallaba, los PDFs se ingestaban solo con Tika (texto mashed) y las nóminas volvían a aparecer "No detallado". Fix: resolver workerSrc en runtime con require.resolve() y forzar outputFileTracingIncludes para que Vercel bundle pdf.worker.js + cmaps + standard_fonts con las rutas /api/files/** y /api/chat/**.

    Nuevo

    • 📦 next.config: outputFileTracingIncludes bundle pdf.worker + cmaps + standard_fonts
    • 🚫 pdfjs-dist + canvas movidos a serverExternalPackages
    • Coords vuelve a reconstruir tablas en producción (no solo en local)

    Arreglado

    • 🩹 GlobalWorkerOptions.workerSrc = require.resolve("pdfjs-dist/.../pdf.worker.js")
  22. v9.5.32

    ⚙️ Admin → Análisis de Documentos: nuevos controles para coords, visión, classifier y caps

    Hasta ahora las features añadidas en v9.5.26-31 (extractor por coordenadas, fallback con visión multimodal, clasificador LLM de intent y los caps de archivos en contexto) vivían en env vars o hardcoded en el código. Ahora todas son editables desde Admin → Análisis de Documentos. Nuevas secciones: "Extracción avanzada de PDFs" (toggle coords + toggle visión + modelo + máx páginas) y "Inteligencia del contexto en chat" (toggle classifier + modelo + 4 caps editables). Migración 118 añade 10 columnas nuevas a doc_analysis_config con defaults seguros.

    Nuevo

    • 🎛️ Admin → Extracción avanzada: toggle coords (gratis) + visión (de pago)
    • 🤖 Toggle del clasificador LLM de intent + selección de modelo
    • 🔢 4 caps editables: adjuntos/carpeta/chunks default/chunks agg max
    • 🗄️ Migración 118: 10 columnas nuevas en doc_analysis_config (aplicada al NAS)
  23. v9.5.31

    🧠 Adiós a las palabras clave: clasificador LLM decide qué contexto incluir

    Antes (v9.5.30): un regex con palabras clave ("todas/total/suma/cada/nóminas…") decidía si la IA recibía contexto de TODOS los archivos o solo unos pocos. Funcionaba el 80% del tiempo — pero frases como "explícame los gastos del año pasado" no matcheaban y la IA terminaba viendo solo 4 de 17. Reemplazado por un clasificador con gpt-4o-mini que entiende intención semántica: lee la pregunta, ve los nombres de los archivos y decide TODOS o ALGUNOS. Reglas rápidas: 1-4 archivos → siempre TODOS (gratis, sin llamada); 5+ archivos → clasificador. Si el clasificador falla (timeout, red, etc.), fallback al regex antiguo. Latencia añadida: ~300-700ms, compensada al correr en paralelo con el embedding del mensaje.

    Nuevo

    • 🤖 Clasificador con gpt-4o-mini reemplaza al regex de keywords
    • 🛡️ Fallback automático a regex si el clasificador falla
    • 📂 Aplica tanto a adjuntos directos como a carpetas

    Mejorado

    • 1-4 archivos: siempre todos en contexto (sin llamada extra)
  24. v9.5.30

    📎 Adjuntos en chat: ahora la IA ve TODOS los archivos (antes solo 7)

    Al subir 17 nóminas a un chat y pedir "dame todas y suma cuánto he ganado", la IA solo veía 7 archivos. La causa: límites fijos en el flow de adjuntos (8 chunks, 4 documentos estructurados) — pensados para "analiza este PDF" no para agregación masiva. La detección de intent ("todas/total/suma/cada/cuánto/nóminas/facturas") ya existía para el flow de carpetas; ahora también se aplica a los adjuntos directos del chat. Cuando detecta intent de agregación: sube a 16-40 chunks y hasta 25 documentos con contexto estructurado completo. Además inserta una instrucción imperativa al modelo para que calcule y responda con el listado por documento sin pedir confirmación.

    Nuevo

    • 📊 17 archivos adjuntos → la IA ve los 17 (antes 7)
    • 🎯 Detecta intent: "todas/total/suma/cada/cuánto/nómina/factura"
    • ⚙️ Match hasta 40 chunks + 25 documentos con contexto completo
    • 🗣️ El modelo recibe orden de calcular y listar sin pedir confirmación
  25. v9.5.29

    ✨ Multi-cuenta: modal inline para reactivar sin salir de la página

    Antes (v9.5.28): si los tokens guardados de una cuenta estaban muertos server-side (colateral del bug viejo del logout global), te redirigía a /auth/login con email pre-rellenado. Funcionaba pero rompía el flow. Ahora aparece un modal pequeño centrado pidiendo solo la contraseña, sin salir de donde estés. Tecleas → reactivas → la cuenta vuelve viva al selector. Cero navegación. Pensado para las cuentas afectadas por el bug viejo: una vez reactivadas, los siguientes cambios entre cuentas son INSTANTÁNEOS (sin modal, sin login).

    Nuevo

    • 🪟 Modal inline "Reactivar cuenta" con email locked + contraseña
    • 🔁 Tras reactivar, los próximos switches son directos sin modal
    • 🗑️ Botón "Olvidar esta cuenta" si ya no quieres usarla
  26. v9.5.28

    🔄 Multi-cuenta: re-login automático cuando una cuenta caducó

    El fix de v9.5.25 (logout local en vez de global) evita que NUEVOS logouts maten los tokens, pero las cuentas guardadas en localStorage cuyos tokens YA fueron revocados (por el bug anterior) siguen dando 401 al intentar cambiar. Solución: cuando el switch falla con 401, en vez de quedarse el toast genérico "sesión caducada", redirigimos automáticamente al login con el email pre-rellenado y un banner ámbar explicando la situación. Un solo click (escribir contraseña) y la cuenta vuelve a estar viva en el selector. También arreglado un bug previo: cuando entrabas a /auth/login?add=1 con sesión activa, te redirigía a /chat sin dejarte ver el formulario.

    Nuevo

    • 🎯 Switch fallido (401) → auto-redirect a login con email + banner explicativo
    • 🛡️ /auth/login?add=1 ya no auto-redirige aunque haya sesión activa
    • Tras el re-login, la cuenta vuelve al selector sin pasos extra
  27. v9.5.27

    🎨 Landing actualizada con precios reales, packs y novedades

    La landing /landing/pricing decía "Beta gratis, sin precios todavía" — completamente obsoleto desde que tenemos planes y packs en vivo con Stripe. Reescrita: muestra Free (500 créditos), Pro €8 (5K cr/mes), Max €20 (15K cr/mes) y los 4 packs de créditos (5K €6, 15K €15, 60K €50, 130K €100). Añadido bloque transparente de qué cuesta cada acción (chat 3-8 cr, búsqueda web 12 cr, imagen 180 cr, deep research 200 cr, vídeo 1.200 cr). Sección de app móvil con CTA a Google Play y a iOS PWA. FAQ con preguntas reales. La home también actualizada con sección "Lo nuevo" (multi-cuenta, app móvil, créditos, ubicación) y teaser de precios antes del CTA final.

    Nuevo

    • 💰 /landing/pricing: Free + Pro €8 + Max €20 + 4 packs con precios reales
    • 📊 Bloque "cómo se gastan los créditos" con coste por acción
    • 📱 Sección app móvil con CTAs a Google Play y iOS PWA
    • 🆕 Home con sección "Lo nuevo" (multi-cuenta, créditos, app, ubicación)
    • FAQ con dudas reales sobre caducidad, cancelación, referidos, pago
  28. v9.5.26

    📄 Carpetas con PDFs leídos correctamente (nóminas, facturas, tablas)

    Hasta ahora pdf2json devolvía el texto de los PDFs tabulares MASHED — las columnas se pegaban entre sí ("5,76260,00" en vez de "5,76 | 260,00"). La IA solo lograba extraer datos de algunos meses por azar; los demás aparecían como "No detallado en extracto". Nuevo extractor que usa coordenadas X/Y de pdfjs.getTextContent y reconstruye las columnas por posición. Gratis, instantáneo, determinístico. Re-procesados los 17 PDFs de Nominas GESEM: 15/17 ahora tienen tablas detectadas. Visión (gpt-4o-mini) queda como fallback para PDFs escaneados puros.

    Nuevo

    • 📊 Extractor de coordenadas: reconstruye tablas por posición X/Y (pdfjs.getTextContent)
    • 👁️ Visión multimodal (gpt-4o-mini) como fallback para PDFs escaneados
    • 🔁 Script scripts/reextract-with-vision.ts para re-procesar carpetas existentes

    Arreglado

    • 🩹 OCR de tesseract envuelto en try/catch (antes mataba el ingest)
  29. v9.5.25

    🔐 Multi-cuenta REALMENTE arreglado + permisos de ubicación en Android

    Causa raíz definitiva del 401 en cambio de cuenta: el botón "Cerrar sesión" usaba el scope global por defecto, que revoca TODOS los refresh tokens del usuario en GoTrue. Así que al cerrar sesión en A y luego intentar volver a A desde el selector multi-cuenta, el token guardado ya no servía. Cambiado a scope:"local" en ambos sitios (Header y Sidebar). Comprobado en los logs del auth: cada "logout" del usuario borraba sus tokens server-side, dejando el switch imposible. Adicionalmente, añadidos permisos ACCESS_FINE/COARSE_LOCATION al manifest Android y nueva AAB (versionCode 5, versionName 9.5.25) para Google Play.

    Nuevo

    • 🎯 Logout ahora es local (scope:"local"): los refresh tokens del usuario sobreviven → multi-cuenta vuelve a funcionar

    Arreglado

    • 🪵 Logs en /api/auth/switch-account para diagnosticar futuros fallos

    Seguridad

    • 📱 Android TWA: permisos de ubicación añadidos + nueva AAB (v9.5.25 / code 5)
  30. v9.5.24

    🩹 Avatar visible en Header/Welcome + sidebar sin flicker

    Las nuevas URLs de avatar (supabase.garbotgpt.com) estaban bloqueadas por Next/Image porque el dominio no estaba en la whitelist — por eso Sidebar las mostraba bien pero Header y Welcome no. Añadido a la config. Además, al navegar entre /chat y /carpetas las carpetas del sidebar parpadeaban (la sidebar se remontaba); ahora hay caché y aparecen al instante.

    Nuevo

    • 🖼️ Avatares se muestran en Header y Welcome (faltaba el host en next.config)

    Mejorado

    • Carpetas y nombre de usuario del sidebar instantáneos al navegar (sin flicker)

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