Releases: NLACE-COM/mcp-supermercados-cl
Release list
v1.4.5 — Fix del contrato de sesión de Jumbo (carro y listas guardadas)
Jumbo rotó el contrato de sesión de su BFF y dejó rotas las tools que dependen del navegador logueado. Esta versión lo repone y verifica cada endpoint contra el sitio real.
Basada en el PR #11 de @cristiancs, que diagnosticó el fallo del preflight en el carro. Al revisarlo apareció que el problema era más grande: las listas guardadas fallaban por la misma causa desde la 1.4.4, sin que nadie lo notara.
Fixed
- Carro (
add_to_cart,get_cart): los snippets mandabanWnOIGTaOkfFwotM8Ddw2comoapiKey, junto contoken,x-consumer,x-e-commerceyx-account. Esa key resultó ser la del serviciosalesChannel(VTEX legacy) — nunca fue la del BFF — y esos cuatro headers los rechaza el preflight: el propio frontend los borra para los servicios del BFF. Ahora se mandaAuthorization: Bearer, laapiKeydel servicio,x-client-platform,x-client-versionyx-trace-id, concredentials: "include". - Listas guardadas (
get_saved_lists): rotas desde la 1.4.4 por la misma key vencida. Ahora laapiKeyva por servicio (JUMBO_API_KEYS), porque cada servicio del BFF valida solo la suya. Como carro y listas compartían la constante de headers, arreglar solo el carro habría dejado las listas rotas en silencio — los tests de contrato no tocan la red.jumboFetchSnippet/jumboMutateSnippetahora exigen el servicio como parámetro, para que el compilador no deje repetir el error.
Changed
add_to_cartdocumenta queskuIdes el campoiddesearch_products, no la referencia comercialsku.docs/captura-cencosud-2026-07-06.md§4d: headers y mapa deapiKeypor servicio.
Verificación
Contra el sitio real, con sesión y sucursal jumboclj775. Las keys no son intercambiables — cada servicio rechaza la del otro:
| apiKey enviada | GET /lists |
GET /cart |
|---|---|---|
...jumbo-lists-9f222055975d |
200 | 403 You cannot consume this service |
...jumbo-cart-rhk68rqi0adn |
403 You cannot consume this service |
200 |
WnOIGTaOkfFwotM8Ddw2 (la de 1.4.4) |
401 | 401 |
La fila de abajo es la que explica el alcance: la key de la 1.4.4 daba 401 en ambos endpoints. Jumbo no rotó el contrato del carro, lo rotó entero.
13 tools, 160 tests.
Full changelog: v1.4.4...v1.4.5
v1.4.4 — Smoke live sin falsos positivos (tolera bloqueo antibot)
El smoke live semanal abría un issue de falso positivo cada lunes (ej. #9) porque Tottus y Líder bloquean siempre el tráfico de datacenter (GitHub Actions). Ese ruido enterraba las alertas que sí importan.
🐛 Fixed
- El smoke live tolera el bloqueo antibot esperable (
tests/live/otras-cadenas.live.test.ts) — distingue un bloqueo antibot (HttpStatusError401/403/307/429, oErrorcon mensaje de antibot: PerimeterX/BIG-IP/"blocked") de un cambio de formato real (el fetch devuelve 200 peroProductSchema.parseo la aserción de resultados falla). El bloqueo desde la nube ya no rompe el smoke (solo warning); un cambio de formato sí lo rompe y abre el issue. Jumbo, Santa Isabel y Unimarc se siguen validando de verdad.
✨ Added
SMOKE_STRICT=1— en un runner con IP residencial reendurece el bloqueo a fallo, para cobertura real de las tres cadenas.
✅ Verificación
En vivo: modo normal 7/7 (Tottus/Líder tolerados con warning), estricto 2 failed (Tottus/Líder). Contrato: 157 tests. Cierra #9.
Changelog: CHANGELOG.md
🤖 Generated with Claude Code
v1.4.3 — Fix condición de carrera del puente (navegación en paralelo)
Corrige un bug de concurrencia: al pedir "el más barato" (build_cheapest_basket/compare_stores), Tottus resolvía pero Líder caía como "bloqueado" de forma intermitente.
🐛 Fixed
- Carrera al abrir el navegador — las cadenas se navegan en paralelo; dos
launchPersistentContextconcurrentes sobre el mismo perfil chocaban por el lock (Target page, context or browser has been closed). AhoraensureContext()memoiza la promesa del contexto → todas las llamadas concurrentes comparten un solo navegador.
✅ Verificación
Contra los sitios reales (Chrome real, en paralelo): Líder y Tottus resuelven juntos. 157 tests.
Changelog: CHANGELOG.md
🤖 Generated with Claude Code
v1.4.2 — Puente automático usable con npx (Claude Desktop)
Hace usable el puente automático cuando el server corre por npx (Claude Desktop, etc.). Antes solo cargaba Playwright si era dependencia local.
🐛 Fixed
- Carga de Playwright global con
npx— pornpxelnode_modulesdel paquete es efímero y no ve el Playwright global.NODE_PATHno ayuda (el bridge carga conimport()ESM;NODE_PATHsolo aplica arequire()CommonJS — verificado). Ahora, si elimport("playwright")normal falla, se resuelve el paquete global víacreateRequiredesde la carpeta que indiqueSUPERMERCADOS_PLAYWRIGHT_PATH(npm root -g+/playwright).
➕ Added
- Variable
SUPERMERCADOS_PLAYWRIGHT_PATH+ guía y config lista paranpxen el README.
✅ Verificación
Simulado el arranque de Claude Desktop (npx sin playwright local + la variable al global): Líder 46 productos. 157 tests.
Changelog: CHANGELOG.md
🤖 Generated with Claude Code
v1.4.1 — Fix del puente de navegador (Líder/Tottus ahora sí resuelven)
Corrige la 1.4.0: el puente automático nunca resolvía Líder/Tottus por tres bugs que solo se ven contra el sitio real (los tests con fixtures no los detectaban).
🐛 Fixed
__NEXT_DATA__+noncede CSP — el navegador real inyecta<script nonce="" id="__NEXT_DATA__" …>(nonce antes del id); el marcador literal no lo matcheaba y Líder se reportabablockedcon los datos presentes. NuevonextData.ts(extractNextDataJson/hasNextData, tolerante al orden de atributos), compartido por Líder y Tottus.fetchSsrHtml/ navegación —networkidlenunca se cumple (analytics/polling) → timeout. Ahoradomcontentloaded.fetchSsrHtml/ selector —waitForSelectoresperabavisible, pero un<script>es invisible → timeout. Ahorastate: "attached".
✅ Verificación
Contra los sitios reales (Chrome real, channel: "chrome"): Líder ~46 productos, Tottus ~48. 157 tests.
Changelog: CHANGELOG.md
🤖 Generated with Claude Code
v1.4.0 — Compra multi-cadena y puente de navegador automático
Versión de compra multi-cadena y automatización del puente de navegador. Integra la contribución de @dmnavalon (#3) y cierra #2.
✨ Added
build_cheapest_basket— canasta más barata "repartida": asigna cada ítem a la cadena donde sale más barato (cherry-pick) y agrupa por cadena. Exponepicks,plan,basketTotal,singleStore,splitSaving,mixedFormatItems,missing. Prompt guiadosuper_eficiente.- Puente de navegador manual (Líder/Tottus) —
search_productsaceptabrowserHtml; sin él y bloqueado, devuelveopenUrl+browserSnippet+retryWithen vez de un error seco. - Puente de navegador automático (
browserBridge.ts) — con Playwright configurado por entorno (SUPERMERCADOS_PLAYWRIGHT_PROFILE,_CHANNEL,_HEADLESS), el servidor navega solo reusando el perfil de Chrome del usuario y resuelve Líder/Tottus sin intervención ensearch_products,compare_storesybuild_cheapest_basket. Sin configurar, se mantiene el flujo manual. El servidor sigue sin ver credenciales.
🔧 Changed / Fixed
PlaywrightBridge.fetchSsrHtml()espera#__NEXT_DATA__en el DOM (App Router hace streamingself.__next_f).- Documentado que el bloqueo de Líder es por fingerprint del cliente (TLS/JA3 + PerimeterX + F5 BIG-IP,
307 → /blocked), no por IP. - 13 tools, 153 tests.
Changelog completo: CHANGELOG.md
🤖 Generated with Claude Code
v1.2.0 — Experiencia de usuario: prompts, presupuesto y errores accionables
Versión enfocada en experiencia del usuario: menos fricción, más guía, respuestas más claras.
✨ Novedades
Descubribilidad
- Prompts guiados que tu cliente MCP muestra como sugerencias:
armar_lista(con presupuesto opcional),conectar_sesion,comparar_carroyofertas_frecuentes. El usuario ya no tiene que adivinar qué pedir. instructionsdel servidor: el modelo sabe cómo guiarte en el primer uso (qué cadena, cuándo pedir sesión, cómo leer errores).
Menos fricción
discover_branch: descubre tu sucursal (branchId) leyéndola del navegador, para no pedirte un código técnico comojumboclj512.
Mejores respuestas
- Presupuesto en
build_list(maxBudget): si el total se pasa, baja a alternativas más baratas —sin tocar tus frecuentes— y, si aún se pasa, te sugiere qué quitar. - Errores accionables: cada error trae el siguiente paso concreto (re-loguearte, reintentar, usar IP residencial) en vez de un mensaje técnico.
- Resumen human-friendly en
build_list: totales formateados ($12.345), porcentaje de ahorro y conteo de ítems en oferta.
🧪 Calidad
132 tests de contrato. Lint, formato, typecheck y build limpios.
Changelog completo en CHANGELOG.md.
v1.1.0 — CI, matching en español y flujo de sesión guiado
Versión enfocada en calidad del proyecto (para recibir colaboradores) y en calidad de resultados.
✨ Novedades
Salud del repo (para contribuir)
- CI en GitHub Actions:
lint + typecheck + build + testen cada push y PR (Node 20 y 22). - Smoke live semanal que abre un issue automático si una cadena cambia su formato.
- ESLint (flat) + Prettier con scripts
lint/format/typecheck. - Templates de issue/PR en
.github/(el de bug pide cadena, ítem, error e IP).
Calidad del núcleo
- Matching en español (
src/core/matching.ts): plurales, tildes, sinónimos y regionalismos chilenos — palta↔aguacate, bebida↔gaseosa, confort↔papel higiénico, …build_listahora encuentra frecuentes que el match literal perdía, con guardas para no confundir agua con aguacate. compare_storesmás honesto: filtra candidatos irrelevantes y expone por ítem un campocomparability(same/similar/mixedsegún EAN y unidad) más undisclaimer, para no comparar formatos distintos como si fueran iguales.
Flujo de sesión
get_cart,get_frequent_purchases,get_saved_listsyadd_to_cartdevuelven unbrowserSnippet(fetch de una sola llamada) y prohíben el scraping manual de React/DOM que hacía lentas estas operaciones.- Puente Playwright opcional (
src/adapters/playwrightBridge.ts) para automatizar el flujo reusando el perfil de Chrome logueado. Se carga dinámicamente: no pesa en el paquete.
🧪 Calidad
119 tests de contrato. Formato, lint, typecheck y build limpios.
Changelog completo en CHANGELOG.md.