xonecode 0.8.46 → 0.11.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.
- package/THIRD_PARTY_NOTICES.md +56 -0
- package/apps/web/dist/assets/index-BAyybSz-.css +1 -0
- package/apps/web/dist/assets/index-BNCMVjWv.js +485 -0
- package/apps/web/dist/assets/{php-Bx1jVads.js → php-DPbDT8rX.js} +1 -1
- package/apps/web/dist/assets/{ruby-L0I9KR6K.js → ruby-Bfvws9R8.js} +1 -1
- package/apps/web/dist/index.html +2 -2
- package/apps/web/dist/openui/visor.css +1 -0
- package/apps/web/dist/openui/visor.js +9113 -0
- package/dist/agent/exportarPdf.js +5 -1
- package/dist/agent/exportarPdf.js.map +1 -1
- package/dist/agent/grafo/arbolDeProyecto.js +67 -2
- package/dist/agent/grafo/arbolDeProyecto.js.map +1 -1
- package/dist/agent/grafo/memoriaDeProyecto.js +3 -2
- package/dist/agent/grafo/memoriaDeProyecto.js.map +1 -1
- package/dist/agent/grafo/navegacionXone.js +8 -3
- package/dist/agent/grafo/navegacionXone.js.map +1 -1
- package/dist/agent/grafo/opcionesDeFicheros.js +24 -0
- package/dist/agent/grafo/opcionesDeFicheros.js.map +1 -0
- package/dist/agent/grafo/perfiles.js +1 -1
- package/dist/agent/grafo/perfiles.js.map +1 -1
- package/dist/agent/grafo/proyecto.js +31 -15
- package/dist/agent/grafo/proyecto.js.map +1 -1
- package/dist/agent/grafo/unirSecciones.js +128 -0
- package/dist/agent/grafo/unirSecciones.js.map +1 -0
- package/dist/agent/grafo/xoneAgent.js +56 -51
- package/dist/agent/grafo/xoneAgent.js.map +1 -1
- package/dist/agent/motores/trueforge/capacidades.js +179 -0
- package/dist/agent/motores/trueforge/capacidades.js.map +1 -0
- package/dist/agent/motores/trueforge/eventosTrueforge.js +143 -0
- package/dist/agent/motores/trueforge/eventosTrueforge.js.map +1 -0
- package/dist/agent/motores/trueforge/memoriaTrueforge.js +336 -0
- package/dist/agent/motores/trueforge/memoriaTrueforge.js.map +1 -0
- package/dist/agent/motores/trueforge/metricasTrueforge.js +55 -0
- package/dist/agent/motores/trueforge/metricasTrueforge.js.map +1 -0
- package/dist/agent/motores/trueforge/modeloExterno.js +46 -0
- package/dist/agent/motores/trueforge/modeloExterno.js.map +1 -0
- package/dist/agent/motores/trueforge/modeloLangchain.js +152 -0
- package/dist/agent/motores/trueforge/modeloLangchain.js.map +1 -0
- package/dist/agent/motores/trueforge/recortes.js +121 -0
- package/dist/agent/motores/trueforge/recortes.js.map +1 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.js +1062 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -0
- package/dist/agent/motores/trueforge/skillsTrueforge.js +14 -0
- package/dist/agent/motores/trueforge/skillsTrueforge.js.map +1 -0
- package/dist/agent/motores/trueforge/toolsDeFichero.js +265 -0
- package/dist/agent/motores/trueforge/toolsDeFichero.js.map +1 -0
- package/dist/agent/motores/trueforge/toolsPropias.js +65 -0
- package/dist/agent/motores/trueforge/toolsPropias.js.map +1 -0
- package/dist/agent/motores/trueforge/trueforge.js +45 -0
- package/dist/agent/motores/trueforge/trueforge.js.map +1 -0
- package/dist/agent/navegacion/indiceEnDisco.js +10 -1
- package/dist/agent/navegacion/indiceEnDisco.js.map +1 -1
- package/dist/agent/planesEnDisco.js +64 -0
- package/dist/agent/planesEnDisco.js.map +1 -0
- package/dist/agent/sesiones/memoriaDeHilo.js +24 -0
- package/dist/agent/sesiones/memoriaDeHilo.js.map +1 -0
- package/dist/agent/sesiones/modeloDelCambio.js +70 -0
- package/dist/agent/sesiones/modeloDelCambio.js.map +1 -0
- package/dist/agent/sesiones/sesionGit.js +14 -0
- package/dist/agent/sesiones/sesionGit.js.map +1 -1
- package/dist/agent/subagentes/actividadDeCodex.js +60 -0
- package/dist/agent/subagentes/actividadDeCodex.js.map +1 -0
- package/dist/agent/subagentes/agentesEnDisco.js +95 -5
- package/dist/agent/subagentes/agentesEnDisco.js.map +1 -1
- package/dist/agent/subagentes/escrituraExterna.js +10 -2
- package/dist/agent/subagentes/escrituraExterna.js.map +1 -1
- package/dist/agent/subagentes/subagenteCodex.js +20 -0
- package/dist/agent/subagentes/subagenteCodex.js.map +1 -1
- package/dist/agent/subagentes/subagenteExterno.js +269 -202
- package/dist/agent/subagentes/subagenteExterno.js.map +1 -1
- package/dist/agent/subagentes/subagenteOpencode.js +19 -2
- package/dist/agent/subagentes/subagenteOpencode.js.map +1 -1
- package/dist/agent/turno/diagnosticoDeTools.js +3 -0
- package/dist/agent/turno/diagnosticoDeTools.js.map +1 -1
- package/dist/agent/turno/ficherosDelProyecto.js +62 -0
- package/dist/agent/turno/ficherosDelProyecto.js.map +1 -0
- package/dist/agent/turno/informeDeTraza.js +28 -1
- package/dist/agent/turno/informeDeTraza.js.map +1 -1
- package/dist/agent/turno/puente.js +17 -1
- package/dist/agent/turno/puente.js.map +1 -1
- package/dist/agent/turno/resumenDeContexto.js +17 -4
- package/dist/agent/turno/resumenDeContexto.js.map +1 -1
- package/dist/agent/turno/resumenDeTool.js +3 -0
- package/dist/agent/turno/resumenDeTool.js.map +1 -1
- package/dist/agent/turno/sesionReal.js +2 -0
- package/dist/agent/turno/sesionReal.js.map +1 -0
- package/dist/agent/turno/turnoReal.js +55 -164
- package/dist/agent/turno/turnoReal.js.map +1 -1
- package/dist/agent/turno/verificacion.js +142 -0
- package/dist/agent/turno/verificacion.js.map +1 -0
- package/dist/cli/config.js +19 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/consola.js.map +1 -1
- package/dist/cli/main.js +35 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/tui/correrTui.js +1 -1
- package/dist/cli/tui/correrTui.js.map +1 -1
- package/dist/cli/tui/transcript.js +9 -0
- package/dist/cli/tui/transcript.js.map +1 -1
- package/dist/core/actos.js.map +1 -1
- package/dist/core/agentes.js +17 -0
- package/dist/core/agentes.js.map +1 -1
- package/dist/core/artefactos.js +22 -0
- package/dist/core/artefactos.js.map +1 -1
- package/dist/core/config.js +13 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/diffDeColecciones.js +84 -0
- package/dist/core/diffDeColecciones.js.map +1 -0
- package/dist/core/exportacion.js +6 -1
- package/dist/core/exportacion.js.map +1 -1
- package/dist/core/fotoDeColecciones.js +48 -0
- package/dist/core/fotoDeColecciones.js.map +1 -0
- package/dist/core/imagenesDeDocumento.js +88 -0
- package/dist/core/imagenesDeDocumento.js.map +1 -0
- package/dist/core/memoria.js +24 -0
- package/dist/core/memoria.js.map +1 -0
- package/dist/core/motor.js +41 -0
- package/dist/core/motor.js.map +1 -0
- package/dist/core/navegacion.js.map +1 -1
- package/dist/core/notify.js +23 -5
- package/dist/core/notify.js.map +1 -1
- package/dist/core/ports.js.map +1 -1
- package/dist/core/serieDeEscrituras.js +13 -0
- package/dist/core/serieDeEscrituras.js.map +1 -1
- package/dist/core/settings.js +17 -1
- package/dist/core/settings.js.map +1 -1
- package/dist/core/tareasDelPlan.js +103 -0
- package/dist/core/tareasDelPlan.js.map +1 -0
- package/dist/core/trazaDeErrores.js +42 -3
- package/dist/core/trazaDeErrores.js.map +1 -1
- package/dist/core/turno.js +44 -4
- package/dist/core/turno.js.map +1 -1
- package/dist/web/servidor/arranque.js +204 -5
- package/dist/web/servidor/arranque.js.map +1 -1
- package/dist/web/servidor/pielWeb.js +69 -4
- package/dist/web/servidor/pielWeb.js.map +1 -1
- package/dist/web/servidor/sesiones.js +11 -0
- package/dist/web/servidor/sesiones.js.map +1 -1
- package/dist/web/servidor/transporte.js.map +1 -1
- package/dist/web/servidor/vestibulo.js +23 -2
- package/dist/web/servidor/vestibulo.js.map +1 -1
- package/dist/web/servidor/visorOpenui.js +63 -0
- package/dist/web/servidor/visorOpenui.js.map +1 -0
- package/package.json +7 -2
- package/skills/openui-builder/SKILL.md +48 -0
- package/apps/web/dist/assets/index-GRwyotMV.js +0 -478
- package/apps/web/dist/assets/index-_cBVqq54.css +0 -1
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* modelo y lo guarda: un paso de cuenta que solo guardara la credencial dejaría `trabajo`
|
|
28
28
|
* en la omisión (Ollama local) con una clave de Anthropic recién escrita al lado.
|
|
29
29
|
*/
|
|
30
|
+
import { hayMemoriaDeHilo, olvidarMemoriaDeHilo } from "../../agent/sesiones/memoriaDeHilo.js";
|
|
30
31
|
import { existsSync, readFileSync } from "node:fs";
|
|
31
32
|
import { lineaDeVersion } from "../../core/version.js";
|
|
32
33
|
import { basename, dirname, join } from "node:path";
|
|
@@ -62,7 +63,7 @@ import { motivoDeClaveInaceptable } from "../../core/config.js";
|
|
|
62
63
|
import { aplicarAuth, aplicarCredencialAlProceso, cargar, guardarModeloGlobal, } from "../../agent/config/configEnDisco.js";
|
|
63
64
|
import { borrarCredencial, guardarCredencial } from "../../agent/config/authEnDisco.js";
|
|
64
65
|
import { borrarProveedorPersonalizado, guardarProveedorPersonalizado, proveedoresPersonalizados, } from "../../agent/config/configEnDisco.js";
|
|
65
|
-
import { crearCheckpointerDeProyecto,
|
|
66
|
+
import { crearCheckpointerDeProyecto, mantenimientoDelCheckpointer, } from "../../agent/sesiones/checkpointer.js";
|
|
66
67
|
import { resumenDePoda } from "../../core/podaDeCheckpoint.js";
|
|
67
68
|
import { cargarSettings, guardarConcurrenciaDeTareas, guardarWorkspace as guardarWorkspaceEnDisco, guardarDispositivos, guardarEntorno as guardarEntornoEnDisco, olvidarEntornoDeSettings, copiasDeEntorno, borrarCopiasDeEntorno, } from "../../agent/config/settingsEnDisco.js";
|
|
68
69
|
import { dentroDelWorkspace, expandirConCasa, motivoParaNoOlvidarEntorno, motivoDeWorkspaceInaceptable, } from "../../core/settings.js";
|
|
@@ -76,7 +77,14 @@ import { cambiosDeSesion, fotoDeApertura, olvidarSesion, parcheDeSesion } from "
|
|
|
76
77
|
import { commitDeTurno, cambiosPendientes, trabajoSinCommitear } from "../../agent/sesiones/gitSync.js";
|
|
77
78
|
import { marcarTareaDeSesion, sembrarConsumosPendientes } from "./sesiones.js";
|
|
78
79
|
import { RUTA_ARTEFACTOS, esRutaDeArtefacto } from "../../core/artefactos.js";
|
|
79
|
-
import { arbolDeProyecto, leerFicheroDeProyecto, motivoDeRutaInaceptable, } from "../../agent/grafo/arbolDeProyecto.js";
|
|
80
|
+
import { arbolDeProyecto, leerFicheroDeProyecto, mimeDeImagen, motivoDeRutaInaceptable, } from "../../agent/grafo/arbolDeProyecto.js";
|
|
81
|
+
import { modeloEnDisco } from "../../agent/navegacion/indiceEnDisco.js";
|
|
82
|
+
import { ficherosDelProyecto } from "../../agent/turno/ficherosDelProyecto.js";
|
|
83
|
+
import { fotoDeColecciones } from "../../core/fotoDeColecciones.js";
|
|
84
|
+
import { modeloDelCambio } from "../../agent/sesiones/modeloDelCambio.js";
|
|
85
|
+
import { planesDelProyecto } from "../../agent/planesEnDisco.js";
|
|
86
|
+
import { CSP_DE_OPENUI, documentoDeOpenui, esArtefactoOpenui } from "./visorOpenui.js";
|
|
87
|
+
import { RUTA_IMAGEN_DEL_PROYECTO } from "../../core/imagenesDeDocumento.js";
|
|
80
88
|
import { leerArtefactoCrudo, leerArtefactoDeSesion, } from "../../agent/grafo/artefactosEnDisco.js";
|
|
81
89
|
import { CatalogoModelos, baseUrlDeOllama, baseUrlDeOllamaCloud, capacidadesDeOllama, } from "../../agent/config/catalogoModelos.js";
|
|
82
90
|
import { Modelos } from "../../agent/config/modelos.js";
|
|
@@ -162,6 +170,21 @@ export const MS_ENTRE_PROGRESOS = 250;
|
|
|
162
170
|
export function raizDelClientePorOmision() {
|
|
163
171
|
return join(dirname(fileURLToPath(import.meta.url)), "..", "..", "..", "apps", "web", "dist");
|
|
164
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* El visor de OpenUI del build del cliente, o `undefined` si no está. Se lee en cada petición, como
|
|
175
|
+
* el resto del cliente: reconstruirlo se ve recargando, sin reiniciar el servidor.
|
|
176
|
+
*/
|
|
177
|
+
export function leerVisorOpenui(raizDelCliente) {
|
|
178
|
+
try {
|
|
179
|
+
return {
|
|
180
|
+
js: readFileSync(join(raizDelCliente, "openui", "visor.js"), "utf8"),
|
|
181
|
+
css: readFileSync(join(raizDelCliente, "openui", "visor.css"), "utf8"),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
165
188
|
export const FALTA_EL_BUILD = "falta el build del cliente: ejecuta «npm run build:web»";
|
|
166
189
|
/** Tope del cuerpo de `POST /accion`. Generoso para una prosa larga, finito porque el
|
|
167
190
|
* cuerpo se acumula en memoria y un cliente roto no puede llenarla. */
|
|
@@ -2743,6 +2766,73 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
|
|
|
2743
2766
|
emitir({ clase: "arbol", rutas: [], recortado: false, error: "no se pudo listar el proyecto" });
|
|
2744
2767
|
}
|
|
2745
2768
|
};
|
|
2769
|
+
/**
|
|
2770
|
+
* El diff semántico de un `.xne` de Revisión. Siempre CONTESTA —la fila abierta espera, y un
|
|
2771
|
+
* silencio la dejaría cargando para siempre—, y la ruta pasa por la MISMA barrera que la del
|
|
2772
|
+
* lector de Ficheros antes de llegar a git.
|
|
2773
|
+
*/
|
|
2774
|
+
const atenderModeloDelCambio = async (ruta) => {
|
|
2775
|
+
const abierto = vestibulo.proyectoAbierto();
|
|
2776
|
+
const sesion = abierto?.sesion;
|
|
2777
|
+
const sinNada = (error) => emitir({ clase: "modeloDelCambio", ruta, error });
|
|
2778
|
+
if (abierto === undefined || opciones.modeloDelCambio === undefined)
|
|
2779
|
+
return sinNada("esta ejecución no sabe comparar el modelo");
|
|
2780
|
+
if (sesion === undefined)
|
|
2781
|
+
return sinNada("la sesión todavía no ha empezado");
|
|
2782
|
+
if (motivoDeRutaInaceptable(ruta) !== undefined)
|
|
2783
|
+
return sinNada("esa ruta no se enseña");
|
|
2784
|
+
try {
|
|
2785
|
+
const cambios = await opciones.modeloDelCambio(abierto.raiz, sesion, ruta);
|
|
2786
|
+
if (cambios === undefined)
|
|
2787
|
+
return sinNada("no hay con qué comparar");
|
|
2788
|
+
emitir({ clase: "modeloDelCambio", ruta, cambios });
|
|
2789
|
+
}
|
|
2790
|
+
catch (error) {
|
|
2791
|
+
informar(`no se pudo comparar el modelo (${codigoDe(error)})`);
|
|
2792
|
+
sinNada("no se pudo comparar el modelo");
|
|
2793
|
+
}
|
|
2794
|
+
};
|
|
2795
|
+
/**
|
|
2796
|
+
* Los planes del proyecto abierto. Mismas reglas que el árbol: sin proyecto no se contesta,
|
|
2797
|
+
* sin puerto se contesta con error, y el fallo viaja sin la ruta de la máquina.
|
|
2798
|
+
*/
|
|
2799
|
+
const atenderPlanes = async () => {
|
|
2800
|
+
const abierto = vestibulo.proyectoAbierto();
|
|
2801
|
+
if (abierto === undefined)
|
|
2802
|
+
return;
|
|
2803
|
+
if (opciones.planesDelProyecto === undefined) {
|
|
2804
|
+
emitir({ clase: "planes", error: "esta ejecución no puede leer los planes" });
|
|
2805
|
+
return;
|
|
2806
|
+
}
|
|
2807
|
+
try {
|
|
2808
|
+
emitir({ clase: "planes", planes: opciones.planesDelProyecto(abierto.raiz) });
|
|
2809
|
+
}
|
|
2810
|
+
catch (error) {
|
|
2811
|
+
informar(`no se pudieron leer los planes (${codigoDe(error)})`);
|
|
2812
|
+
emitir({ clase: "planes", error: "no se pudieron leer los planes" });
|
|
2813
|
+
}
|
|
2814
|
+
};
|
|
2815
|
+
/**
|
|
2816
|
+
* La foto del modelo XOne del proyecto abierto. Mismas reglas que el árbol: sin proyecto no
|
|
2817
|
+
* se contesta, sin puerto se contesta con error —un «consultando…» eterno es un fallo mudo—,
|
|
2818
|
+
* y el fallo viaja sin la ruta de la máquina.
|
|
2819
|
+
*/
|
|
2820
|
+
const atenderColecciones = async () => {
|
|
2821
|
+
const abierto = vestibulo.proyectoAbierto();
|
|
2822
|
+
if (abierto === undefined)
|
|
2823
|
+
return;
|
|
2824
|
+
if (opciones.coleccionesDelProyecto === undefined) {
|
|
2825
|
+
emitir({ clase: "colecciones", error: "esta ejecución no puede leer el modelo del proyecto" });
|
|
2826
|
+
return;
|
|
2827
|
+
}
|
|
2828
|
+
try {
|
|
2829
|
+
emitir({ clase: "colecciones", foto: await opciones.coleccionesDelProyecto(abierto.raiz) });
|
|
2830
|
+
}
|
|
2831
|
+
catch (error) {
|
|
2832
|
+
informar(`no se pudo leer el modelo del proyecto (${codigoDe(error)})`);
|
|
2833
|
+
emitir({ clase: "colecciones", error: "no se pudo leer el modelo del proyecto" });
|
|
2834
|
+
}
|
|
2835
|
+
};
|
|
2746
2836
|
/**
|
|
2747
2837
|
* El contenido de una ruta del proyecto abierto. El lector decide si se puede enseñar.
|
|
2748
2838
|
*
|
|
@@ -3340,6 +3430,25 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
|
|
|
3340
3430
|
return;
|
|
3341
3431
|
}
|
|
3342
3432
|
const descargar = query.get("descargar") !== null;
|
|
3433
|
+
// Un programa de OpenUI se VE dentro de su visor, en un documento autocontenido y sin red
|
|
3434
|
+
// (`visorOpenui.ts`). Descargarlo sigue dando el fichero tal cual.
|
|
3435
|
+
if (!descargar && esArtefactoOpenui(leido.nombre)) {
|
|
3436
|
+
const visor = opciones.visorOpenui?.();
|
|
3437
|
+
if (visor === undefined) {
|
|
3438
|
+
responder(503, "el visor de OpenUI no está construido: ejecuta «npm run build:web»");
|
|
3439
|
+
return;
|
|
3440
|
+
}
|
|
3441
|
+
const documento = Buffer.from(documentoDeOpenui(leido.datos.toString("utf8"), visor, leido.nombre), "utf8");
|
|
3442
|
+
respuesta.writeHead(200, {
|
|
3443
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
3444
|
+
"Content-Length": documento.length,
|
|
3445
|
+
"Content-Security-Policy": CSP_DE_OPENUI,
|
|
3446
|
+
"X-Content-Type-Options": "nosniff",
|
|
3447
|
+
"Cache-Control": "no-store",
|
|
3448
|
+
});
|
|
3449
|
+
respuesta.end(documento);
|
|
3450
|
+
return;
|
|
3451
|
+
}
|
|
3343
3452
|
// Sin mime conocido se descarga en vez de adivinar. El nombre ya pasó la barrera de
|
|
3344
3453
|
// segmento llano, así que entre comillas no puede romper la cabecera.
|
|
3345
3454
|
const inline = !descargar && leido.mime !== undefined;
|
|
@@ -3355,6 +3464,67 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
|
|
|
3355
3464
|
});
|
|
3356
3465
|
respuesta.end(leido.datos);
|
|
3357
3466
|
});
|
|
3467
|
+
/**
|
|
3468
|
+
* `GET /imagen-del-proyecto?ruta=<relativa>` — una IMAGEN del proyecto abierto, para que un `.md`
|
|
3469
|
+
* de la pestaña Ficheros enseñe las suyas.
|
|
3470
|
+
*
|
|
3471
|
+
* Existe porque el visor de markdown solo pinta imágenes `http(s)` absolutas: un enlace relativo o
|
|
3472
|
+
* una `data:` se quedaban en su texto alternativo. La vista del documento reescribe cada enlace a
|
|
3473
|
+
* esta ruta (`arbolDeProyecto.ts#vistaDeMarkdown`), y aquí se sirve con la barrera de siempre:
|
|
3474
|
+
* - **Solo imágenes, por su extensión**, antes de leer nada: esto no es un lector de ficheros por
|
|
3475
|
+
* HTTP, y sin esa criba cualquier ruta que se enseñe se podría pedir por aquí.
|
|
3476
|
+
* - **Leída con `leerFichero`** —las dos barreras de la pestaña Ficheros, sobre el texto y sobre
|
|
3477
|
+
* el camino REAL, y su tope—, no con una copia de ellas.
|
|
3478
|
+
* - `Content-Security-Policy: sandbox`, `nosniff` y `no-store`: un `.svg` abierto a pelo en una
|
|
3479
|
+
* pestaña no ejecuta nada, el navegador no adivina el tipo, y una captura reescrita se ve nueva.
|
|
3480
|
+
*/
|
|
3481
|
+
servidor.registrarRuta("GET", RUTA_IMAGEN_DEL_PROYECTO, async (peticion, respuesta) => {
|
|
3482
|
+
const responder = (codigo, texto) => {
|
|
3483
|
+
respuesta.writeHead(codigo, { "Content-Type": "text/plain; charset=utf-8" });
|
|
3484
|
+
respuesta.end(texto);
|
|
3485
|
+
};
|
|
3486
|
+
const ruta = new URLSearchParams((peticion.url ?? "").split("?")[1] ?? "").get("ruta");
|
|
3487
|
+
if (ruta === null || ruta === "") {
|
|
3488
|
+
responder(400, "falta la ruta");
|
|
3489
|
+
return;
|
|
3490
|
+
}
|
|
3491
|
+
if (mimeDeImagen(ruta) === undefined) {
|
|
3492
|
+
responder(403, "eso no es una imagen");
|
|
3493
|
+
return;
|
|
3494
|
+
}
|
|
3495
|
+
const abierto = vestibulo.proyectoAbierto();
|
|
3496
|
+
if (abierto === undefined || opciones.leerFichero === undefined) {
|
|
3497
|
+
responder(404, "no hay imagen");
|
|
3498
|
+
return;
|
|
3499
|
+
}
|
|
3500
|
+
let leido;
|
|
3501
|
+
try {
|
|
3502
|
+
leido = await opciones.leerFichero(abierto.raiz, ruta);
|
|
3503
|
+
}
|
|
3504
|
+
catch (error) {
|
|
3505
|
+
// Como en el resto: al cliente y a `informar` solo el código, nunca el mensaje de Node.
|
|
3506
|
+
informar(`no se pudo servir la imagen «${ruta}» (${codigoDe(error)})`);
|
|
3507
|
+
responder(500, "no se pudo leer");
|
|
3508
|
+
return;
|
|
3509
|
+
}
|
|
3510
|
+
if (leido.error !== undefined) {
|
|
3511
|
+
responder(leido.error === "no existe" ? 404 : 403, leido.error);
|
|
3512
|
+
return;
|
|
3513
|
+
}
|
|
3514
|
+
if (leido.base64 === undefined || leido.mime === undefined) {
|
|
3515
|
+
responder(413, "la imagen es demasiado grande");
|
|
3516
|
+
return;
|
|
3517
|
+
}
|
|
3518
|
+
const datos = Buffer.from(leido.base64, "base64");
|
|
3519
|
+
respuesta.writeHead(200, {
|
|
3520
|
+
"Content-Type": leido.mime,
|
|
3521
|
+
"Content-Length": datos.length,
|
|
3522
|
+
"Content-Security-Policy": "sandbox",
|
|
3523
|
+
"X-Content-Type-Options": "nosniff",
|
|
3524
|
+
"Cache-Control": "no-store",
|
|
3525
|
+
});
|
|
3526
|
+
respuesta.end(datos);
|
|
3527
|
+
});
|
|
3358
3528
|
/**
|
|
3359
3529
|
* `POST /adjunto?tarea=<id>&nombre=<fichero>` — los BYTES de un adjunto de tarea.
|
|
3360
3530
|
*
|
|
@@ -3575,6 +3745,27 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
|
|
|
3575
3745
|
respuesta.end();
|
|
3576
3746
|
return;
|
|
3577
3747
|
}
|
|
3748
|
+
if (typeof mensaje === "object" &&
|
|
3749
|
+
mensaje !== null &&
|
|
3750
|
+
mensaje.clase === "modeloDelCambio" &&
|
|
3751
|
+
typeof mensaje.ruta === "string") {
|
|
3752
|
+
void atenderModeloDelCambio(mensaje.ruta).catch(contar);
|
|
3753
|
+
respuesta.writeHead(204);
|
|
3754
|
+
respuesta.end();
|
|
3755
|
+
return;
|
|
3756
|
+
}
|
|
3757
|
+
if (typeof mensaje === "object" && mensaje !== null && mensaje.clase === "planes") {
|
|
3758
|
+
void atenderPlanes().catch(contar);
|
|
3759
|
+
respuesta.writeHead(204);
|
|
3760
|
+
respuesta.end();
|
|
3761
|
+
return;
|
|
3762
|
+
}
|
|
3763
|
+
if (typeof mensaje === "object" && mensaje !== null && mensaje.clase === "colecciones") {
|
|
3764
|
+
void atenderColecciones().catch(contar);
|
|
3765
|
+
respuesta.writeHead(204);
|
|
3766
|
+
respuesta.end();
|
|
3767
|
+
return;
|
|
3768
|
+
}
|
|
3578
3769
|
if (typeof mensaje === "object" &&
|
|
3579
3770
|
mensaje !== null &&
|
|
3580
3771
|
mensaje.clase === "sync" &&
|
|
@@ -4592,7 +4783,7 @@ export async function arrancarConsolaWeb(opciones) {
|
|
|
4592
4783
|
vestibulo: conVestibulo,
|
|
4593
4784
|
tareasFabrica: opciones.tareas,
|
|
4594
4785
|
informar,
|
|
4595
|
-
olvidarHiloDeSesion:
|
|
4786
|
+
olvidarHiloDeSesion: olvidarMemoriaDeHilo,
|
|
4596
4787
|
/**
|
|
4597
4788
|
* El juez de QA de las tareas, con el papel `afilado` — el que `core/modelos.ts` le
|
|
4598
4789
|
* reserva.
|
|
@@ -4707,6 +4898,12 @@ export async function arrancarConsolaWeb(opciones) {
|
|
|
4707
4898
|
// El proyecto tal como lo ve el agente, para la pestaña Ficheros: mismo filtro, misma
|
|
4708
4899
|
// barrera de rutas (`agent/grafo/arbolDeProyecto.ts`).
|
|
4709
4900
|
arbolDelProyecto: async (raiz) => arbolDeProyecto(raiz),
|
|
4901
|
+
// El modelo XOne con el MISMO cargador y el mismo conjunto de ficheros que la tool, para
|
|
4902
|
+
// que la pestaña y el agente no contesten distinto sobre el mismo proyecto.
|
|
4903
|
+
coleccionesDelProyecto: async (raiz) => fotoDeColecciones(await modeloEnDisco(raiz)(ficherosDelProyecto(raiz))),
|
|
4904
|
+
modeloDelCambio,
|
|
4905
|
+
planesDelProyecto,
|
|
4906
|
+
visorOpenui: () => leerVisorOpenui(raizDelCliente),
|
|
4710
4907
|
leerFichero: leerFicheroDeProyecto,
|
|
4711
4908
|
leerArtefacto: leerArtefactoDeSesion,
|
|
4712
4909
|
leerArtefactoCrudo,
|
|
@@ -4949,8 +5146,10 @@ function vestibuloReal(opciones, servidor, escribir, informar) {
|
|
|
4949
5146
|
olvidarMarcaDeSesion: olvidarSesion,
|
|
4950
5147
|
// La memoria del agente por hilo. `historica` deja de ser «se reabrió» para ser «no hay
|
|
4951
5148
|
// checkpoint que cargar», y borrar una sesión se lleva también su checkpoint.
|
|
4952
|
-
|
|
4953
|
-
|
|
5149
|
+
// Las dos memorias —la del checkpointer de deepagents y la foto de TrueForge—, en una función
|
|
5150
|
+
// exportada y probada (`memoriaDeHilo.ts`), no en dos lambdas de este cierre.
|
|
5151
|
+
hayMemoriaDeHilo,
|
|
5152
|
+
olvidarMemoriaDeHilo,
|
|
4954
5153
|
entornos: settings.entornos,
|
|
4955
5154
|
/**
|
|
4956
5155
|
* Dónde se bajan las copias, RELEÍDO en cada uso y no resuelto aquí.
|