xonecode 0.17.1 → 0.19.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.
Files changed (86) hide show
  1. package/apps/web/dist/assets/{index-BRVuyPBf.js → index-BvPUqjUm.js} +72 -72
  2. package/apps/web/dist/assets/{index-DLfF2uEK.css → index-CGEXMJBx.css} +1 -1
  3. package/apps/web/dist/assets/{php-B5LpMCn-.js → php-Dk28VW45.js} +1 -1
  4. package/apps/web/dist/assets/{ruby-Clm-qfwM.js → ruby-CPzEcmdp.js} +1 -1
  5. package/apps/web/dist/index.html +2 -2
  6. package/dist/agent/config/iconosEnRed.js +47 -0
  7. package/dist/agent/config/iconosEnRed.js.map +1 -0
  8. package/dist/agent/dispositivos/decodificarImagen.js +62 -0
  9. package/dist/agent/dispositivos/decodificarImagen.js.map +1 -0
  10. package/dist/agent/grafo/buscarIcono.js +92 -0
  11. package/dist/agent/grafo/buscarIcono.js.map +1 -0
  12. package/dist/agent/grafo/compararCapturas.js +103 -0
  13. package/dist/agent/grafo/compararCapturas.js.map +1 -0
  14. package/dist/agent/grafo/criticaVisual.js +23 -3
  15. package/dist/agent/grafo/criticaVisual.js.map +1 -1
  16. package/dist/agent/grafo/diferenciaDeCapturas.js +88 -0
  17. package/dist/agent/grafo/diferenciaDeCapturas.js.map +1 -0
  18. package/dist/agent/grafo/generarFondoSvg.js +83 -0
  19. package/dist/agent/grafo/generarFondoSvg.js.map +1 -0
  20. package/dist/agent/grafo/lectorDeReferencias.js +19 -0
  21. package/dist/agent/grafo/lectorDeReferencias.js.map +1 -0
  22. package/dist/agent/grafo/xoneAgent.js +8 -1
  23. package/dist/agent/grafo/xoneAgent.js.map +1 -1
  24. package/dist/agent/motores/trueforge/eventosTrueforge.js +11 -1
  25. package/dist/agent/motores/trueforge/eventosTrueforge.js.map +1 -1
  26. package/dist/agent/motores/trueforge/modeloLangchain.js +5 -0
  27. package/dist/agent/motores/trueforge/modeloLangchain.js.map +1 -1
  28. package/dist/agent/motores/trueforge/sesionTrueforge.js +67 -6
  29. package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
  30. package/dist/agent/subagentes/agentesEnDisco.js +26 -2
  31. package/dist/agent/subagentes/agentesEnDisco.js.map +1 -1
  32. package/dist/agent/turno/diagnosticoDeTools.js +32 -3
  33. package/dist/agent/turno/diagnosticoDeTools.js.map +1 -1
  34. package/dist/agent/turno/informeDeTraza.js +54 -4
  35. package/dist/agent/turno/informeDeTraza.js.map +1 -1
  36. package/dist/agent/turno/registroDeFallos.js +6 -1
  37. package/dist/agent/turno/registroDeFallos.js.map +1 -1
  38. package/dist/agent/turno/resumenDeTool.js +9 -0
  39. package/dist/agent/turno/resumenDeTool.js.map +1 -1
  40. package/dist/agent/turno/turnoReal.js +8 -2
  41. package/dist/agent/turno/turnoReal.js.map +1 -1
  42. package/dist/cli/run.js +11 -0
  43. package/dist/cli/run.js.map +1 -1
  44. package/dist/core/agentes.js +29 -1
  45. package/dist/core/agentes.js.map +1 -1
  46. package/dist/core/analisisDeSesion.js +198 -0
  47. package/dist/core/analisisDeSesion.js.map +1 -0
  48. package/dist/core/compararCapturas.js +339 -0
  49. package/dist/core/compararCapturas.js.map +1 -0
  50. package/dist/core/fallos.js.map +1 -1
  51. package/dist/core/fondosSvg.js +223 -0
  52. package/dist/core/fondosSvg.js.map +1 -0
  53. package/dist/core/iconos.js +135 -0
  54. package/dist/core/iconos.js.map +1 -0
  55. package/dist/core/modoDeEscritura.js +22 -0
  56. package/dist/core/modoDeEscritura.js.map +1 -1
  57. package/dist/core/notify.js +8 -0
  58. package/dist/core/notify.js.map +1 -1
  59. package/dist/core/nucleoXone.js +111 -0
  60. package/dist/core/nucleoXone.js.map +1 -0
  61. package/dist/core/paqueteDeSoporte.js +118 -0
  62. package/dist/core/paqueteDeSoporte.js.map +1 -0
  63. package/dist/core/ports.js +31 -0
  64. package/dist/core/ports.js.map +1 -1
  65. package/dist/core/referenciasDeImagen.js +55 -0
  66. package/dist/core/referenciasDeImagen.js.map +1 -0
  67. package/dist/web/servidor/arranque.js +110 -0
  68. package/dist/web/servidor/arranque.js.map +1 -1
  69. package/dist/web/servidor/sesiones.js +8 -0
  70. package/dist/web/servidor/sesiones.js.map +1 -1
  71. package/dist/web/servidor/soporte.js +571 -0
  72. package/dist/web/servidor/soporte.js.map +1 -0
  73. package/dist/web/servidor/transporte.js.map +1 -1
  74. package/package.json +4 -1
  75. package/skills/artifacts-builder/reference/estilo.md +3 -6
  76. package/skills/xone-development/SKILL.md +1 -5
  77. package/skills/xone-development/references/css/propiedades-y-herencia.md +2 -0
  78. package/skills/xone-development/references/fundamentos/errores-comunes.md +15 -3
  79. package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +2 -0
  80. package/skills/xone-hotswap/SKILL.md +10 -0
  81. package/skills/xone-hotswap/references/comandos.md +14 -0
  82. package/skills/xone-hotswap/scripts/xone-recargar-android +269 -0
  83. package/skills/xone-plan-builder/SKILL.md +8 -0
  84. package/skills/xone-plan-builder/references/TASKS-FORMAT.md +8 -0
  85. package/skills/xone-project-generator/SKILL.md +1 -1
  86. package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +1 -0
@@ -113,6 +113,8 @@ import { crearGestorJira } from "../../agent/conectores/gestorJira.js";
113
113
  import { crearGestorNotion } from "../../agent/conectores/gestorNotion.js";
114
114
  import { admiteMiasDelVinculo, motivoDeProyectoInaceptable, transicionPropuesta, comentarioDeCierre, } from "../../core/gestorDeTareas.js";
115
115
  import { datosDeCierre } from "./datosDeCierre.js";
116
+ import { ErrorDeDescargaCortada, escribirPaquete, listarSoporte, motivoParaNoExportar } from "./soporte.js";
117
+ import { nombreDelPaquete } from "../../core/paqueteDeSoporte.js";
116
118
  /** Las dos rutas del cable. El cliente las tiene escritas en `apps/web/src/conexion.ts`. */
117
119
  /**
118
120
  * Cuánto se espera al aviso de «lo que ya había sin commitear» antes de anunciar sin él.
@@ -153,6 +155,12 @@ export const RUTA_ACCION = "/accion";
153
155
  * el contrato de las skills que los escriben es «autocontenido».
154
156
  */
155
157
  export const RUTA_ARTEFACTO = "/artefacto";
158
+ /**
159
+ * `GET /soporte?tipo=<proyecto|chat|tarea>&proyecto=<id>[&id=<id>]` — el PAQUETE de soporte
160
+ * (`soporte.ts`), escrito en streaming. Del cable llegan IDs; la raíz y lo que existe los decide
161
+ * el servidor con su propio listado e índice.
162
+ */
163
+ export const RUTA_SOPORTE = "/soporte";
156
164
  /**
157
165
  * `POST /skill?nombre=<fichero.zip>&ambito=<global|proyecto>` — los BYTES de un `.zip`.
158
166
  *
@@ -4206,6 +4214,94 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
4206
4214
  });
4207
4215
  respuesta.end(leido.datos);
4208
4216
  });
4217
+ /**
4218
+ * Lo que la pestaña Soporte necesita de UN proyecto, compuesto por el SERVIDOR a partir del
4219
+ * id: la raíz sale del listado del entorno activo (como `resumen` y `borrar`), las tareas se
4220
+ * deciden por la RAÍZ (`mismaRuta`), y lo que está en vuelo se pregunta a las consolas vivas.
4221
+ * Solo con copia bajada: sin ella no hay chats ni trazas que exportar.
4222
+ */
4223
+ const fuenteDeSoporte = (idDeProyecto) => {
4224
+ const identidad = proyectos.find((p) => p.id === idDeProyecto);
4225
+ if (entornoElegido === undefined || identidad === undefined)
4226
+ return { motivo: "ese proyecto no está en el listado del entorno activo" };
4227
+ const raiz = vestibulo.raizDeProyecto(entornoElegido, identidad.nombre);
4228
+ if (!esProyectoEnDisco(raiz))
4229
+ return { motivo: "ese proyecto no tiene copia local" };
4230
+ const cola = opciones.colaDeTareas;
4231
+ const version = opciones.version?.();
4232
+ return {
4233
+ fuente: {
4234
+ raiz,
4235
+ proyecto: identidad.nombre,
4236
+ tareas: (cola?.listar() ?? []).filter((t) => mismaRuta(t.proyecto.raiz, raiz)),
4237
+ ...(cola?.carpetaDeAdjuntos === undefined ? {} : { carpetaDeAdjuntosDeTarea: (id) => cola.carpetaDeAdjuntos(id) }),
4238
+ sesionesEnVuelo: sesionesTrabajando(),
4239
+ raizEnVuelo: [...raicesTrabajando()].some((r) => mismaRuta(r, raiz)),
4240
+ ...(version === undefined ? {} : { version: version.commit === undefined ? version.version : `${version.version}+${version.commit}` }),
4241
+ ...(opciones.topeDeContexto === undefined ? {} : { topeDeContexto: (modelo) => opciones.topeDeContexto(raiz, modelo) }),
4242
+ },
4243
+ };
4244
+ };
4245
+ /**
4246
+ * `GET /soporte` — el paquete, escrito MIENTRAS se lee (`soporte.ts`): un proyecto entero no
4247
+ * se monta en memoria en el proceso que sirve todos los turnos. **Con un turno en vuelo se
4248
+ * exporta igual**: es cuando más falta hace, y el manifiesto lo dice.
4249
+ *
4250
+ * Las cabeceras salen ANTES de escribir nada, así que un fallo a medias no puede volverse un
4251
+ * 500: se corta la respuesta (el navegador da la descarga por fallida) y se informa por el
4252
+ * transcript con el código del error, nunca con su mensaje (lleva rutas).
4253
+ */
4254
+ servidor.registrarRuta("GET", RUTA_SOPORTE, async (peticion, respuesta) => {
4255
+ const responder = (codigo, texto) => {
4256
+ respuesta.writeHead(codigo, { "Content-Type": "text/plain; charset=utf-8" });
4257
+ respuesta.end(texto);
4258
+ };
4259
+ const query = new URLSearchParams((peticion.url ?? "").split("?")[1] ?? "");
4260
+ const tipo = query.get("tipo");
4261
+ const idDeProyecto = query.get("proyecto");
4262
+ const id = query.get("id");
4263
+ if (idDeProyecto === null || idDeProyecto === "") {
4264
+ responder(400, "falta el proyecto");
4265
+ return;
4266
+ }
4267
+ let pedido;
4268
+ if (tipo === "proyecto")
4269
+ pedido = { tipo };
4270
+ else if ((tipo === "chat" || tipo === "tarea") && id !== null && id !== "")
4271
+ pedido = { tipo, id };
4272
+ else {
4273
+ responder(400, "pedido de soporte ilegible");
4274
+ return;
4275
+ }
4276
+ const resuelta = fuenteDeSoporte(idDeProyecto);
4277
+ if ("motivo" in resuelta) {
4278
+ responder(409, resuelta.motivo);
4279
+ return;
4280
+ }
4281
+ const motivo = motivoParaNoExportar(resuelta.fuente, pedido);
4282
+ if (motivo !== undefined) {
4283
+ responder(409, motivo);
4284
+ return;
4285
+ }
4286
+ const nombre = nombreDelPaquete(pedido.tipo, pedido.tipo === "proyecto" ? resuelta.fuente.proyecto : pedido.id, new Date());
4287
+ respuesta.writeHead(200, {
4288
+ "Content-Type": "application/zip",
4289
+ // El nombre lo compone el código con segmentos llanos: entre comillas no rompe la cabecera.
4290
+ "Content-Disposition": `attachment; filename="${nombre}"`,
4291
+ "X-Content-Type-Options": "nosniff",
4292
+ "Cache-Control": "no-store",
4293
+ });
4294
+ try {
4295
+ await escribirPaquete(resuelta.fuente, pedido, respuesta);
4296
+ respuesta.end();
4297
+ }
4298
+ catch (error) {
4299
+ // Una descarga cancelada no es un fallo que contar: quien la pidió se fue.
4300
+ if (!(error instanceof ErrorDeDescargaCortada))
4301
+ informar(`no se pudo exportar el paquete de soporte (${codigoDe(error)})`);
4302
+ respuesta.destroy();
4303
+ }
4304
+ });
4209
4305
  /**
4210
4306
  * `GET /imagen-del-proyecto?ruta=<relativa>` — una IMAGEN del proyecto abierto, para que un `.md`
4211
4307
  * de la pestaña Ficheros enseñe las suyas.
@@ -4553,6 +4649,20 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
4553
4649
  respuesta.end(JSON.stringify(foto));
4554
4650
  return;
4555
4651
  }
4652
+ if (typeof mensaje === "object" && mensaje !== null && mensaje.clase === "soporte" && mensaje.accion === "listar") {
4653
+ // El listado de la pestaña Soporte, con el análisis PREVIO de cada chat y cada tarea
4654
+ // (`core/analisisDeSesion.ts`), contestado en la propia respuesta como `resumen`.
4655
+ const resuelta = fuenteDeSoporte(mensaje.proyecto);
4656
+ if ("motivo" in resuelta) {
4657
+ respuesta.writeHead(409, { "content-type": "application/json" });
4658
+ respuesta.end(JSON.stringify({ motivo: resuelta.motivo }));
4659
+ return;
4660
+ }
4661
+ const listado = await listarSoporte(resuelta.fuente);
4662
+ respuesta.writeHead(200, { "content-type": "application/json" });
4663
+ respuesta.end(JSON.stringify(listado));
4664
+ return;
4665
+ }
4556
4666
  if (typeof mensaje === "object" && mensaje !== null && mensaje.clase === "copiaLocal" && mensaje.accion === "abrirCarpeta") {
4557
4667
  // Como `borrar`: del cable llega el ID, el nombre sale del listado del servidor y la
4558
4668
  // ruta la compone el vestíbulo. Solo con la copia BAJADA: una carpeta a medias de un alta