xonecode 0.38.35 → 0.38.37

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 (34) hide show
  1. package/apps/web/dist/assets/{EditorDeFichero-bypW6tEz.js → EditorDeFichero-B7G4n1D8.js} +1 -1
  2. package/apps/web/dist/assets/{index-BVznZu4Y.css → index-DzN1xufv.css} +1 -1
  3. package/apps/web/dist/assets/index-pdX3FkHb.js +506 -0
  4. package/apps/web/dist/assets/{php-Do7Rxy2W.js → php-C6f803Zw.js} +1 -1
  5. package/apps/web/dist/assets/{ruby-C4McYv9k.js → ruby-CNvSd4Sa.js} +1 -1
  6. package/apps/web/dist/index.html +2 -2
  7. package/dist/agent/config/configEnDisco.js +12 -0
  8. package/dist/agent/config/configEnDisco.js.map +1 -1
  9. package/dist/agent/motores/trueforge/sesionTrueforge.js +24 -2
  10. package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
  11. package/dist/agent/motores/trueforge/traerDeStitch.js +138 -90
  12. package/dist/agent/motores/trueforge/traerDeStitch.js.map +1 -1
  13. package/dist/agent/tareas/aumentador.js +18 -0
  14. package/dist/agent/tareas/aumentador.js.map +1 -1
  15. package/dist/cli/main.js +1 -0
  16. package/dist/cli/main.js.map +1 -1
  17. package/dist/core/config.js +10 -0
  18. package/dist/core/config.js.map +1 -1
  19. package/dist/core/disenoVinculado.js +9 -0
  20. package/dist/core/disenoVinculado.js.map +1 -0
  21. package/dist/core/entrega.js +4 -0
  22. package/dist/core/entrega.js.map +1 -1
  23. package/dist/core/ports.js.map +1 -1
  24. package/dist/core/stitch.js +107 -1
  25. package/dist/core/stitch.js.map +1 -1
  26. package/dist/core/tareas.js.map +1 -1
  27. package/dist/web/servidor/arranque.js +116 -11
  28. package/dist/web/servidor/arranque.js.map +1 -1
  29. package/dist/web/servidor/corredorDeTareas.js +12 -0
  30. package/dist/web/servidor/corredorDeTareas.js.map +1 -1
  31. package/dist/web/servidor/transporte.js +1 -0
  32. package/dist/web/servidor/transporte.js.map +1 -1
  33. package/package.json +1 -1
  34. package/apps/web/dist/assets/index-B8v6Pl75.js +0 -506
@@ -65,6 +65,9 @@ import { nombreDeApp } from "../../core/descriptoresDeApp.js";
65
65
  import { modelosDeMotor } from "../../agent/config/modelosDeMotor.js";
66
66
  import { crearServicioDeMotoresLocales } from "../../agent/motores/motoresLocales.js";
67
67
  import { medirDiagnosticoDeNode } from "../../agent/config/diagnosticoDeNodeEnMaquina.js";
68
+ import { CONECTOR_STITCH, marcarPantallaElegida, traerPantalla } from "../../agent/motores/trueforge/traerDeStitch.js";
69
+ import { guardarDisenoDeProyecto } from "../../agent/config/configEnDisco.js";
70
+ import { pantallaElegidaValida, pantallasConMiniatura, motivoDeProyectoDeStitchInaceptable, entradasDeStitch, textoDePantallaElegida } from "../../core/stitch.js";
68
71
  import { esMotorLocal } from "../../core/motoresLocales.js";
69
72
  import { parsear, compatibleConOpenAi, esProveedorPersonalizado, idDeProveedorPersonalizado, motivoDeEndpointInaceptable, motivoDeSlugInaceptable, nombreDeProveedor, PROVEEDORES, slugDesdeNombre, resolver, SIN_CREDENCIAL, PAPELES, } from "../../core/modelos.js";
70
73
  import { hayCredencial } from "../../cli/consola.js";
@@ -85,7 +88,7 @@ import { nombreDePersona } from "../../agent/config/persona.js";
85
88
  import { cambiosDeSesion, fotoDeApertura, olvidarSesion, parcheDeSesion } from "../../agent/sesiones/sesionGit.js";
86
89
  import { commitDeTurno, cambiosPendientes, parcheDeSubida, pendientesDeSubida, sinSeguir, trabajoSinCommitear, } from "../../agent/sesiones/gitSync.js";
87
90
  import { listarSesiones, marcarTareaDeSesion, reabrirSesion, sembrarConsumosPendientes } from "./sesiones.js";
88
- import { RUTA_ARTEFACTOS, esRutaDeArtefacto, rutaRelativaDeArtefacto } from "../../core/artefactos.js";
91
+ import { RUTA_ARTEFACTOS, carpetaDeArtefactosDeSesion, esRutaDeArtefacto, rutaRelativaDeArtefacto } from "../../core/artefactos.js";
89
92
  import { MIMES_DE_ARTEFACTO_AL_MOVIL, TOPE_DE_ARTEFACTO_AL_MOVIL, trozosDeArtefacto } from "../../core/remoto.js";
90
93
  import { arbolDeProyecto, escribirFicheroDeProyecto, iconoDelProyecto, leerFicheroDeProyecto, mimeDeImagen, motivoDeRutaInaceptable, motivoParaNoEnsenar, } from "../../agent/grafo/arbolDeProyecto.js";
91
94
  import { baseDeFichero } from "../../agent/sesiones/baseDeFichero.js";
@@ -121,7 +124,7 @@ import { filaDeTarea } from "./transporte.js";
121
124
  import { crearSesionRemota, motivoFijoDelTunel } from "./puenteRemoto.js";
122
125
  import { componerPanorama, INTERVALO_DE_PANORAMA_MS } from "../../core/panorama.js";
123
126
  import { esEsfuerzo, nivelesDeEsfuerzo } from "../../core/esfuerzo.js";
124
- import { CATALOGO_DE_CONECTORES, conectoresParaElAgente, definicionDelCable, RUTA_CALLBACK_MCP } from "../../core/conectores.js";
127
+ import { CATALOGO_DE_CONECTORES, conectoresParaElAgente, definicionDelCable, RUTA_CALLBACK_MCP, TOPE_DE_LLAMADA_MS } from "../../core/conectores.js";
125
128
  import { servicioDeConectoresCableado } from "../../agent/conectores/servicioDeConectores.js";
126
129
  import { crearGestorJira } from "../../agent/conectores/gestorJira.js";
127
130
  import { crearGestorNotion } from "../../agent/conectores/gestorNotion.js";
@@ -1717,7 +1720,9 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
1717
1720
  borrador,
1718
1721
  /** El ticket del gestor YA creado (`atenderCrearTareaEnGestor`): se copia a la tarea antes de guardarla, porque
1719
1722
  * guardar dispara al corredor y el reflejo de «empezar» tiene que encontrarlo. */
1720
- ticket) => {
1723
+ ticket,
1724
+ /** La pantalla de Stitch elegida en «Nueva tarea», tal como llega del cable: se comprueba aquí (`pantallaElegidaValida`). */
1725
+ pantallaDeStitch) => {
1721
1726
  if (opciones.colaDeTareas === undefined)
1722
1727
  return undefined;
1723
1728
  const proyecto = proyectoParaTarea(proyectoId);
@@ -1725,6 +1730,11 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
1725
1730
  informar(`no se pudo crear la tarea: el proyecto «${proyectoId}» no se pudo resolver`);
1726
1731
  return undefined;
1727
1732
  }
1733
+ const pantalla = pantallaDeStitch === undefined ? undefined : pantallaElegidaValida(pantallaDeStitch, disenoVinculadoDe(proyecto.raiz));
1734
+ if (pantallaDeStitch !== undefined && pantalla === undefined) {
1735
+ informar("no se pudo crear la tarea: esa pantalla no es del proyecto de Stitch vinculado");
1736
+ return undefined;
1737
+ }
1728
1738
  const lista = opciones.colaDeTareas.listar();
