nexusflex-mcp 3.74.1 → 3.75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nexusflex",
3
3
  "description": "Nexus Flex en Claude: el MCP (altas, consultas, control por foto; nunca mueve dinero) y las skills (control por foto) en un solo instalable.",
4
- "version": "3.74.1",
4
+ "version": "3.75.0",
5
5
  "author": {
6
6
  "name": "Nexus Flex",
7
7
  "url": "https://nexusflex.com.ar"
package/docs.mjs CHANGED
@@ -217,7 +217,7 @@ const TOOL_DOCS = {
217
217
  control_foto_preparar: { que: "Crea en la PC las carpetas del control por foto de uno o varios d\xEDas, con los nombres EXACTOS de tus grupos y cadetes (DADOS/<grupo>, DADOS/<cadete>, RECIBIDOS/<cadete>, RECIBIDOS/<grupo>) + un LEEME.txt.", uso: "Cuando el usuario dice 'hagamos el control por foto del d\xEDa tal': fechas ('14/09/2026', '14/09 a 19/09', '14/09, 16/09'). Se arman adentro de la carpeta del control por foto (la que eligi\xF3 al instalar el plugin; por defecto Documentos\\Control por foto); `ruta` es solo una subcarpeta opcional. Decile d\xF3nde quedaron y que suelte las fotos; despu\xE9s `control_foto_carpeta`.", ej: "control_foto_preparar fechas:'14/09 a 19/09' \u2192 6 d\xEDas con DADOS/Bonorino, DADOS/Portela, DADOS/Gerardo Soveron\u2026", no: "Solo en el MCP local (npx). No crea ni lee nada afuera de la carpeta del control; no pisa carpetas que ya existen; no procesa fotos." },
218
218
  control_foto_estructura: { que: "C\xF3mo se arman las carpetas del control por foto para TU nodo: tus grupos log\xEDsticos y qui\xE9nes reparten (los nombres que valen en DADOS/\u2026 y RECIBIDOS/\u2026).", uso: "Sin argumentos (el admin global pasa `nodo`). Llamalo antes del primer control para explicarle la estructura al usuario, o cuando una carpeta no se reconoce.", ej: "control_foto_estructura \u2192 grupos: Bonorino, Portela, Z\xE1rate Campana \xB7 cadetes: Gerardo Soveron, Miguel Punturirero\u2026", no: "No procesa fotos ni cambia nada." },
219
219
  control_foto_carpeta: { que: "Procesa la CARPETA de un d\xEDa (o de varios) del control por foto, desde tu PC: cada foto bajo DADOS/\u2026 o RECIBIDOS/\u2026 con su carpeta y el d\xEDa que sale del nombre de la carpeta.", uso: "ruta: la carpeta del d\xEDa (o la que contiene varios d\xEDas). Primero SIN `aplicar` (simula) \u2192 mostr\xE1 el resumen y resolv\xE9 las preguntas (cuentas de ML desconocidas, zonas con varios responsables, duplicados) \u2192 despu\xE9s `aplicar:true`. Reanudable: lo ya procesado no se repite. Deja _control-foto-<d\xEDa>.json y copia lo dudoso a _sin_identificar.", ej: "control_foto_carpeta ruta:'Lunes 14-9-2026' \u2192 312 fotos: 280 ok, 25 preguntas (3 cuentas de ML desconocidas\u2026). Despu\xE9s, aplicar:true.", no: "Solo en el MCP local (npx): el conector remoto no ve tu disco. Solo lee adentro de la carpeta del control por foto (rutas relativas a ella). No mueve dinero; no descomprime .zip (avisa)." },
220
- control_foto_foto: { que: "Procesa UNA foto de etiqueta del control por foto: QR o IA \u2192 env\xEDo sin duplicar \u2192 asignaci\xF3n seg\xFAn la carpeta \u2192 Entregado en el d\xEDa real \u2192 foto en el historial.", uso: "ruta (MCP local) o imagen en base64 (remoto) + carpeta ('DADOS/Bonorino', 'RECIBIDOS/Matanza/Gerardo'\u2026) + fecha. Sirve para CONTESTAR una pregunta: repet\xED la foto con `nodoEntrega` (qui\xE9n la llev\xF3) o `cliente` (de qui\xE9n es la cuenta de ML). `simular:true` = solo mirar.", ej: "control_foto_foto ruta:'Lunes 14-9-2026/RECIBIDOS/Matanza/Gerardo/IMG_1.jpg' carpeta:'RECIBIDOS/Matanza/Gerardo' fecha:'14/09/2026' cliente:306", no: "No mueve dinero; no toca env\xEDos de afuera de tu red (tu nodo + los de tus grupos); no reasigna lo que ya entr\xF3 en un cierre semanal congelado." },
220
+ control_foto_foto: { que: "Procesa UNA foto de etiqueta del control por foto: QR o IA \u2192 env\xEDo sin duplicar \u2192 asignaci\xF3n seg\xFAn la carpeta \u2192 Entregado en el d\xEDa real \u2192 foto en el historial.", uso: "ruta (MCP local) o imagen en base64 (remoto) + carpeta ('DADOS/Bonorino', 'RECIBIDOS/Matanza/Gerardo'\u2026) + fecha. Sirve para CONTESTAR una pregunta: repet\xED la foto con `nodoEntrega` (qui\xE9n la llev\xF3) o `cliente` (de qui\xE9n es la cuenta de ML). Etiqueta SIN n\xFAmero (env\xEDo particular, la imprimi\xF3 el vendedor): pas\xE1 `direccion` (+ `localidad`, `destinatario`, `telefono`) y `cliente` o `nodo` \u2014 busca si ya est\xE1 cargado a esa direcci\xF3n y, si no, lo da de alta con un tracking propio de Nexus Flex. `simular:true` = solo mirar.", ej: "control_foto_foto ruta:'Lunes 14-9-2026/RECIBIDOS/Matanza/Gerardo/IMG_1.jpg' carpeta:'RECIBIDOS/Matanza/Gerardo' fecha:'14/09/2026' cliente:306", no: "No mueve dinero; no toca env\xEDos de afuera de tu red (tu nodo + los de tus grupos); no reasigna lo que ya entr\xF3 en un cierre semanal congelado." },
221
221
  envio_entregar: { que: "Marca como ENTREGADO uno o varios env\xEDos que YA est\xE1n cargados, por tracking \u2014 y con `fecha`, el d\xEDa REAL en que se entreg\xF3.", uso: "trackings: ['TN-123', 'NFABC123'] + fecha (opcional, dd/mm/aaaa). Usalo cuando no est\xE1s cargando desde una etiqueta (para eso est\xE1 `envio_desde_etiqueta_ml` con `avanzarA`). Sin `fecha` el historial dice que se entreg\xF3 ahora, que es mentira cuando la tanda se controla por foto d\xEDas despu\xE9s; sobre un env\xEDo que YA figura entregado, `fecha` CORRIGE el cierre ya registrado (vuelve en `fechaCorregida`). Entrega solo con los datos (sin foto ni firma). Scopeado a tu nodo.", ej: "envio_entregar trackings:['TN-2057600163'] fecha:'02/09/2026' \u2192 lo cierra con el d\xEDa en que sali\xF3 y sella la log\xEDstica de entrega para el clearing.", no: "No mueve dinero; `fecha` toca el evento 'Entregado' del historial, NO la semana en que se liquida (eso es envio_editar_fecha); no pide foto ni firma (para eso est\xE1 la entrega del cadete en la PWA); no revierte una entrega." },
222
222
  envio_procesar: { que: "Marca un env\xEDo como PROCESADO / recibido en el centro de distribuci\xF3n (queda 'En centro de distribuci\xF3n') por su tracking, sin escanear.", uso: "tracking del env\xEDo. Scopeado a tu nodo/grupo (solo proces\xE1s lo que te corresponde). Es la misma acci\xF3n 'procesar' del esc\xE1ner.", ej: "envio_procesar tracking:'NFABC123' \u2192 lo marca recibido en el centro.", no: "No mueve dinero (registra el tramo de clearing del grupo, como procesar_zona); no lo entrega ni lo asigna a un cadete." },
223
223
  envio_desde_etiqueta_ml: { que: "Registra un env\xEDo a partir de lo que VOS (Claude) le\xEDste de la foto de una etiqueta de Mercado Libre.", uso: "Le\xE9 la etiqueta: mlShipmentId + (si pod\xE9s) mlQr crudo, mlSenderId del vendedor y el destino. El vendedor se mapea por mlSenderId (cuenta vinculada) o `cliente` por nombre. Una llamada por etiqueta. Si la planilla es de d\xEDas anteriores, pas\xE1 `fecha` (solo staff, dd/mm/aaaa): fecha el env\xEDo Y toda la cadena de `avanzarA` (cada estado con su hora de ESE d\xEDa: Colectado 9, En centro 12, En camino 15, Entregado 18). Sin eso todo queda con la hora del control y se liquida en la semana equivocada. Si el env\xEDo YA estaba cargado tambi\xE9n le mueve la fecha, salvo que ese per\xEDodo ya est\xE9 liquidado (ah\xED rechaza nombrando la liquidaci\xF3n).", ej: "envio_desde_etiqueta_ml mlSenderId:'123456' mlShipmentId:'44000...' destinatario:'Juan' direccion:'...' localidad:'Avellaneda'.", no: "No mueve dinero; si no reconoce el vendedor por mlSenderId ten\xE9s que pasar `cliente`." },
@@ -386,7 +386,9 @@ const CONTROL_POR_FOTO = [
386
386
  " o que el nodo due\xF1o vincule/aprenda esa cuenta y volv\xE9s a correr la carpeta.",
387
387
  " \u2022 responsable (zona con varios responsables o sin ninguno) \u2192 pregunt\xE1 qui\xE9n lo llev\xF3 y",
388
388
  " repet\xED esa foto con `nodoEntrega`.",
389
- " \u2022 duplicado / no_ml / sin_codigo / fuera_de_red \u2192 se revisan a mano (la foto qued\xF3 copiada",
389
+ " \u2022 sin_codigo (etiqueta sin n\xFAmero = env\xEDo particular del vendedor) \u2192 le\xE9 la direcci\xF3n de la foto y repet\xED con",
390
+ " `control_foto_foto \u2026 direccion:<\u2026> localidad:<\u2026> cliente:<id>` (busca por direcci\xF3n; si no est\xE1, lo carga con tracking propio).",
391
+ " \u2022 duplicado / no_ml / fuera_de_red \u2192 se revisan a mano (la foto qued\xF3 copiada",
390
392
  " en <d\xEDa>/_sin_identificar).",
391
393
  " \u2022 erroresDeCarpeta \u2192 una carpeta que no coincide con un grupo o cadete tuyo: renombrala.",
392
394
  "",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexusflex-mcp",
3
- "version": "3.74.1",
3
+ "version": "3.75.0",
4
4
  "description": "MCP de Nexus Flex: operá tu nodo/cuenta desde un asistente de IA (altas de clientes, stock, KPIs). Login por autorización web (device-flow). NO toca dinero.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/server.mjs CHANGED
@@ -56,8 +56,9 @@ const ALLOW_PRECIOS = truthy(process.env.NEXUSFLEX_MCP_ALLOW_PRECIOS);
56
56
 
57
57
  // ATADO CON: backend/src/services/mcp-remote.ts (MCP_VERSION + NOVEDADES + mismos tools, salvo SOLO_REMOTO)
58
58
  // y mcp/package.json. Lo verifica backend/src/coherencia.test.ts. Ver CLAUDE.md → "Cosas que van juntas".
59
- const MCP_VERSION = "3.74.1"; // bumpear junto con package.json + backend/services/mcp-remote.ts
59
+ const MCP_VERSION = "3.75.0"; // bumpear junto con package.json + backend/services/mcp-remote.ts
60
60
  const NOVEDADES = [
61
+ "3.75.0 — CONTROL POR FOTO: ENVÍO PARTICULAR SIN NÚMERO. Una etiqueta que el vendedor imprimió él mismo (sin QR ni tracking) ya no se queda trabada en 'sin código': si leés la dirección, `control_foto_foto` acepta `direccion` (+ `localidad`, `destinatario`, `telefono`) con `cliente` o `nodo`, busca si ya está cargado a esa dirección (te avisa del posible duplicado) y, si no, lo da de alta con un tracking propio de Nexus Flex. La pantalla Control por foto tiene los mismos campos. No mueve dinero.",
61
62
  "3.74.1 — CONTROL POR FOTO: un paquete que está el mismo día en DADOS y en RECIBIDOS es el MISMO paquete (te lo dieron y lo pasaste), no un duplicado. Vale cómo salió en DADOS; la foto de RECIBIDOS (el respaldo por si algo no se registró) solo se suma al envío. `control_foto_carpeta` procesa primero DADOS y después RECIBIDOS.",
62
63
  "3.74.0 — RECLAMOS DE VENDEDORES: nuevo `reclamo_responder` (responder, cerrar o reabrir el reclamo que un vendedor dejó sobre su liquidación; la respuesta la lee en su portal). Se usa junto con `liquidacion_excluir_envio` / `liquidacion_reincluir_envio`: primero corregís el cobro, después contestás con el nuevo total. Es lo mismo que la pantalla Reclamos de vendedores. Además `liquidacion_cobro_parcial`: cuando el comprador pagó en destino MENOS que el flete (ej. zona media cobrada como cercana), lo cobrado se da por pagado y el envío sigue en la liquidación por la diferencia; con `montoCobrado` 0 se quita el ajuste. Y el cierre automático de un reclamo ya no responde con un solo envío y un total viejo: espera a que estén atendidos todos los envíos del reclamo. Además la app y el MCP validan que el reclamo sea de un cliente de TU nodo. Solo texto y estado: no mueve dinero. Requiere permiso finanzas.",
63
64
  "3.73.0 — CONTROL POR FOTO MÁS SEGURO: el MCP de la PC solo puede leer y crear adentro de UNA carpeta, la que elegís al instalar el plugin de Nexus Flex (si no elegís ninguna: Documentos\\Control por foto, que se crea sola). `control_foto_preparar`, `control_foto_carpeta` y `control_foto_foto` toman las rutas desde ahí (podés pasar solo 'Lunes 14-9-2026') y rechazan cualquier ruta de afuera o un acceso directo que apunte afuera. `control_foto_estructura` te dice cuál es la carpeta. No mueve dinero.",
@@ -335,6 +336,10 @@ function registrarControlFoto() {
335
336
  simular: z.boolean().optional(),
336
337
  nodoEntrega: zStr().describe("Respuesta: nodo (nombre o id) que lo llevó, cuando la zona tiene varios responsables"),
337
338
  cliente: zStr().describe("Respuesta: id del cliente dueño de una cuenta de ML desconocida"),
339
+ direccion: zStr().describe("Envío PARTICULAR sin número (etiqueta propia del vendedor, no se lee QR ni tracking): la dirección que leés de la foto. Busca si ya está cargado (misma dirección) y, si no, lo da de alta con un tracking propio de Nexus Flex"),
340
+ localidad: zStr().describe("Envío particular: localidad"),
341
+ destinatario: zStr().describe("Envío particular: destinatario (opcional)"),
342
+ telefono: zStr().describe("Envío particular: teléfono (opcional)"),
338
343
  nodo: zNodo(),
339
344
  },
340
345
  }, async (a) => run(async () => {
@@ -345,7 +350,7 @@ function registrarControlFoto() {
345
350
  if (permitida.error) return permitida.error;
346
351
  const foto = permitida.ruta;
347
352
  if (!fs.existsSync(foto) || !EXT_FOTO.test(foto)) return { ok: false, status: 400, data: { message: `No encuentro la foto ${a.ruta}.` } };
348
- return api("POST", "/control-foto/foto", { imagen: fs.readFileSync(foto).toString("base64"), carpeta: a.carpeta, fecha: a.fecha, simular: a.simular === true, nodoEntrega: a.nodoEntrega, cliente: a.cliente, nombreArchivo: path.basename(foto), nodo: a.nodo });
353
+ return api("POST", "/control-foto/foto", { imagen: fs.readFileSync(foto).toString("base64"), carpeta: a.carpeta, fecha: a.fecha, simular: a.simular === true, nodoEntrega: a.nodoEntrega, cliente: a.cliente, nombreArchivo: path.basename(foto), direccion: a.direccion, localidad: a.localidad, destinatario: a.destinatario, telefono: a.telefono, nodo: a.nodo });
349
354
  }));
350
355
 
351
356
  tool("control_foto_carpeta", {
@@ -45,7 +45,8 @@ Mostrá un resumen corto por día: fotos, ok, altas nuevas, preguntas y errores
45
45
 
46
46
  - **cuentasMLDesconocidas**: preguntá de qué nodo y cliente es cada cuenta. Mostrá el vendedor, la marca a mano y la foto de ejemplo. Con el id del cliente: `control_foto_foto ruta:<foto> carpeta:<…> fecha:<…> cliente:<id>`. Si es un vendedor de otro nodo, puede vincular o aprender la cuenta ese nodo, y después se vuelve a correr la carpeta.
47
47
  - **responsable** (la zona tiene varios responsables o ninguno): preguntá quién lo llevó y repetí la foto con `nodoEntrega`.
48
- - **duplicado / no_ml / sin_codigo / fuera_de_red**: van a revisión manual. La foto quedó copiada en `<día>/_sin_identificar`.
48
+ - **sin_codigo** (la etiqueta no tiene número: es un envío particular que imprimió el vendedor): leé la dirección de la foto (y localidad/destinatario si se ven) y repetí `control_foto_foto ruta:<foto> carpeta:<…> fecha:<…> direccion:<…> localidad:<…>` con `cliente:<id>` o `nodo:<…>` (el nodo que te lo dio, queda sin vendedor). Busca por dirección si ya está cargado; si no, lo carga con un tracking propio de Nexus Flex. Si la dirección no se lee, no la inventes: va a revisión manual.
49
+ - **duplicado / no_ml / fuera_de_red**: van a revisión manual. La foto quedó copiada en `<día>/_sin_identificar`.
49
50
  - **erroresDeCarpeta**: una carpeta no coincide con un grupo o cadete del nodo. Que la renombren (con `control_foto_estructura` a la vista).
50
51
 
51
52
  **Más cómodo:** al aplicar, lo dudoso se sube solo a la app, en **Logística → 📷 Control por foto**. Ahí cada foto se ve grande y se elige: