xonecode 0.26.1 → 0.28.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 (36) hide show
  1. package/apps/web/dist/assets/{EditorDeFichero-BW6i19HW.js → EditorDeFichero-ChyJtiiz.js} +1 -1
  2. package/apps/web/dist/assets/{index-CJycg35E.js → index-CFIrUOmW.js} +84 -84
  3. package/apps/web/dist/assets/{index-DICdq4UC.css → index-IptObD2z.css} +1 -1
  4. package/apps/web/dist/assets/{php-DxWUQTjM.js → php-B91ZcS-9.js} +1 -1
  5. package/apps/web/dist/assets/{ruby-gCKsUWxP.js → ruby-DrxrTSz0.js} +1 -1
  6. package/apps/web/dist/index.html +2 -2
  7. package/dist/agent/dispositivos/hotswap.js +27 -0
  8. package/dist/agent/dispositivos/hotswap.js.map +1 -1
  9. package/dist/agent/dispositivos/lanzamientoEnMaquina.js +33 -1
  10. package/dist/agent/dispositivos/lanzamientoEnMaquina.js.map +1 -1
  11. package/dist/agent/dispositivos/recargaEnAparato.js +149 -0
  12. package/dist/agent/dispositivos/recargaEnAparato.js.map +1 -0
  13. package/dist/agent/grafo/arbolDeProyecto.js +34 -11
  14. package/dist/agent/grafo/arbolDeProyecto.js.map +1 -1
  15. package/dist/agent/grafo/codificacionDelProyecto.js +282 -0
  16. package/dist/agent/grafo/codificacionDelProyecto.js.map +1 -0
  17. package/dist/agent/grafo/proyecto.js +6 -1
  18. package/dist/agent/grafo/proyecto.js.map +1 -1
  19. package/dist/agent/motores/trueforge/sesionTrueforge.js +4 -1
  20. package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
  21. package/dist/agent/sesiones/baseDeFichero.js +8 -8
  22. package/dist/agent/sesiones/baseDeFichero.js.map +1 -1
  23. package/dist/agent/subagentes/escrituraExterna.js +4 -1
  24. package/dist/agent/subagentes/escrituraExterna.js.map +1 -1
  25. package/dist/agent/turno/turnoReal.js +4 -1
  26. package/dist/agent/turno/turnoReal.js.map +1 -1
  27. package/dist/core/codificacion.js +134 -0
  28. package/dist/core/codificacion.js.map +1 -0
  29. package/dist/core/recargaEnCaliente.js +114 -0
  30. package/dist/core/recargaEnCaliente.js.map +1 -0
  31. package/dist/web/servidor/arranque.js +184 -5
  32. package/dist/web/servidor/arranque.js.map +1 -1
  33. package/dist/web/servidor/transporte.js.map +1 -1
  34. package/package.json +1 -1
  35. package/skills/xone-hotswap/scripts/xone-desplegar-android +62 -24
  36. package/skills/xone-hotswap/scripts/xone-recargar-android +23 -1
@@ -1 +1 @@
1
- {"version":3,"file":"transporte.js","sourceRoot":"","sources":["../../../src/web/servidor/transporte.ts"],"names":[],"mappings":"AA4HA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,aAAa;IACb,cAAc;IACd,UAAU;IACV,aAAa;IACb,UAAU;IACV,sBAAsB;CACd,CAAC;AAGX,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,CAAU,CAAC;AAijCrG;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,WAAW,CAAC,CAAQ;IAClC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,uFAAuF;QACvF,uCAAuC;QACvC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE;QACvB,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM;QACjC,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QACvD,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QACvD,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC7D,GAAG,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QAC1D,GAAG,CAAC,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACtE,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC7D,GAAG,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS;YAC3B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,SAAS,EAAE;oBACT,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS;oBAChC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO;oBAC5B,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;oBACpF,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;iBAClF;aACF,CAAC;QACN,GAAG,CAAC,CAAC,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC;KAChF,CAAC;AACJ,CAAC;AAstBD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,gBAAgB,GAA2C,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC;AAE/G,MAAM,UAAU,eAAe,CAAC,KAA4B;IAC1D,MAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,MAAM,eAAe,GAAmB,EAAE,CAAC;IAC3C;8FAC0F;IAC1F,MAAM,SAAS,GAAG,IAAI,GAAG,EAAY,CAAC;IACtC;;;OAGG;IACH,MAAM,OAAO,GAAG,IAAI,GAAG,EAAY,CAAC;IACpC;;;;OAIG;IACH,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,OAAO;QACL,QAAQ,CAAC,MAAM;YACb,UAAU,GAAG,IAAI,CAAC;YAClB,IAAI,MAAM,KAAK,SAAS;gBAAE,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QACtB,CAAC;QACD,WAAW,CAAC,MAAM;YAChB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACzB,iFAAiF;gBACjF,sCAAsC;gBACtC,IAAI,SAAS,CAAC,IAAI,GAAG,CAAC;oBAAE,OAAO;YACjC,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,KAAK,EAAE,CAAC;gBAClB,mFAAmF;gBACnF,+EAA+E;gBAC/E,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;YACD,UAAU,GAAG,KAAK,CAAC;YACnB,KAAK,MAAM,OAAO,IAAI,eAAe;gBAAE,OAAO,EAAE,CAAC;QACnD,CAAC;QACD,MAAM,CAAC,MAAM;YACX,IAAI,MAAM,KAAK,SAAS;gBAAE,SAAS,CAAC,KAAK,EAAE,CAAC;;gBACvC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,SAAS,EAAE,GAAG,EAAE,CAAC,UAAU;QAC3B,KAAK,CAAC,MAAM;YACV,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpB,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;QACtB,CAAC;QACD,YAAY,CAAC,MAAM;YACjB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;QACD,MAAM,CAAC,OAAO;YACZ,IAAI,OAAO,CAAC,KAAK,KAAK,YAAY;gBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxD,sFAAsF;YACtF,kCAAkC;YAClC,KAAK,MAAM,QAAQ,IAAI,SAAS;gBAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;YACpD,+DAA+D;YAC/D,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,OAAO;YACjD,KAAK,MAAM,KAAK,IAAI,OAAO;gBAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;QACD,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK;QACrB,aAAa,CAAC,OAAO;YACnB,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"transporte.js","sourceRoot":"","sources":["../../../src/web/servidor/transporte.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xonecode",
3
- "version": "0.26.1",
3
+ "version": "0.28.0",
4
4
  "description": "Consola CLI y harness de agente para desarrollar aplicaciones XOne",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -359,6 +359,68 @@ function exigirAparato() {
359
359
  const cuerpo = crearZip(process.cwd(), [".xonecode", ".git"]);
360
360
  console.log(` ${(cuerpo.length / 1024).toFixed(0)} KB`);
361
361
 
362
+ const cliente = join(import.meta.dirname, "xone-hotswap");
363
+ /**
364
+ * **En `clave=valor`, que es lo único que el cliente entiende.**
365
+ *
366
+ * Esto mandaba `JSON.stringify(comando)` y se rompió ENTERO el día que el cliente dejó de
367
+ * aceptar JSON: el objeto se metía como NOMBRE del comando, el aparato contestaba
368
+ * `Unknown command: {…}` y el despliegue no lanzaba nada. Lanzar la app, pedir el árbol y
369
+ * capturar —las tres cosas que hace este paso— pasaban por aquí, así que se cayeron las
370
+ * tres a la vez, y en silencio: el script reintenta diez veces y acaba diciendo que el
371
+ * canal no levantó, que manda a mirar el puerto y el paquete en vez de al cliente.
372
+ *
373
+ * La conversión es la misma que hace el cliente al revés: cada campo que no es `command`
374
+ * sale como `clave=valor`, y un objeto o un array se serializan porque el tipado del
375
+ * cliente los reconoce por la forma.
376
+ */
377
+ const mandar = (comando) => {
378
+ const { command, ...resto } = comando;
379
+ const pares = Object.entries(resto).map(([k, v]) =>
380
+ `${k}=${typeof v === "object" && v !== null ? JSON.stringify(v) : String(v)}`,
381
+ );
382
+ // El hijo habla por el MISMO puerto que el túnel de arriba, aunque venga de `--puerto`.
383
+ return execFileSync(NODE, [cliente, command, ...pares], { encoding: "utf8", env: { ...process.env, HOTSWAP_URL: process.env.HOTSWAP_URL ?? `wss://127.0.0.1:${PUERTO}/hotswap` } }).trim();
384
+ };
385
+ const esperar = (segundos) => dormir(segundos);
386
+
387
+ /**
388
+ * **El servidor del framework, ANTES de subir: la subida va por él.** Medido en el emulador: con el
389
+ * framework parado (`am force-stop`) la subida moría con un error de TLS, porque el túnel acepta y no
390
+ * hay nadie detrás; el reinicio del paso 4 —lo único que lo arrancaba— llega DESPUÉS. Se pregunta una
391
+ * vez (`getAllElements` contesta «App is not running» con el framework vivo y sin app, y el cliente
392
+ * sale con error si no hay servidor); si no contesta, se arranca su pantalla y se espera a que conteste.
393
+ * Es la misma regla que Ejecutar (`lanzamientoEnMaquina.ts`).
394
+ */
395
+ const contesta = () => {
396
+ try {
397
+ // Con su stderr CALLADO: aquí que falle es la respuesta, no un error, y la línea del cliente
398
+ // («no se pudo hablar con el aparato») haría creer que el despliegue va mal.
399
+ execFileSync(NODE, [cliente, "getAllElements", "format=xone"], {
400
+ encoding: "utf8",
401
+ stdio: ["ignore", "pipe", "ignore"],
402
+ env: { ...process.env, HOTSWAP_URL: process.env.HOTSWAP_URL ?? `wss://127.0.0.1:${PUERTO}/hotswap` },
403
+ });
404
+ return true;
405
+ } catch {
406
+ return false;
407
+ }
408
+ };
409
+ if (!contesta()) {
410
+ console.log(" el servidor del framework no contesta: se arranca su pantalla");
411
+ adb("shell", "am", "start", "-n", ACTIVIDAD);
412
+ let arranco = false;
413
+ for (let intento = 1; intento <= 60 && !arranco; intento++) {
414
+ esperar(1);
415
+ arranco = contesta();
416
+ }
417
+ if (!arranco) {
418
+ console.error(`el servidor del framework no arrancó en 60 s. Comprueba que ${PAQUETE} está instalado.`);
419
+ process.exit(1);
420
+ }
421
+ console.log(" el servidor del framework ya contesta");
422
+ }
423
+
362
424
  console.log(`3/5 subiendo a ${app}`);
363
425
  const url = `https://127.0.0.1:${PUERTO}/file_upload?file=debug_app_update.zip&appName=${encodeURIComponent(app)}`;
364
426
  const respuesta = await fetch(url, {
@@ -385,30 +447,6 @@ function exigirAparato() {
385
447
  adb("shell", "am", "start", "-n", ACTIVIDAD);
386
448
 
387
449
  console.log("5/5 esperando al canal, lanzando y comprobando que está VIVA");
388
- const cliente = join(import.meta.dirname, "xone-hotswap");
389
- /**
390
- * **En `clave=valor`, que es lo único que el cliente entiende.**
391
- *
392
- * Esto mandaba `JSON.stringify(comando)` y se rompió ENTERO el día que el cliente dejó de
393
- * aceptar JSON: el objeto se metía como NOMBRE del comando, el aparato contestaba
394
- * `Unknown command: {…}` y el despliegue no lanzaba nada. Lanzar la app, pedir el árbol y
395
- * capturar —las tres cosas que hace este paso— pasaban por aquí, así que se cayeron las
396
- * tres a la vez, y en silencio: el script reintenta diez veces y acaba diciendo que el
397
- * canal no levantó, que manda a mirar el puerto y el paquete en vez de al cliente.
398
- *
399
- * La conversión es la misma que hace el cliente al revés: cada campo que no es `command`
400
- * sale como `clave=valor`, y un objeto o un array se serializan porque el tipado del
401
- * cliente los reconoce por la forma.
402
- */
403
- const mandar = (comando) => {
404
- const { command, ...resto } = comando;
405
- const pares = Object.entries(resto).map(([k, v]) =>
406
- `${k}=${typeof v === "object" && v !== null ? JSON.stringify(v) : String(v)}`,
407
- );
408
- // El hijo habla por el MISMO puerto que el túnel de arriba, aunque venga de `--puerto`.
409
- return execFileSync(NODE, [cliente, command, ...pares], { encoding: "utf8", env: { ...process.env, HOTSWAP_URL: process.env.HOTSWAP_URL ?? `wss://127.0.0.1:${PUERTO}/hotswap` } }).trim();
410
- };
411
- const esperar = (segundos) => dormir(segundos);
412
450
 
413
451
  /**
414
452
  * **El canal no está en pie justo después del reinicio**, y esto se descubrió corriéndolo:
@@ -206,6 +206,28 @@ function clase(rel) {
206
206
  return "relanzar";
207
207
  }
208
208
 
209
+ /**
210
+ * Lo que se le da a `loadCollection`: el MISMO XML en UTF-8 y con el prólogo diciendo UTF-8.
211
+ * MEDIDO (5.0.5.5dev): con los bytes de un `.xne` en ISO-8859-15, cada tilde salía doble («Año»).
212
+ * La misma regla que `core/recargaEnCaliente.ts#xmlParaCargarEnMemoria`. Solo para memoria: a disco
213
+ * va el fichero tal cual, que es lo que el framework lee al relanzar.
214
+ */
215
+ function xmlEnUtf8(bytes) {
216
+ let texto;
217
+ try {
218
+ texto = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
219
+ } catch {
220
+ const cabeza = bytes.subarray(0, 256).toString("latin1");
221
+ const tabla = /encoding\s*=\s*["'][^"']*(8859-15|latin-?9)/i.test(cabeza) ? "iso-8859-15" : "windows-1252";
222
+ texto = new TextDecoder(tabla).decode(bytes);
223
+ }
224
+ texto = texto.replace(/^\uFEFF/, "").replace(
225
+ /^(\s*<\?xml[^?]*?encoding\s*=\s*)(["'])[^"']*\2/i,
226
+ (_t, antes, comilla) => `${antes}${comilla}UTF-8${comilla}`,
227
+ );
228
+ return Buffer.from(texto, "utf8");
229
+ }
230
+
209
231
  // 1. Subir a disco (siempre): lo que solo está en memoria se pierde al relanzar.
210
232
  const subidos = [];
211
233
  for (const rel of cambiados) {
@@ -238,7 +260,7 @@ if (hayQueRelanzar) {
238
260
  } else {
239
261
  for (const [f, c] of clases) {
240
262
  if (c === "coleccion") {
241
- const r = mandar("loadCollection", { xmlNode: readFileSync(f).toString("base64"), encoding: "UTF-8" });
263
+ const r = mandar("loadCollection", { xmlNode: xmlEnUtf8(readFileSync(f)).toString("base64"), encoding: "UTF-8" });
242
264
  if (r.result !== true) fallos.push(`${f}: loadCollection ${r.exceptionMessage ?? r.status ?? "sin motivo"}`);
243
265
  else console.log(` ${f} → colección recargada en caliente`);
244
266
  } else {