1729
1739
  if (borrador !== undefined && !esBorradorLibre(borrador, lista)) {
1730
1740
  // **No se cae a un id nuevo en silencio**, y esa es la decisión: seguir con un uuid
@@ -1746,6 +1756,7 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
1746
1756
  estado: "nuevo",
1747
1757
  creada: new Date().toISOString(),
1748
1758
  ...(ticket === undefined ? {} : { ticket }),
1759
+ ...(pantalla === undefined ? {} : { pantallaDeStitch: pantalla }),
1749
1760
  };
1750
1761
  opciones.colaDeTareas.guardar([...lista, nueva]);
1751
1762
  return { id: nueva.id };
@@ -1756,6 +1767,15 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
1756
1767
  * gestor que sabe CREAR. Sin vínculo, o con un gestor sin `crear`, `undefined` y la tarea se encola en local como
1757
1768
  * siempre (límite declarado: lo dice la ventana).
1758
1769
  */
1770
+ /** El proyecto de Stitch vinculado a esa raíz, o `undefined` (sin vínculo, o el config no se lee). */
1771
+ const disenoVinculadoDe = (raiz) => {
1772
+ try {
1773
+ return cargar(raiz).config.proyecto?.disenoVinculado;
1774
+ }
1775
+ catch {
1776
+ return undefined;
1777
+ }
1778
+ };
1759
1779
  const gestorParaTareaNueva = (proyectoId) => {
1760
1780
  const proyecto = proyectoParaTarea(proyectoId);
1761
1781
  if (proyecto === undefined)
@@ -1781,7 +1801,7 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
1781
1801
  * pierde— y se contesta 409 con el motivo. Si el ticket se creó pero el comentario no, la tarea se crea igual y se
1782
1802
  * dice: el ticket ya existe.
1783
1803
  */
1784
- const atenderCrearTareaEnGestor = async (destino, peticion, encargo, borrador) => {
1804
+ const atenderCrearTareaEnGestor = async (destino, peticion, encargo, borrador, pantallaDeStitch) => {
1785
1805
  if (opciones.colaDeTareas === undefined)
1786
1806
  return { estado: 409, cuerpo: { motivo: "esta ejecución no tiene cola de tareas" } };
1787
1807
  // El borrador se comprueba ANTES de tocar el gestor: un ticket creado para una tarea que luego no se guarda quedaría huérfano.
@@ -1816,7 +1836,7 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
1816
1836
  ...(vinculo.estados === undefined ? {} : { estados: vinculo.estados }),
1817
1837
  };
1818
1838
  // Con la línea del ticket delante (`encargoConTicket`): en Jira el comentario lleva el encargo SIN ella —ya está en el ticket—.
1819
- const nueva = atenderCrearTarea(destino.proyecto.id, peticion, encargoConTicket(encargo, ticket), borrador, ticket);
1839
+ const nueva = atenderCrearTarea(destino.proyecto.id, peticion, encargoConTicket(encargo, ticket), borrador, ticket, pantallaDeStitch);
1820
1840
  if (nueva === undefined) {
1821
1841
  return { estado: 409, cuerpo: { motivo: `se creó ${creada.clave} en el gestor, pero no la tarea local: créala de nuevo o bórrala allí` } };
1822
1842
  }
@@ -1844,7 +1864,9 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
1844
1864
  * manda el id. Sin proyecto resoluble no se pregunta a nadie: se contesta el error, que es
1845
1865
  * lo que la ventana pinta — nunca se inventa una raíz.
1846
1866
  */
1847
- const atenderAugmentar = async (augmentar, proyectoId, texto, borrador) => {
1867
+ const atenderAugmentar = async (augmentar, proyectoId, texto, borrador,
1868
+ /** La pantalla de Stitch elegida en «Nueva tarea», tal como llega: se comprueba contra el vínculo del proyecto. */
1869
+ pantallaDeStitch) => {
1848
1870
  const proyecto = proyectoParaTarea(proyectoId);
1849
1871
  if (proyecto === undefined) {
1850
1872
  emitir({
@@ -1861,7 +1883,8 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
1861
1883
  .listarAdjuntos(borrador)
1862
1884
  .map((a) => ({ nombre: a.nombre, ...(a.mime === undefined ? {} : { mime: a.mime }) }));
1863
1885
  try {
1864
- const encargo = await augmentar({ texto, proyecto, adjuntos });
1886
+ const pantalla = pantallaDeStitch === undefined ? undefined : pantallaElegidaValida(pantallaDeStitch, disenoVinculadoDe(proyecto.raiz));
1887
+ const encargo = await augmentar({ texto, proyecto, adjuntos, ...(pantalla === undefined ? {} : { pantallaDeStitch: pantalla }) });
1865
1888
  emitir({ clase: "tarea", accion: "augmentado", encargo });
1866
1889
  }
1867
1890
  catch (error) {
@@ -4724,6 +4747,54 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
4724
4747
  modelosPorMotor.set(motor, r);
4725
4748
  emitirlos(r);
4726
4749
  };
4750
+ /**
4751
+ * El DISEÑO vinculado de un proyecto (panel → Conectores, y el selector de «Nueva tarea»): qué proyecto de Stitch,
4752
+ * cuáles hay para elegir y sus pantallas con miniatura. Todo pasa por el MISMO servicio de conectores; la raíz la
4753
+ * resuelve el servidor por el id del proyecto (o la del abierto). Lo que dice Stitch al fallar va recortado.
4754
+ */
4755
+ const atenderDiseno = async (m) => {
4756
+ const raiz = m.proyecto !== undefined ? proyectoParaTarea(m.proyecto)?.raiz : vestibulo.proyectoAbierto()?.raiz;
4757
+ const responder = (cuerpo) => emitir({ clase: "diseno", ...(m.proyecto === undefined ? {} : { proyecto: m.proyecto }), ...cuerpo });
4758
+ if (raiz === undefined)
4759
+ return responder({ error: "no hay un proyecto abierto con copia" });
4760
+ const vinculo = () => disenoVinculadoDe(raiz) ?? null;
4761
+ if (m.accion === "estado")
4762
+ return responder({ vinculo: vinculo() });
4763
+ if (m.accion === "desvincular") {
4764
+ guardarDisenoDeProyecto(raiz, undefined);
4765
+ return responder({ vinculo: null });
4766
+ }
4767
+ if (m.accion === "vincular") {
4768
+ if (motivoDeProyectoDeStitchInaceptable(m.vinculo.proyecto) !== undefined || typeof m.vinculo.nombre !== "string" || m.vinculo.nombre.trim() === "") {
4769
+ return responder({ error: "ese proyecto de Stitch no vale" });
4770
+ }
4771
+ guardarDisenoDeProyecto(raiz, { proyecto: m.vinculo.proyecto, nombre: m.vinculo.nombre.trim().slice(0, 200) });
4772
+ return responder({ vinculo: vinculo() });
4773
+ }
4774
+ if (servicioConectores === undefined)
4775
+ return responder({ error: "esta ejecución no tiene conectores" });
4776
+ const llamar = (tool, args) => servicioConectores.llamar(CONECTOR_STITCH, tool, args, { topeMs: TOPE_DE_LLAMADA_MS });
4777
+ try {
4778
+ if (m.accion === "proyectos") {
4779
+ const proyectos = [];
4780
+ for (const args of [{}, { filter: "view=shared" }]) {
4781
+ for (const p of entradasDeStitch(await llamar("list_projects", args), "projects")) {
4782
+ if (!proyectos.some((q) => q.name === p.name))
4783
+ proyectos.push(p);
4784
+ }
4785
+ }
4786
+ return responder({ proyectos });
4787
+ }
4788
+ const v = disenoVinculadoDe(raiz);
4789
+ if (v === undefined)
4790
+ return responder({ vinculo: null, pantallas: [] });
4791
+ const pantallas = pantallasConMiniatura(await llamar("list_screens", { projectId: v.proyecto.replace(/^projects\//, "") }));
4792
+ return responder({ vinculo: v, pantallas });
4793
+ }
4794
+ catch (e) {
4795
+ return responder({ error: sinCorreos(e instanceof Error ? e.message : String(e)).slice(0, 200) });
4796
+ }
4797
+ };
4727
4798
  /** Ajustes → General → Node: se mide al pulsar, sin caché (lo que se arregla en la máquina se ve al volver a pulsar). */
4728
4799
  const atenderDiagnosticoDeNode = async () => {
4729
4800
  if (opciones.diagnosticoDeNode === undefined)
@@ -6878,20 +6949,20 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
6878
6949
  // si el gestor la creó). Sin él, el camino de siempre.
6879
6950
  const enGestor = mensaje.accion === "crear" ? gestorParaTareaNueva(mensaje.proyecto) : undefined;
6880
6951
  if (mensaje.accion === "crear" && enGestor !== undefined) {
6881
- const r = await atenderCrearTareaEnGestor(enGestor, mensaje.peticion, mensaje.encargo, mensaje.borrador);
6952
+ const r = await atenderCrearTareaEnGestor(enGestor, mensaje.peticion, mensaje.encargo, mensaje.borrador, mensaje.pantallaDeStitch);
6882
6953
  respuesta.writeHead(r.estado, { "content-type": "application/json" });
6883
6954
  respuesta.end(JSON.stringify(r.cuerpo));
6884
6955
  return;
6885
6956
  }
6886
6957
  if (mensaje.accion === "crear" && opciones.colaDeTareas !== undefined) {
6887
- const creada = atenderCrearTarea(mensaje.proyecto, mensaje.peticion, mensaje.encargo, mensaje.borrador);
6958
+ const creada = atenderCrearTarea(mensaje.proyecto, mensaje.peticion, mensaje.encargo, mensaje.borrador, undefined, mensaje.pantallaDeStitch);
6888
6959
  if (creada !== undefined) {
6889
6960
  opciones.revisarTareas?.();
6890
6961
  emitirTareas();
6891
6962
  }
6892
6963
  }
6893
6964
  else if (mensaje.accion === "augmentar" && opciones.augmentar !== undefined) {
6894
- void atenderAugmentar(opciones.augmentar, mensaje.proyecto, mensaje.peticion, mensaje.borrador);
6965
+ void atenderAugmentar(opciones.augmentar, mensaje.proyecto, mensaje.peticion, mensaje.borrador, mensaje.pantallaDeStitch);
6895
6966
  }
6896
6967
  else if (mensaje.accion === "feedback" && opciones.colaDeTareas !== undefined) {
6897
6968
  darFeedbackATarea(mensaje.id, mensaje.texto);
@@ -7171,6 +7242,17 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
7171
7242
  respuesta.end();
7172
7243
  return;
7173
7244
  }
7245
+ if (typeof mensaje === "object" &&
7246
+ mensaje !== null &&
7247
+ mensaje.clase === "diseno" &&
7248
+ ["estado", "proyectos", "vincular", "desvincular", "pantallas"].includes(mensaje.accion) &&
7249
+ (mensaje.proyecto === undefined || typeof mensaje.proyecto === "string") &&
7250
+ (mensaje.accion !== "vincular" || (typeof mensaje.vinculo === "object" && mensaje.vinculo !== null))) {
7251
+ void atenderDiseno(mensaje).catch(contar);
7252
+ respuesta.writeHead(204);
7253
+ respuesta.end();
7254
+ return;
7255
+ }
7174
7256
  if (typeof mensaje === "object" && mensaje !== null && mensaje.clase === "diagnosticoNode") {
7175
7257
  void atenderDiagnosticoDeNode().catch(contar);
7176
7258
  respuesta.writeHead(204);
@@ -7841,7 +7923,7 @@ async function cuantosDeLaSesion(raiz, sesion, pendientes) {
7841
7923
  * encargo vacío y sin motivo.
7842
7924
  */
7843
7925
  export function augmentacionCableada(opciones) {
7844
- return async ({ texto, proyecto, adjuntos }) => {
7926
+ return async ({ texto, proyecto, adjuntos, pantallaDeStitch }) => {
7845
7927
  const extra = opciones.contexto?.(proyecto.raiz) ?? {};
7846
7928
  return opciones.aumentador.augmentar({
7847
7929
  texto,
@@ -7851,6 +7933,8 @@ export function augmentacionCableada(opciones) {
7851
7933
  adjuntos,
7852
7934
  ...(extra.memoria === undefined ? {} : { memoria: extra.memoria }),
7853
7935
  ...(extra.conectores === undefined ? {} : { conectores: extra.conectores }),
7936
+ // La pantalla elegida llega al prompt con sus ids: sin esta línea se perdía aquí, con todo en verde.
7937
+ ...(pantallaDeStitch === undefined ? {} : { pantallaDeStitch }),
7854
7938
  });
7855
7939
  };
7856
7940
  }
@@ -8154,6 +8238,24 @@ export function ajusteDeGestorCableado(ajuste) {
8154
8238
  },
8155
8239
  };
8156
8240
  }
8241
+ /**
8242
+ * Trae la pantalla de Stitch ELEGIDA a la carpeta de artefactos de la sesión de la tarea, con la MISMA función que la tool
8243
+ * (`traerDeStitch.ts#traerPantalla`), y compone la línea del encargo con la pantalla y el proyecto y sus ids. Nunca lanza.
8244
+ */
8245
+ export function prepararDisenoDeTarea(conectores, traer = traerPantalla) {
8246
+ return async (raiz, sesion, pantalla) => {
8247
+ try {
8248
+ const carpeta = carpetaDeArtefactosDeSesion(raiz, sesion);
8249
+ // La marca va SIEMPRE, antes de traerla: con ella la tool no busca por título ni trae otra (`traerDeStitch.ts`).
8250
+ marcarPantallaElegida(carpeta, pantalla);
8251
+ const texto = await traer({ conectores, carpeta }, pantalla.name);
8252
+ return textoDePantallaElegida(pantalla, texto.startsWith("Traída") ? { ok: true } : { ok: false, motivo: texto.split("\n")[0].slice(0, 160) });
8253
+ }
8254
+ catch {
8255
+ return textoDePantallaElegida(pantalla, { ok: false, motivo: "falló al traerla" });
8256
+ }
8257
+ };
8258
+ }
8157
8259
  export function construirCorredorDeTareasCableado(opciones) {
8158
8260
  const crudo = opciones.tareasFabrica === undefined ? undefined : opciones.tareasFabrica(opciones.informar);
8159
8261
  /**
@@ -8198,6 +8300,7 @@ export function construirCorredorDeTareasCableado(opciones) {
8198
8300
  ? undefined
8199
8301
  : crearCorredorDeTareas({
8200
8302
  disco,
8303
+ ...(opciones.conectores === undefined ? {} : { prepararDiseno: prepararDisenoDeTarea(opciones.conectores) }),
8201
8304
  // La costura de las tres piezas: la segunda puerta del vestíbulo (que no mueve el
8202
8305
  // cable), la consola que APARCA en vez de contestar por nadie, y el ejecutor de
8203
8306
  // siempre con las mismas barreras que el de una persona.
@@ -8420,6 +8523,8 @@ export async function arrancarConsolaWeb(opciones) {
8420
8523
  informar,
8421
8524
  // El MISMO gestor memoizado que el panel: con él, una tarea con ticket se refleja en su gestor al cambiar de estado.
8422
8525
  gestorDeTareas: conectoresYGestor.gestorDeTareas,
8526
+ // Los MISMOS conectores de las sesiones: con ellos, la pantalla de Stitch elegida se trae antes del primer turno.
8527
+ conectores: conectoresYGestor.conectoresDeSesion,
8423
8528
  olvidarHiloDeSesion: olvidarMemoriaDeHilo,
8424
8529
  /**
8425
8530
  * El juez de QA de las tareas, con el papel `afilado` — el que `core/modelos.ts` le