xonecode 0.20.3 → 0.22.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/apps/web/dist/assets/index-5rtynJV_.js +490 -0
- package/apps/web/dist/assets/index-Cq6c6WEF.css +1 -0
- package/apps/web/dist/assets/{php-CDg2Quc0.js → php-BTFUgUDo.js} +1 -1
- package/apps/web/dist/assets/{ruby-DlFaAWQT.js → ruby-BKKiBtJK.js} +1 -1
- package/apps/web/dist/index.html +2 -2
- package/dist/agent/conectores/servicioDeConectores.js +86 -45
- package/dist/agent/conectores/servicioDeConectores.js.map +1 -1
- package/dist/agent/config/modelos.js +4 -0
- package/dist/agent/config/modelos.js.map +1 -1
- package/dist/agent/config/mudanzaEnDisco.js +237 -3
- package/dist/agent/config/mudanzaEnDisco.js.map +1 -1
- package/dist/agent/config/selectorEnMaquina.js +3 -2
- package/dist/agent/config/selectorEnMaquina.js.map +1 -1
- package/dist/agent/config/settingsEnDisco.js +76 -2
- package/dist/agent/config/settingsEnDisco.js.map +1 -1
- package/dist/agent/dispositivos/arranqueDeEmulador.js +27 -3
- package/dist/agent/dispositivos/arranqueDeEmulador.js.map +1 -1
- package/dist/agent/dispositivos/instalacionEnMaquina.js +240 -29
- package/dist/agent/dispositivos/instalacionEnMaquina.js.map +1 -1
- package/dist/agent/dispositivos/lanzamientoEnMaquina.js +12 -17
- package/dist/agent/dispositivos/lanzamientoEnMaquina.js.map +1 -1
- package/dist/agent/grafo/proyecto.js +91 -50
- package/dist/agent/grafo/proyecto.js.map +1 -1
- package/dist/agent/motores/trueforge/capacidades.js +22 -0
- package/dist/agent/motores/trueforge/capacidades.js.map +1 -1
- package/dist/agent/motores/trueforge/medidaAutomatica.js +16 -3
- package/dist/agent/motores/trueforge/medidaAutomatica.js.map +1 -1
- package/dist/agent/motores/trueforge/modeloLangchain.js +7 -1
- package/dist/agent/motores/trueforge/modeloLangchain.js.map +1 -1
- package/dist/agent/motores/trueforge/sesionTrueforge.js +135 -14
- package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
- package/dist/agent/motores/trueforge/toolsDeConectores.js +128 -0
- package/dist/agent/motores/trueforge/toolsDeConectores.js.map +1 -0
- package/dist/agent/motores/trueforge/traerDeStitch.js +142 -0
- package/dist/agent/motores/trueforge/traerDeStitch.js.map +1 -0
- package/dist/agent/subagentes/consumoExterno.js +15 -8
- package/dist/agent/subagentes/consumoExterno.js.map +1 -1
- package/dist/agent/subagentes/escrituraExterna.js +69 -2
- package/dist/agent/subagentes/escrituraExterna.js.map +1 -1
- package/dist/agent/subagentes/subagenteExterno.js +17 -1
- package/dist/agent/subagentes/subagenteExterno.js.map +1 -1
- package/dist/agent/turno/turnoReal.js +1 -0
- package/dist/agent/turno/turnoReal.js.map +1 -1
- package/dist/cli/main.js +5 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/core/actos.js +44 -1
- package/dist/core/actos.js.map +1 -1
- package/dist/core/agentes.js +13 -2
- package/dist/core/agentes.js.map +1 -1
- package/dist/core/comandoExterno.js +69 -0
- package/dist/core/comandoExterno.js.map +1 -0
- package/dist/core/conectores.js +148 -3
- package/dist/core/conectores.js.map +1 -1
- package/dist/core/copiaDeAvd.js +111 -0
- package/dist/core/copiaDeAvd.js.map +1 -0
- package/dist/core/mudanzaDeWorkspace.js +105 -15
- package/dist/core/mudanzaDeWorkspace.js.map +1 -1
- package/dist/core/ports.js +28 -0
- package/dist/core/ports.js.map +1 -1
- package/dist/core/puertosDeAvd.js +64 -0
- package/dist/core/puertosDeAvd.js.map +1 -0
- package/dist/core/selectorDeCarpeta.js +88 -9
- package/dist/core/selectorDeCarpeta.js.map +1 -1
- package/dist/core/settings.js +60 -1
- package/dist/core/settings.js.map +1 -1
- package/dist/core/shellDeAgente.js +11 -0
- package/dist/core/shellDeAgente.js.map +1 -1
- package/dist/core/stitch.js +114 -0
- package/dist/core/stitch.js.map +1 -0
- package/dist/web/servidor/arranque.js +523 -52
- package/dist/web/servidor/arranque.js.map +1 -1
- package/dist/web/servidor/consolaDeTarea.js +4 -1
- package/dist/web/servidor/consolaDeTarea.js.map +1 -1
- package/dist/web/servidor/pielWeb.js +3 -1
- package/dist/web/servidor/pielWeb.js.map +1 -1
- package/dist/web/servidor/transporte.js.map +1 -1
- package/dist/web/servidor/vestibulo.js +154 -48
- package/dist/web/servidor/vestibulo.js.map +1 -1
- package/package.json +1 -1
- package/skills/xone-hotswap/SKILL.md +26 -10
- package/skills/xone-hotswap/lib/dispositivo.mjs +97 -3
- package/skills/xone-hotswap/references/conexion-y-despliegue.md +27 -15
- package/skills/xone-hotswap/scripts/xone-arrancar-android +9 -2
- package/skills/xone-hotswap/scripts/xone-desplegar-android +12 -6
- package/skills/xone-hotswap/scripts/xone-hotswap +32 -10
- package/skills/xone-hotswap/scripts/xone-reiniciar-android +23 -7
- package/apps/web/dist/assets/index-40sIfNsT.js +0 -485
- package/apps/web/dist/assets/index-BYTna8Os.css +0 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qué `Bash` se le deja correr a un agente EXTERNO (Claude Code) que declara `ejecucion: true`.
|
|
3
|
+
*
|
|
4
|
+
* En los motores externos la shell está cerrada: lo que el hijo ejecuta va directo a la máquina,
|
|
5
|
+
* sin nuestras guardas. La excepción es ESTRECHA a propósito: una sola llamada a uno de los
|
|
6
|
+
* scripts de las skills que el agente declara (`xone-hotswap`, `xone-log-android`…), por su
|
|
7
|
+
* NOMBRE, con argumentos que la shell no puede reinterpretar. Todo lo demás se deniega.
|
|
8
|
+
*
|
|
9
|
+
* La gramática sale de cómo se llaman de verdad (`skills/xone-hotswap/SKILL.md`): palabras
|
|
10
|
+
* sueltas (`--app MiApp`, `name=MAP_BT_ACEPTAR`, `--`, nombres de fichero) y, para un texto con
|
|
11
|
+
* espacios, comillas SIMPLES —dentro de ellas la shell no expande nada—. Se rechaza lo demás:
|
|
12
|
+
* comillas dobles, `$`, backticks, `\`, comodines, `~`, `{}`, `#`, redirecciones, tuberías,
|
|
13
|
+
* encadenados, saltos de línea y una asignación `VAR=` delante.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Un argumento: palabra suelta, con como mucho UN tramo entre comillas simples al final
|
|
17
|
+
* (`--texto='hola mundo'`, `'dos palabras'`). Dentro de las comillas simples la shell no expande
|
|
18
|
+
* nada; fuera, solo caracteres que no interpreta.
|
|
19
|
+
*/
|
|
20
|
+
const ARGUMENTO = /^[A-Za-z0-9_./:=,@%+-]*(?:'[^'\n\r]*')?$/;
|
|
21
|
+
/** Parte el comando en argumentos por los espacios de FUERA de las comillas, o `undefined` si una no cierra. */
|
|
22
|
+
function palabras(comando) {
|
|
23
|
+
const salida = [];
|
|
24
|
+
let actual = "";
|
|
25
|
+
let enComillas = false;
|
|
26
|
+
for (const c of comando) {
|
|
27
|
+
if (c === "'")
|
|
28
|
+
enComillas = !enComillas;
|
|
29
|
+
if (c === " " && !enComillas) {
|
|
30
|
+
if (actual !== "")
|
|
31
|
+
salida.push(actual);
|
|
32
|
+
actual = "";
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
actual += c;
|
|
36
|
+
}
|
|
37
|
+
if (enComillas)
|
|
38
|
+
return undefined;
|
|
39
|
+
if (actual !== "")
|
|
40
|
+
salida.push(actual);
|
|
41
|
+
return salida;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* El motivo por el que ese comando NO se deja correr, o `undefined` si se deja. `scripts` son los
|
|
45
|
+
* nombres (sin ruta) de los ejecutables de las skills del agente. El motivo dice la forma que sí
|
|
46
|
+
* vale: sin eso el modelo reintenta con `./scripts/…` o con la ruta de la variable.
|
|
47
|
+
*/
|
|
48
|
+
export function motivoDeComandoExternoInaceptable(comando, scripts) {
|
|
49
|
+
const forma = `Solo puedes correr UNO de tus scripts, por su nombre y sin ruta (${scripts.join(", ")}), ` +
|
|
50
|
+
"con argumentos sueltos o entre comillas simples: nada de ;, &&, |, >, $, comillas dobles ni rutas al script.";
|
|
51
|
+
if (scripts.length === 0)
|
|
52
|
+
return "este agente no tiene scripts que correr";
|
|
53
|
+
const limpio = comando.trim();
|
|
54
|
+
if (limpio === "" || /[\n\r\t]/.test(limpio))
|
|
55
|
+
return forma;
|
|
56
|
+
const partes = palabras(limpio);
|
|
57
|
+
if (partes === undefined || partes.length === 0)
|
|
58
|
+
return forma;
|
|
59
|
+
const [programa, ...argumentos] = partes;
|
|
60
|
+
if (programa === undefined || !/^[A-Za-z0-9_-]+$/.test(programa) || !scripts.includes(programa)) {
|
|
61
|
+
return `«${programa ?? ""}» no es uno de tus scripts. ${forma}`;
|
|
62
|
+
}
|
|
63
|
+
for (const a of argumentos) {
|
|
64
|
+
if (a === "" || !ARGUMENTO.test(a))
|
|
65
|
+
return `El argumento «${a}» no se admite. ${forma}`;
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=comandoExterno.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comandoExterno.js","sourceRoot":"","sources":["../../src/core/comandoExterno.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;GAIG;AACH,MAAM,SAAS,GAAG,0CAA0C,CAAC;AAE7D,gHAAgH;AAChH,SAAS,QAAQ,CAAC,OAAe;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG;YAAE,UAAU,GAAG,CAAC,UAAU,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAC7B,IAAI,MAAM,KAAK,EAAE;gBAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvC,MAAM,GAAG,EAAE,CAAC;YACZ,SAAS;QACX,CAAC;QACD,MAAM,IAAI,CAAC,CAAC;IACd,CAAC;IACD,IAAI,UAAU;QAAE,OAAO,SAAS,CAAC;IACjC,IAAI,MAAM,KAAK,EAAE;QAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iCAAiC,CAAC,OAAe,EAAE,OAA0B;IAC3F,MAAM,KAAK,GACT,oEAAoE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;QAC3F,8GAA8G,CAAC;IACjH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,yCAAyC,CAAC;IAC3E,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,MAAM,KAAK,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,QAAQ,EAAE,GAAG,UAAU,CAAC,GAAG,MAAM,CAAC;IACzC,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChG,OAAO,IAAI,QAAQ,IAAI,EAAE,+BAA+B,KAAK,EAAE,CAAC;IAClE,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,iBAAiB,CAAC,mBAAmB,KAAK,EAAE,CAAC;IAC1F,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/core/conectores.js
CHANGED
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
* abajo —estado, prueba, autorización, botones— nada sabe de qué familia viene: es lo que
|
|
10
10
|
* hace que un servidor añadido a mano se comporte como Jira.
|
|
11
11
|
*
|
|
12
|
-
* **
|
|
13
|
-
*
|
|
12
|
+
* **Llegan a los agentes de TrueForge** por `ConectoresPort` (`agent/motores/trueforge/
|
|
13
|
+
* toolsDeConectores.ts`): qué conectores (`conectoresParaElAgente`), a quién (`recibeConectores`)
|
|
14
|
+
* y qué ve el modelo (`esquemaParaElModelo`, `resultadoRecortado`) se decide aquí, puro.
|
|
14
15
|
*/
|
|
16
|
+
import { CARPETA_DE_ICONOS } from "./iconos.js";
|
|
15
17
|
import { motivoDeEndpointInaceptable, motivoDeSlugInaceptable, PREFIJO_PERSONALIZADO, slugDesdeNombre } from "./modelos.js";
|
|
16
18
|
/**
|
|
17
19
|
* El literal, comprobado por VALOR: es lo que llega por el cable, donde puede mentir.
|
|
@@ -28,7 +30,8 @@ export function esAutenticacionDeConector(valor) {
|
|
|
28
30
|
/**
|
|
29
31
|
* Medido contra los tres servidores el 24-09-2026: deepwiki contesta `listTools` sin
|
|
30
32
|
* credenciales; Notion y Atlassian publican `registration_endpoint` y S256, y aceptan un
|
|
31
|
-
* cliente público con `redirect_uri` en loopback.
|
|
33
|
+
* cliente público con `redirect_uri` en loopback. Stitch (30-09-2026) lleva la clave en su propia
|
|
34
|
+
* cabecera y se comprueba con una llamada, ver `cabeceraDeClave`. El transporte NO se declara: se prueba
|
|
32
35
|
* `streamable-http` y, si no, `sse`, como hace TrueForge.
|
|
33
36
|
*/
|
|
34
37
|
export const CATALOGO_DE_CONECTORES = [
|
|
@@ -53,6 +56,17 @@ export const CATALOGO_DE_CONECTORES = [
|
|
|
53
56
|
descripcion: "Busca páginas, lee contenido, consulta bases de datos y crea páginas.",
|
|
54
57
|
autenticacion: "oauth",
|
|
55
58
|
},
|
|
59
|
+
{
|
|
60
|
+
id: "stitch",
|
|
61
|
+
nombre: "Stitch",
|
|
62
|
+
url: "https://stitch.googleapis.com/mcp",
|
|
63
|
+
descripcion: "Diseña pantallas con Google Stitch y lee sus proyectos, pantallas y sistemas de diseño.",
|
|
64
|
+
autenticacion: "api-key",
|
|
65
|
+
cabeceraDeClave: "X-Goog-Api-Key",
|
|
66
|
+
comprobacion: "list_projects",
|
|
67
|
+
fueraDelAgente: ["delete_project", "create_design_system", "update_design_system"],
|
|
68
|
+
camposFueraDelResultado: { list_projects: ["designTheme", "screenInstances", "thumbnailScreenshot", "metadata"] },
|
|
69
|
+
},
|
|
56
70
|
];
|
|
57
71
|
export function conectorDelCatalogo(id) {
|
|
58
72
|
return CATALOGO_DE_CONECTORES.find((c) => c.id === id);
|
|
@@ -162,6 +176,12 @@ export function estadoDeConector(conector, hayCredencial) {
|
|
|
162
176
|
export const TTL_DE_AUTORIZACION_MS = 10 * 60 * 1000;
|
|
163
177
|
/** Conectar + listar tools: más que esto es «no responde». */
|
|
164
178
|
export const TOPE_DE_CONEXION_MS = 30 * 1000;
|
|
179
|
+
/**
|
|
180
|
+
* Una llamada de un AGENTE a una tool: generar una pantalla en Stitch tarda minutos (medido: casi
|
|
181
|
+
* dos), y con el tope de conexión el agente veía un fallo de algo que sí terminaba. El SDK tiene su
|
|
182
|
+
* PROPIO tope por petición (60 s por omisión), así que este valor se le pasa también a él.
|
|
183
|
+
*/
|
|
184
|
+
export const TOPE_DE_LLAMADA_MS = 10 * 60 * 1000;
|
|
165
185
|
/** La ruta del callback. PÚBLICA: la redirección llega sin cookie (`SameSite=Strict`). */
|
|
166
186
|
export const RUTA_CALLBACK_MCP = "/mcp/oauth/callback";
|
|
167
187
|
/**
|
|
@@ -188,4 +208,129 @@ export function interpretarCallback(query, pendientes, ahora) {
|
|
|
188
208
|
return { ok: false, motivo: "la respuesta no trae código de autorización" };
|
|
189
209
|
return { ok: true, id: pendiente.id, code };
|
|
190
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* Qué conectores del proyecto llegan a un AGENTE: los marcados en su `config.json`
|
|
213
|
+
* (`conectores`), que sigan AÑADIDOS y que esta consola sepa nombrar — y NUNCA el del gestor de
|
|
214
|
+
* tareas vinculado, aunque esté en la misma lista (vincular lo marca): en Jira y en Notion escribe
|
|
215
|
+
* el HARNESS, con su tarjeta, nunca el agente. El orden es el de los marcados; un id repetido
|
|
216
|
+
* sale una vez.
|
|
217
|
+
*/
|
|
218
|
+
export function conectoresParaElAgente(entrada) {
|
|
219
|
+
const vistos = new Set();
|
|
220
|
+
const salida = [];
|
|
221
|
+
for (const id of entrada.marcados) {
|
|
222
|
+
if (vistos.has(id) || id === entrada.gestor || !entrada.anadidos.includes(id))
|
|
223
|
+
continue;
|
|
224
|
+
const fila = entrada.catalogo.find((c) => c.id === id);
|
|
225
|
+
if (fila === undefined)
|
|
226
|
+
continue;
|
|
227
|
+
vistos.add(id);
|
|
228
|
+
const deCodigo = conectorDelCatalogo(id);
|
|
229
|
+
salida.push({ id, nombre: fila.nombre, fueraDelAgente: deCodigo?.fueraDelAgente ?? [], camposFueraDelResultado: deCodigo?.camposFueraDelResultado ?? {} });
|
|
230
|
+
}
|
|
231
|
+
return salida;
|
|
232
|
+
}
|
|
233
|
+
/** Lo que admite un nombre de función en los proveedores de modelos: `^[a-zA-Z0-9_-]{1,64}$`. */
|
|
234
|
+
export const LARGO_MAXIMO_DE_NOMBRE_DE_TOOL = 64;
|
|
235
|
+
/**
|
|
236
|
+
* Cómo se llama la tool `tool` del conector `id` DENTRO del agente: `stitch__list_projects`. El
|
|
237
|
+
* prefijo evita que dos conectores con una tool del mismo nombre se pisen, y dice de dónde viene.
|
|
238
|
+
* Un `custom:acme` lleva `:`, que un proveedor rechaza como nombre de función: todo lo que no sea
|
|
239
|
+
* `[a-zA-Z0-9_-]` pasa a `_`. Recortado al máximo; devuelve `undefined` si ni así cabe algo que
|
|
240
|
+
* identifique a la tool (un prefijo que ya ocupa el máximo).
|
|
241
|
+
*/
|
|
242
|
+
export function nombreDeToolDeConector(id, tool) {
|
|
243
|
+
const limpio = (t) => t.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
244
|
+
const nombre = `${limpio(id)}__${limpio(tool)}`;
|
|
245
|
+
return nombre.length <= LARGO_MAXIMO_DE_NOMBRE_DE_TOOL ? nombre : undefined;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Qué tools de los conectores recibe un ESPECIALISTA: todas, solo quien hace los RECURSOS —su
|
|
249
|
+
* `escribeEn` cubre `icons/`, de los de serie `designer-xone`—, que es quien diseña; el resto,
|
|
250
|
+
* ninguna. Regla de DATO, no una lista de nombres. Estrecha a propósito: las tools de un conector
|
|
251
|
+
* viajan en CADA llamada del agente que las recibe (las de Stitch, miles de tokens). El raíz recibe
|
|
252
|
+
* solo las de LECTURA, y eso lo decide la sesión: es de solo lectura por permisos.
|
|
253
|
+
*/
|
|
254
|
+
export function recibeConectores(a) {
|
|
255
|
+
if (a.soloLectura || a.ejecucion === true)
|
|
256
|
+
return false;
|
|
257
|
+
const carpetas = a.escribeEn ?? [];
|
|
258
|
+
return carpetas.some((c) => `/${CARPETA_DE_ICONOS}/`.startsWith(c.endsWith("/") ? c : `${c}/`));
|
|
259
|
+
}
|
|
260
|
+
/** Cuántos `$ref` anidados se incrustan antes de cortar: un esquema recursivo no puede colgar esto. */
|
|
261
|
+
export const PROFUNDIDAD_MAXIMA_DE_REF = 8;
|
|
262
|
+
/**
|
|
263
|
+
* El esquema de una tool tal como se le puede dar a CUALQUIER proveedor de modelos. Medido con
|
|
264
|
+
* Stitch y Gemini: los esquemas de Google llevan claves propias (`x-google-identifier`,
|
|
265
|
+
* `x-google-enum-descriptions`…) y la API de Gemini RECHAZA la petición entera por una sola —el
|
|
266
|
+
* turno moría antes de empezar—. Se quitan las claves `x-…` (son anotaciones, no restricciones) y
|
|
267
|
+
* se INCRUSTA cada `$ref` local (`#/$defs/…`), que no todos los proveedores siguen; `$defs` sale
|
|
268
|
+
* con ellos. Dentro de `properties` las claves son NOMBRES de campo y no se tocan. Puro: no
|
|
269
|
+
* modifica lo que recibe.
|
|
270
|
+
*/
|
|
271
|
+
export function esquemaParaElModelo(esquema) {
|
|
272
|
+
const defs = (esquema["$defs"] ?? {});
|
|
273
|
+
const limpiar = (nodo, profundidad) => {
|
|
274
|
+
if (Array.isArray(nodo))
|
|
275
|
+
return nodo.map((n) => limpiar(n, profundidad));
|
|
276
|
+
if (nodo === null || typeof nodo !== "object")
|
|
277
|
+
return nodo;
|
|
278
|
+
const o = nodo;
|
|
279
|
+
const ref = o["$ref"];
|
|
280
|
+
if (typeof ref === "string" && ref.startsWith("#/$defs/")) {
|
|
281
|
+
const destino = defs[ref.slice("#/$defs/".length)];
|
|
282
|
+
const { $ref: _ref, ...resto } = o;
|
|
283
|
+
if (destino === undefined || profundidad >= PROFUNDIDAD_MAXIMA_DE_REF)
|
|
284
|
+
return limpiar({ type: "object", ...resto }, profundidad);
|
|
285
|
+
return limpiar({ ...destino, ...resto }, profundidad + 1);
|
|
286
|
+
}
|
|
287
|
+
const salida = {};
|
|
288
|
+
for (const [clave, valor] of Object.entries(o)) {
|
|
289
|
+
if (clave.startsWith("x-") || clave === "$defs" || clave === "$schema")
|
|
290
|
+
continue;
|
|
291
|
+
salida[clave] =
|
|
292
|
+
clave === "properties" && valor !== null && typeof valor === "object" && !Array.isArray(valor)
|
|
293
|
+
? Object.fromEntries(Object.entries(valor).map(([nombre, v]) => [nombre, limpiar(v, profundidad)]))
|
|
294
|
+
: limpiar(valor, profundidad);
|
|
295
|
+
}
|
|
296
|
+
return salida;
|
|
297
|
+
};
|
|
298
|
+
return limpiar(esquema, 0);
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* El resultado de una tool sin los `campos` que el catálogo le recorta (`camposFueraDelResultado`),
|
|
302
|
+
* a cualquier profundidad, con una línea al final que dice cuáles faltan —que el agente no los dé
|
|
303
|
+
* por inexistentes—. Lo que no es JSON, o no trae ninguno, vuelve TAL CUAL.
|
|
304
|
+
*/
|
|
305
|
+
export function resultadoRecortado(texto, campos) {
|
|
306
|
+
if (campos.length === 0)
|
|
307
|
+
return texto;
|
|
308
|
+
let datos;
|
|
309
|
+
try {
|
|
310
|
+
datos = JSON.parse(texto);
|
|
311
|
+
}
|
|
312
|
+
catch {
|
|
313
|
+
return texto;
|
|
314
|
+
}
|
|
315
|
+
const fuera = new Set(campos);
|
|
316
|
+
const quitados = new Set();
|
|
317
|
+
const podar = (n) => {
|
|
318
|
+
if (Array.isArray(n))
|
|
319
|
+
return n.map(podar);
|
|
320
|
+
if (n === null || typeof n !== "object")
|
|
321
|
+
return n;
|
|
322
|
+
const salida = {};
|
|
323
|
+
for (const [k, v] of Object.entries(n)) {
|
|
324
|
+
if (fuera.has(k))
|
|
325
|
+
quitados.add(k);
|
|
326
|
+
else
|
|
327
|
+
salida[k] = podar(v);
|
|
328
|
+
}
|
|
329
|
+
return salida;
|
|
330
|
+
};
|
|
331
|
+
const podado = podar(datos);
|
|
332
|
+
if (quitados.size === 0)
|
|
333
|
+
return texto;
|
|
334
|
+
return `${JSON.stringify(podado)}\n(recortado por el harness: sin ${[...quitados].join(", ")}; el detalle de uno, con la tool que lo lee entero)`;
|
|
335
|
+
}
|
|
191
336
|
//# sourceMappingURL=conectores.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conectores.js","sourceRoot":"","sources":["../../src/core/conectores.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"conectores.js","sourceRoot":"","sources":["../../src/core/conectores.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Las reglas PURAS de «Nuevo emulador a partir de uno existente»: qué se lee de un AVD base y qué
|
|
3
|
+
* se copia al nuevo. El disco y `avdmanager` viven en `agent/dispositivos/instalacionEnMaquina.ts`.
|
|
4
|
+
*
|
|
5
|
+
* Dos modos, y la diferencia es cuánto de la base viaja:
|
|
6
|
+
* - CONFIGURACIÓN: `avdmanager` crea un AVD vacío con la imagen y el perfil de la base, y se le
|
|
7
|
+
* pone encima el `config.ini` de la base (RAM, disco…). Vale con la base encendida.
|
|
8
|
+
* - CLON: se copia la carpeta entera (lo instalado), salvo lo que `seCopiaEnClon` excluye. La base
|
|
9
|
+
* tiene que estar apagada: sus discos están bloqueados mientras corre.
|
|
10
|
+
*/
|
|
11
|
+
/** Las líneas `clave=valor` de un `.ini` de AVD. Sin `=` o en blanco se ignoran; el valor va tal cual. */
|
|
12
|
+
export function leerIni(texto) {
|
|
13
|
+
const r = new Map();
|
|
14
|
+
for (const linea of texto.split(/\r?\n/)) {
|
|
15
|
+
const i = linea.indexOf("=");
|
|
16
|
+
if (i <= 0)
|
|
17
|
+
continue;
|
|
18
|
+
r.set(linea.slice(0, i).trim(), linea.slice(i + 1).trim());
|
|
19
|
+
}
|
|
20
|
+
return r;
|
|
21
|
+
}
|
|
22
|
+
const FORMA_DE_SYSDIR = /^system-images\/([^/;\s]+)\/([^/;\s]+)\/([^/;\s]+)\/?$/;
|
|
23
|
+
/**
|
|
24
|
+
* El paquete de imagen para `avdmanager -k`, de `image.sysdir.1`:
|
|
25
|
+
* `system-images/android-35/google_apis/arm64-v8a/` → `system-images;android-35;google_apis;arm64-v8a`.
|
|
26
|
+
* Sin esa forma no se adivina nada: `undefined`.
|
|
27
|
+
*/
|
|
28
|
+
export function paqueteDeImagen(config) {
|
|
29
|
+
const m = FORMA_DE_SYSDIR.exec(config.get("image.sysdir.1") ?? "");
|
|
30
|
+
return m === null ? undefined : `system-images;${m[1]};${m[2]};${m[3]}`;
|
|
31
|
+
}
|
|
32
|
+
const FORMA_DE_PERFIL = /^[A-Za-z0-9._-]+$/;
|
|
33
|
+
/** El perfil de teléfono (`-d`) de la base: `hw.device.name`, si tiene forma de un nombre de perfil. */
|
|
34
|
+
export function perfilDeTelefono(config) {
|
|
35
|
+
const p = config.get("hw.device.name");
|
|
36
|
+
return p !== undefined && FORMA_DE_PERFIL.test(p) ? p : undefined;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* El `<nombre>.ini` del clon: el de la base con `path` y `path.rel` apuntando a la carpeta nueva.
|
|
40
|
+
* Lo demás (`target`, codificación…) se conserva. Si la base no traía alguna de las dos claves se
|
|
41
|
+
* AÑADE: un `.ini` sin `path` no lo encuentra nadie.
|
|
42
|
+
*/
|
|
43
|
+
export function iniDeClon(iniBase, nombre, carpetaAvd) {
|
|
44
|
+
const nuevas = { path: carpetaAvd, "path.rel": `avd/${nombre}.avd` };
|
|
45
|
+
const puestas = new Set();
|
|
46
|
+
const lineas = iniBase.split(/\r?\n/).filter((l, i, todas) => !(l === "" && i === todas.length - 1));
|
|
47
|
+
const salida = lineas.map((linea) => {
|
|
48
|
+
const i = linea.indexOf("=");
|
|
49
|
+
const clave = i > 0 ? linea.slice(0, i).trim() : undefined;
|
|
50
|
+
if (clave !== undefined && clave in nuevas) {
|
|
51
|
+
puestas.add(clave);
|
|
52
|
+
return `${clave}=${nuevas[clave]}`;
|
|
53
|
+
}
|
|
54
|
+
return linea;
|
|
55
|
+
});
|
|
56
|
+
for (const [clave, valor] of Object.entries(nuevas))
|
|
57
|
+
if (!puestas.has(clave))
|
|
58
|
+
salida.push(`${clave}=${valor}`);
|
|
59
|
+
return `${salida.join("\n")}\n`;
|
|
60
|
+
}
|
|
61
|
+
/** Ficheros sueltos de la carpeta de un AVD que NO viajan al clon: son de la última ejecución del original. */
|
|
62
|
+
const FICHEROS_QUE_NO_SE_COPIAN = new Set([
|
|
63
|
+
"hardware-qemu.ini", // lleva la ruta absoluta del original, tres veces; el emulador lo regenera
|
|
64
|
+
"emu-launch-params.txt", // ídem
|
|
65
|
+
"read-snapshot.txt",
|
|
66
|
+
"snapshot.trace",
|
|
67
|
+
"tmpAdbCmds",
|
|
68
|
+
"bootcompleted.ini",
|
|
69
|
+
]);
|
|
70
|
+
/**
|
|
71
|
+
* ¿Entra en el clon esta ruta, relativa a la carpeta del AVD (separada por `/` o `\`)? Lista NEGRA:
|
|
72
|
+
* los `.lock` en cualquier nivel (el original los tiene cogidos) y los ficheros de la última
|
|
73
|
+
* ejecución. `snapshots/` SÍ viaja (medido): al parar, el emulador guarda la memoria en la
|
|
74
|
+
* instantánea, y lo que aún no se volcó al disco solo vive ahí; sin ella, el clon ve un disco a
|
|
75
|
+
* medias (un fichero escrito salía con 0 bytes). Hay que reescribirles la identidad
|
|
76
|
+
* (`hardwareIniDeClon`) o el emulador las rechaza.
|
|
77
|
+
*/
|
|
78
|
+
export function seCopiaEnClon(relativa) {
|
|
79
|
+
const partes = relativa.split(/[\\/]/).filter((p) => p !== "" && p !== ".");
|
|
80
|
+
if (partes.length === 0)
|
|
81
|
+
return true;
|
|
82
|
+
const ultimo = partes[partes.length - 1];
|
|
83
|
+
if (ultimo.endsWith(".lock"))
|
|
84
|
+
return false;
|
|
85
|
+
return !(partes.length === 1 && FICHEROS_QUE_NO_SE_COPIAN.has(ultimo));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* El `hardware.ini` de una instantánea del clon, con la identidad del original cambiada por la del
|
|
89
|
+
* clon (medido: con solo las rutas el emulador rechaza la instantánea —«cannot load snapshot»—; con
|
|
90
|
+
* las dos cosas la carga). Formato `clave = valor`, con espacios. Solo se tocan:
|
|
91
|
+
* - `avd.name` y `avd.id`, si valen exactamente la base;
|
|
92
|
+
* - en cualquier otro valor, los segmentos de ruta `<base>.avd` EXACTOS (entre `/` o `\`, o al
|
|
93
|
+
* final), nunca el nombre suelto: la base podría aparecer dentro de otra palabra.
|
|
94
|
+
*/
|
|
95
|
+
export function hardwareIniDeClon(texto, base, nombre) {
|
|
96
|
+
const escapada = base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
97
|
+
const segmento = new RegExp(`(^|[\\\\/])${escapada}\\.avd(?=[\\\\/]|$)`, "g");
|
|
98
|
+
return texto
|
|
99
|
+
.split("\n")
|
|
100
|
+
.map((linea) => {
|
|
101
|
+
const m = /^(\s*)([^=\s][^=]*?)(\s*=\s*)(.*?)(\r?)$/.exec(linea);
|
|
102
|
+
if (m === null)
|
|
103
|
+
return linea;
|
|
104
|
+
const [, sangria, clave, igual, valor, cr] = m;
|
|
105
|
+
if (clave === "avd.name" || clave === "avd.id")
|
|
106
|
+
return `${sangria}${clave}${igual}${valor === base ? nombre : valor}${cr}`;
|
|
107
|
+
return `${sangria}${clave}${igual}${valor.replace(segmento, `$1${nombre}.avd`)}${cr}`;
|
|
108
|
+
})
|
|
109
|
+
.join("\n");
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=copiaDeAvd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copiaDeAvd.js","sourceRoot":"","sources":["../../src/core/copiaDeAvd.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { posix } from "node:path";
|
|
2
|
-
import { rutaDeWorkspace } from "./settings.js";
|
|
1
|
+
import { posix, win32 } from "node:path";
|
|
2
|
+
import { esRutaDeWindows, rutaDeWorkspace } from "./settings.js";
|
|
3
3
|
/**
|
|
4
4
|
* El literal que vivía en MEDIO del reparto: `<base>/<entorno>/workspace/<proyecto>`.
|
|
5
5
|
*
|
|
@@ -12,16 +12,30 @@ export const CARPETA_DEL_REPARTO_VIEJO = "workspace";
|
|
|
12
12
|
function esSegmentoLlano(valor) {
|
|
13
13
|
return valor !== "" && valor !== "." && valor !== ".." && !/[/\\]/.test(valor);
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Los segmentos de una ruta, con la barra invertida de Windows como separador cuando la ruta
|
|
17
|
+
* es de Windows. Con `posix` a secas, `C:\Users\…` era UN segmento y ni la guarda de anidadas
|
|
18
|
+
* ni `rutaMudada` veían nada dentro de nada.
|
|
19
|
+
*/
|
|
20
|
+
function segmentos(ruta) {
|
|
21
|
+
const windows = esRutaDeWindows(ruta);
|
|
22
|
+
const barras = windows ? ruta.replace(/\\/g, "/") : ruta;
|
|
23
|
+
return posix.normalize(barras).replace(/(?<=.)\/+$/, "").split("/");
|
|
24
|
+
}
|
|
25
|
+
/** Dos segmentos son el mismo: en Windows sin distinguir mayúsculas, como su disco. */
|
|
26
|
+
function mismoSegmento(a, b, windows) {
|
|
27
|
+
return windows ? a.toLowerCase() === b.toLowerCase() : a === b;
|
|
28
|
+
}
|
|
29
|
+
/** ¿`prefijo` es la ruta `ruta` o una antepasada suya? Por SEGMENTOS, nunca por texto. */
|
|
30
|
+
function empiezaPor(ruta, prefijo, windows) {
|
|
31
|
+
return prefijo.length <= ruta.length && prefijo.every((seg, i) => mismoSegmento(seg, ruta[i], windows));
|
|
17
32
|
}
|
|
18
33
|
/** ¿Son la misma ruta, o una es antepasada de la otra? Por SEGMENTOS, nunca por texto. */
|
|
19
34
|
function unaCuelgaDeLaOtra(a, b) {
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
return corto.every((seg, i) => largo[i] === seg);
|
|
35
|
+
const windows = esRutaDeWindows(a) || esRutaDeWindows(b);
|
|
36
|
+
const uno = segmentos(a);
|
|
37
|
+
const otro = segmentos(b);
|
|
38
|
+
return empiezaPor(uno, otro, windows) || empiezaPor(otro, uno, windows);
|
|
25
39
|
}
|
|
26
40
|
/**
|
|
27
41
|
* Qué copias locales siguen en el reparto viejo y adónde van.
|
|
@@ -82,15 +96,91 @@ export function mudanzasPendientes(opciones) {
|
|
|
82
96
|
* entrada para decidir si reescribe el fichero.
|
|
83
97
|
*/
|
|
84
98
|
export function rutaMudada(ruta, mudanzas) {
|
|
85
|
-
const partes =
|
|
99
|
+
const partes = segmentos(ruta);
|
|
86
100
|
for (const mudanza of mudanzas) {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (!origen.every((seg, i) => partes[i] === seg))
|
|
101
|
+
const windows = esRutaDeWindows(ruta) || esRutaDeWindows(mudanza.desde);
|
|
102
|
+
const origen = segmentos(mudanza.desde);
|
|
103
|
+
if (!empiezaPor(partes, origen, windows))
|
|
91
104
|
continue;
|
|
92
|
-
|
|
105
|
+
// Con las reglas del DESTINO: una base de Windows se compone con `\`.
|
|
106
|
+
return (esRutaDeWindows(mudanza.hacia) ? win32 : posix).join(mudanza.hacia, ...partes.slice(origen.length));
|
|
93
107
|
}
|
|
94
108
|
return undefined;
|
|
95
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Una ruta traducida a través de VARIAS mudanzas, en el orden en que ocurrieron: cada tanda
|
|
112
|
+
* es el plan de un cambio de base, y la salida de una es la entrada de la siguiente.
|
|
113
|
+
*
|
|
114
|
+
* Existe porque `rutaMudada` coge la PRIMERA coincidencia, que dentro de UN plan es correcto
|
|
115
|
+
* (sus orígenes no se solapan) y entre varios no: con ir de A a B y volver a A, una lista plana
|
|
116
|
+
* traducía `A/…` a `B/…` —la ida— aunque la vuelta ya había vaciado `B`, y abrir el proyecto
|
|
117
|
+
* abría una carpeta que no existe. Encadenadas, `A/…` va a `B/…` y vuelve a `A/…`.
|
|
118
|
+
*/
|
|
119
|
+
export function rutaTrasLasMudanzas(ruta, tandas) {
|
|
120
|
+
let actual = ruta;
|
|
121
|
+
for (const tanda of tandas)
|
|
122
|
+
actual = rutaMudada(actual, tanda) ?? actual;
|
|
123
|
+
return actual;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Qué copias hay que MUDAR al cambiar el workspace de `desde` a `hacia`, o por qué no se
|
|
127
|
+
* puede — antes de tocar nada.
|
|
128
|
+
*
|
|
129
|
+
* **Se listan las carpetas REALES** `<desde>/<entorno>/<proyecto>`, no los entornos
|
|
130
|
+
* registrados: quitar un entorno de Ajustes no borra sus copias, y una mudanza que solo mirara
|
|
131
|
+
* la lista las dejaría huérfanas en la base vieja. Lo OCULTO no es un proyecto —las lápidas
|
|
132
|
+
* `.<proyecto>.borrando-…` que un borrado a medias deja (`borrarCopiaDeProyecto`) y las
|
|
133
|
+
* carpetas temporales de una mudanza cortada—, y se queda fuera.
|
|
134
|
+
*
|
|
135
|
+
* Tres noes, y todos antes de copiar un byte:
|
|
136
|
+
* - **una base cuelga de la otra** (o son la misma): copiar una carpeta dentro de sí misma no
|
|
137
|
+
* termina, y al revés la base vieja pasaría a parecer un entorno de la nueva;
|
|
138
|
+
* - **dentro de la casa de xonecode** (`~/.xonecode`), salvo su `workspace` de omisión: ahí
|
|
139
|
+
* viven `tareas/`, `agentes/` y `auth.json`, y un entorno llamado igual se mezclaría con
|
|
140
|
+
* ellos;
|
|
141
|
+
* - **un destino que ya existe**: se NIEGA ENTERO, nunca se pisa. En esa carpeta puede haber
|
|
142
|
+
* otra historia de git y otro checkpoint, y mudar la mitad dejaría el workspace partido.
|
|
143
|
+
*/
|
|
144
|
+
export function planDeCambioDeBase(opciones) {
|
|
145
|
+
const { desde, hacia, casaXonecode } = opciones;
|
|
146
|
+
if (unaCuelgaDeLaOtra(desde, hacia)) {
|
|
147
|
+
return {
|
|
148
|
+
mudanzas: [],
|
|
149
|
+
motivo: "la carpeta nueva no puede estar dentro de la de ahora, ni al revés: elige una que no cuelgue de la otra",
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const windows = esRutaDeWindows(hacia) || esRutaDeWindows(casaXonecode);
|
|
153
|
+
const nueva = segmentos(hacia);
|
|
154
|
+
const casa = segmentos(casaXonecode);
|
|
155
|
+
const deOmision = segmentos((esRutaDeWindows(casaXonecode) ? win32 : posix).join(casaXonecode, "workspace"));
|
|
156
|
+
if (empiezaPor(nueva, casa, windows) && !empiezaPor(nueva, deOmision, windows)) {
|
|
157
|
+
return {
|
|
158
|
+
mudanzas: [],
|
|
159
|
+
motivo: "esa carpeta es la de la configuración de XOneCode (tareas, agentes, credenciales): elige otra fuera de ella",
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const mudanzas = [];
|
|
163
|
+
const ocupadas = [];
|
|
164
|
+
const separador = esRutaDeWindows(desde) ? win32 : posix;
|
|
165
|
+
for (const entorno of opciones.listar(desde)) {
|
|
166
|
+
if (!esSegmentoLlano(entorno) || entorno.startsWith("."))
|
|
167
|
+
continue;
|
|
168
|
+
for (const proyecto of opciones.listar(separador.join(desde, entorno))) {
|
|
169
|
+
if (!esSegmentoLlano(proyecto) || proyecto.startsWith("."))
|
|
170
|
+
continue;
|
|
171
|
+
const mudanza = { entorno, proyecto, desde: separador.join(desde, entorno, proyecto), hacia: rutaDeWorkspace(hacia, entorno, proyecto) };
|
|
172
|
+
if (opciones.existe(mudanza.hacia))
|
|
173
|
+
ocupadas.push(`${proyecto} (${entorno})`);
|
|
174
|
+
else
|
|
175
|
+
mudanzas.push(mudanza);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (ocupadas.length > 0) {
|
|
179
|
+
return {
|
|
180
|
+
mudanzas: [],
|
|
181
|
+
motivo: `en la carpeta nueva ya hay ${ocupadas.length === 1 ? "una copia" : "copias"} de ${ocupadas.join(", ")}: no se pisa nada, así que no se muda ninguna`,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return { mudanzas };
|
|
185
|
+
}
|
|
96
186
|
//# sourceMappingURL=mudanzaDeWorkspace.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mudanzaDeWorkspace.js","sourceRoot":"","sources":["../../src/core/mudanzaDeWorkspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"mudanzaDeWorkspace.js","sourceRoot":"","sources":["../../src/core/mudanzaDeWorkspace.ts"],"names":[],"mappings":"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"}
|
package/dist/core/ports.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* Este fichero es TypeScript puro: no importa langchain, langgraph, deepagents, MCP,
|
|
9
9
|
* Ink ni React. La frontera está probada en `core/imports.test.ts`.
|
|
10
10
|
*/
|
|
11
|
+
import { sumarPorModelo } from "./actos.js";
|
|
11
12
|
/**
|
|
12
13
|
* La marca de «esto es un doble», y por qué es un Symbol y no un booleano.
|
|
13
14
|
*
|
|
@@ -59,6 +60,7 @@ export function consumoPersistible(c) {
|
|
|
59
60
|
modelo: { ...c.modelo },
|
|
60
61
|
externo: { ...c.externo },
|
|
61
62
|
...(c.contexto === 0 ? {} : { ventana: c.contexto }),
|
|
63
|
+
...(c.porModelo === undefined ? {} : { porModelo: sumarPorModelo({}, c.porModelo) }),
|
|
62
64
|
};
|
|
63
65
|
}
|
|
64
66
|
/**
|
|
@@ -74,6 +76,7 @@ export function consumoDeLaSesion(c) {
|
|
|
74
76
|
modelo: { ...c.modelo },
|
|
75
77
|
externo: { ...c.externo },
|
|
76
78
|
contexto: c.ventana ?? 0,
|
|
79
|
+
...(c.porModelo === undefined ? {} : { porModelo: sumarPorModelo({}, c.porModelo) }),
|
|
77
80
|
};
|
|
78
81
|
}
|
|
79
82
|
/**
|
|
@@ -377,4 +380,29 @@ export class IconosEnMemoria {
|
|
|
377
380
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="${tamano}" height="${tamano}" viewBox="0 0 24 24"><path fill="${color}" d="M0 0h24v24H0z"/></svg>`;
|
|
378
381
|
}
|
|
379
382
|
}
|
|
383
|
+
/** El doble: conectores fijos, sin red. `llamadas` deja ver qué llegó; `fallo` simula la red caída. */
|
|
384
|
+
export class ConectoresEnMemoria {
|
|
385
|
+
conectores;
|
|
386
|
+
fallo;
|
|
387
|
+
[ES_DOBLE] = true;
|
|
388
|
+
llamadas = [];
|
|
389
|
+
constructor(conectores = {}, fallo) {
|
|
390
|
+
this.conectores = conectores;
|
|
391
|
+
this.fallo = fallo;
|
|
392
|
+
}
|
|
393
|
+
delProyecto() {
|
|
394
|
+
return Object.entries(this.conectores).map(([id, c]) => ({ id, nombre: c.nombre, fueraDelAgente: [], camposFueraDelResultado: {} }));
|
|
395
|
+
}
|
|
396
|
+
async tools(id) {
|
|
397
|
+
if (this.fallo !== undefined)
|
|
398
|
+
throw new Error(this.fallo);
|
|
399
|
+
return this.conectores[id]?.tools ?? [];
|
|
400
|
+
}
|
|
401
|
+
async llamar(id, nombre, args, opciones) {
|
|
402
|
+
this.llamadas.push({ id, nombre, args, ...(opciones?.topeMs === undefined ? {} : { topeMs: opciones.topeMs }) });
|
|
403
|
+
if (this.fallo !== undefined)
|
|
404
|
+
throw new Error(this.fallo);
|
|
405
|
+
return this.conectores[id]?.respuesta ?? "";
|
|
406
|
+
}
|
|
407
|
+
}
|
|
380
408
|
//# sourceMappingURL=ports.js.map
|