xonecode 0.29.0 → 0.33.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 (82) hide show
  1. package/apps/web/dist/assets/{EditorDeFichero-ChyJtiiz.js → EditorDeFichero-H_kGeZt2.js} +1 -1
  2. package/apps/web/dist/assets/{index-IptObD2z.css → index-CWBaotdZ.css} +1 -1
  3. package/apps/web/dist/assets/index-DnGuOvbb.js +499 -0
  4. package/apps/web/dist/assets/{php-B91ZcS-9.js → php-CMFQiZgk.js} +1 -1
  5. package/apps/web/dist/assets/{ruby-DrxrTSz0.js → ruby-Dj3BOBHc.js} +1 -1
  6. package/apps/web/dist/index.html +2 -2
  7. package/dist/agent/config/modelosDeMotor.js +4 -2
  8. package/dist/agent/config/modelosDeMotor.js.map +1 -1
  9. package/dist/agent/config/settingsEnDisco.js +26 -0
  10. package/dist/agent/config/settingsEnDisco.js.map +1 -1
  11. package/dist/agent/dispositivos/cajasDeMaqueta.js +130 -0
  12. package/dist/agent/dispositivos/cajasDeMaqueta.js.map +1 -0
  13. package/dist/agent/dispositivos/geometriaEnDisco.js +25 -0
  14. package/dist/agent/dispositivos/geometriaEnDisco.js.map +1 -0
  15. package/dist/agent/dispositivos/juezVisual.js +84 -3
  16. package/dist/agent/dispositivos/juezVisual.js.map +1 -1
  17. package/dist/agent/grafo/criticaVisual.js +240 -11
  18. package/dist/agent/grafo/criticaVisual.js.map +1 -1
  19. package/dist/agent/grafo/lectorDeReferencias.js +21 -0
  20. package/dist/agent/grafo/lectorDeReferencias.js.map +1 -1
  21. package/dist/agent/grafo/validarFicheroXone.js +114 -0
  22. package/dist/agent/grafo/validarFicheroXone.js.map +1 -0
  23. package/dist/agent/motores/motoresLocales.js +429 -0
  24. package/dist/agent/motores/motoresLocales.js.map +1 -0
  25. package/dist/agent/motores/trueforge/sesionTrueforge.js +79 -11
  26. package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
  27. package/dist/agent/motores/trueforge/toolsDeFichero.js +24 -6
  28. package/dist/agent/motores/trueforge/toolsDeFichero.js.map +1 -1
  29. package/dist/agent/sesiones/adjuntosDeSesion.js +125 -5
  30. package/dist/agent/sesiones/adjuntosDeSesion.js.map +1 -1
  31. package/dist/agent/subagentes/ejecutableEnWindows.js +139 -0
  32. package/dist/agent/subagentes/ejecutableEnWindows.js.map +1 -0
  33. package/dist/agent/subagentes/subagenteCodex.js +7 -2
  34. package/dist/agent/subagentes/subagenteCodex.js.map +1 -1
  35. package/dist/agent/subagentes/subagenteOpencode.js +12 -5
  36. package/dist/agent/subagentes/subagenteOpencode.js.map +1 -1
  37. package/dist/agent/turno/resumenDeTool.js +2 -0
  38. package/dist/agent/turno/resumenDeTool.js.map +1 -1
  39. package/dist/core/adjuntos.js +10 -2
  40. package/dist/core/adjuntos.js.map +1 -1
  41. package/dist/core/contextos.js +20 -0
  42. package/dist/core/contextos.js.map +1 -1
  43. package/dist/core/cssBienFormado.js +97 -0
  44. package/dist/core/cssBienFormado.js.map +1 -0
  45. package/dist/core/descripcionDePantalla.js +354 -0
  46. package/dist/core/descripcionDePantalla.js.map +1 -0
  47. package/dist/core/estiloMedido.js +332 -0
  48. package/dist/core/estiloMedido.js.map +1 -0
  49. package/dist/core/geometriaDePantalla.js +437 -0
  50. package/dist/core/geometriaDePantalla.js.map +1 -0
  51. package/dist/core/jsParaRhino.js +93 -0
  52. package/dist/core/jsParaRhino.js.map +1 -0
  53. package/dist/core/motoresLocales.js +128 -0
  54. package/dist/core/motoresLocales.js.map +1 -0
  55. package/dist/core/notify.js +2 -0
  56. package/dist/core/notify.js.map +1 -1
  57. package/dist/core/nucleoXone.js +6 -6
  58. package/dist/core/nucleoXone.js.map +1 -1
  59. package/dist/core/settings.js +5 -0
  60. package/dist/core/settings.js.map +1 -1
  61. package/dist/core/shellDeAgente.js +13 -0
  62. package/dist/core/shellDeAgente.js.map +1 -1
  63. package/dist/core/xmlBienFormado.js +206 -0
  64. package/dist/core/xmlBienFormado.js.map +1 -0
  65. package/dist/core/zipDeAdjunto.js +79 -0
  66. package/dist/core/zipDeAdjunto.js.map +1 -0
  67. package/dist/web/servidor/arranque.js +84 -0
  68. package/dist/web/servidor/arranque.js.map +1 -1
  69. package/dist/web/servidor/transporte.js.map +1 -1
  70. package/package.json +2 -1
  71. package/skills/xone-development/SKILL.md +2 -1
  72. package/skills/xone-development/references/css/buenas-practicas-y-parser.md +2 -1
  73. package/skills/xone-development/references/css/de-una-maqueta-a-xone.md +81 -0
  74. package/skills/xone-development/references/css/patrones-material-y-temas.md +15 -13
  75. package/skills/xone-development/references/css/propiedades-y-herencia.md +2 -2
  76. package/skills/xone-development/references/css/selectores-unidades-colores.md +8 -3
  77. package/skills/xone-development/references/indice-completo.md +1 -0
  78. package/skills/xone-hotswap/lib/geometria.mjs +147 -0
  79. package/skills/xone-hotswap/scripts/xone-captura-android +6 -0
  80. package/skills/xone-hotswap/scripts/xone-hotswap +8 -0
  81. package/skills/xone-hotswap/scripts/xone-recargar-android +15 -0
  82. package/apps/web/dist/assets/index-CFIrUOmW.js +0 -499
@@ -0,0 +1,429 @@
1
+ /**
2
+ * Los motores locales en la máquina: medir si están y con qué sesión, PROBARLOS con un encargo de
3
+ * verdad, e iniciar la sesión de Claude Code desde un botón. Las reglas puras están en
4
+ * `core/motoresLocales.ts`; aquí solo hay procesos.
5
+ *
6
+ * Tres decisiones que no se ven en el código:
7
+ *
8
+ * - **Se mide el binario que el SDK LANZA**, el de su paquete de plataforma, y no el `claude` del
9
+ * PATH: pueden ser versiones distintas (medido: 2.1.263 frente a 2.1.287), y medir el otro
10
+ * diría algo de un programa que los subagentes no corren. Sin respaldo al PATH, a propósito.
11
+ * - **La prueba sale por el MISMO puerto que un encargo real** (`crearSubagenteExterno().correr`),
12
+ * no por un `query()` montado aquí: una prueba con sus propias opciones mediría otra cosa —el
13
+ * patrón de fallo de siempre, una composición que solo existe donde nadie la usa—.
14
+ * - **`auth login` funciona sin TTY** (medido con el binario del SDK y un `CLAUDE_CONFIG_DIR`
15
+ * aislado): abre el navegador él solo, imprime un enlace de respaldo y espera «Paste code here
16
+ * if prompted». Así que el botón lanza el proceso y, si la web enseña un código, se le pasa
17
+ * por `stdin`. **El enlace no cruza el cable** (la regla de los conectores): si el navegador
18
+ * no se abrió, lo vuelve a abrir el SERVIDOR. Límite declarado: por un túnel no sirve.
19
+ */
20
+ import { exec, execFile, spawn } from "node:child_process";
21
+ import { mkdirSync } from "node:fs";
22
+ import { createRequire } from "node:module";
23
+ import { tmpdir } from "node:os";
24
+ import { join } from "node:path";
25
+ import { promisify } from "node:util";
26
+ import { INSTRUCCIONES_DE_PRUEBA, MOTORES_CON_MODELO, MOTORES_LOCALES, motivoDeModeloDeMotorInaceptable, TAREA_DE_PRUEBA, interpretarAuthStatusDeClaude, lineaDeSesionDeClaude, pideCodigo, recortar, respuestaDePruebaValida, sinUrls, ultimaLinea, urlDeAutorizacion, versionDeSalida, } from "../../core/motoresLocales.js";
27
+ import { entornoDeShell } from "../../core/shellDeAgente.js";
28
+ import { mensajeSeguro } from "../../core/trazaDeErrores.js";
29
+ import { describirFallo } from "../dispositivos/dispositivosEnMaquina.js";
30
+ import { abrirEnSistema } from "../cloudstudio/cloudstudioMcp.js";
31
+ import { crearSubagenteExterno } from "../subagentes/subagenteExterno.js";
32
+ import { binarioDeCodex } from "../subagentes/subagenteCodex.js";
33
+ import { binarioDeOpencode } from "../subagentes/subagenteOpencode.js";
34
+ import { guardarModeloDeOpencode, modeloDeOpencodeGuardado } from "../config/settingsEnDisco.js";
35
+ /** `--version` y `auth status`: si tardan más, el binario no está bien. */
36
+ export const TOPE_DE_MEDIDA_MS = 15_000;
37
+ /** Un primer arranque de Claude Code en frío tarda; dos minutos es «no contesta». */
38
+ export const TOPE_DE_PRUEBA_MS = 120_000;
39
+ /** Lo que se espera a que la persona termine en el navegador. */
40
+ export const TOPE_DE_LOGIN_MS = 10 * 60_000;
41
+ /**
42
+ * El `claude` del paquete de plataforma del SDK, con la MISMA regla con que lo busca el SDK
43
+ * (`sdk.mjs`): `@anthropic-ai/claude-agent-sdk-<plataforma>-<arquitectura>/claude[.exe]`, y en
44
+ * Linux las dos variantes de libc. Resuelto por el cargador de módulos, nunca contando `..`.
45
+ */
46
+ export function binarioDeClaudeDelSdk(plataforma = process.platform, arquitectura = process.arch, resolver = createRequire(import.meta.url).resolve) {
47
+ const base = "@anthropic-ai/claude-agent-sdk";
48
+ const paquetes = plataforma === "linux" ? [`${base}-linux-${arquitectura}`, `${base}-linux-${arquitectura}-musl`] : [`${base}-${plataforma}-${arquitectura}`];
49
+ const sufijo = plataforma === "win32" ? ".exe" : "";
50
+ for (const paquete of paquetes) {
51
+ try {
52
+ return resolver(`${paquete}/claude${sufijo}`);
53
+ }
54
+ catch {
55
+ // No está esta variante: la siguiente.
56
+ }
57
+ }
58
+ return undefined;
59
+ }
60
+ /** El entorno de NUESTRA shell, sin claves de API: el de un subagente con `ejecucion`. */
61
+ function limpio(entorno) {
62
+ return entornoDeShell({ entorno });
63
+ }
64
+ /** ¿El entorno heredado lleva algo de Anthropic que el limpio quita? Entonces son dos caminos. */
65
+ function heredaClaveDeAnthropic(entorno) {
66
+ const sin = limpio(entorno);
67
+ return Object.keys(entorno).some((k) => k.startsWith("ANTHROPIC_") && entorno[k] !== undefined && !(k in sin));
68
+ }
69
+ const execFileP = promisify(execFile);
70
+ const execP = promisify(exec);
71
+ /**
72
+ * Un proceso corto de verdad. Un nombre a secas en Windows va por la shell: `codex` y `opencode`
73
+ * los instala npm como `.cmd`, y `execFile` sin shell no los encuentra. Los argumentos son
74
+ * constantes de este fichero, así que componer la línea no abre ninguna inyección.
75
+ */
76
+ async function ejecutarReal(binario, args, opciones) {
77
+ const env = opciones.entorno;
78
+ if (process.platform === "win32" && !/[\\/]/.test(binario)) {
79
+ const { stdout, stderr } = await execP([binario, ...args].join(" "), { timeout: opciones.timeout, env, windowsHide: true, encoding: "utf8" });
80
+ return { stdout: String(stdout), stderr: String(stderr) };
81
+ }
82
+ const { stdout, stderr } = await execFileP(binario, [...args], { timeout: opciones.timeout, env, windowsHide: true, encoding: "utf8" });
83
+ return { stdout: String(stdout), stderr: String(stderr) };
84
+ }
85
+ function lanzarReal(binario, args, opciones) {
86
+ return spawn(binario, [...args], { env: opciones.entorno, stdio: ["pipe", "pipe", "pipe"], windowsHide: true });
87
+ }
88
+ /**
89
+ * Una terminal con el comando ya escrito: el respaldo de cuando el botón no puede (el navegador
90
+ * es de otra máquina, o la persona prefiere verlo). Solo Windows y macOS, donde se sabe qué
91
+ * terminal hay; en el resto no se ofrece, que es mejor que un botón que no hace nada.
92
+ */
93
+ function abrirTerminalReal(binario, args, entorno) {
94
+ const env = entorno;
95
+ if (process.platform === "win32") {
96
+ const comando = `& '${binario.replace(/'/g, "''")}' ${args.join(" ")}`;
97
+ const hijo = spawn("cmd.exe", ["/c", "start", "", "powershell", "-NoExit", "-Command", comando], { env, detached: true, stdio: "ignore" });
98
+ hijo.on("error", () => { });
99
+ hijo.unref();
100
+ return true;
101
+ }
102
+ if (process.platform === "darwin") {
103
+ const linea = `'${binario.replace(/'/g, `'\\''`)}' ${args.join(" ")}`;
104
+ const guion = `tell application "Terminal" to do script "${linea.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
105
+ const hijo = spawn("osascript", ["-e", guion, "-e", 'tell application "Terminal" to activate'], { env, detached: true, stdio: "ignore" });
106
+ hijo.on("error", () => { });
107
+ hijo.unref();
108
+ return true;
109
+ }
110
+ return false;
111
+ }
112
+ /**
113
+ * La prueba de producción: el MISMO puerto que corre un subagente, sin política de escritura
114
+ * (nada que escribir) y en una carpeta vacía fuera de cualquier proyecto. Con `con-ejecucion`
115
+ * lleva el entorno limpio, que es lo que recibe un agente con `ejecucion: true`.
116
+ */
117
+ async function probarReal(peticion) {
118
+ const cwd = join(tmpdir(), "xonecode-prueba-de-motor");
119
+ mkdirSync(cwd, { recursive: true });
120
+ return crearSubagenteExterno({}).correr({
121
+ motor: peticion.motor,
122
+ cwd,
123
+ instrucciones: INSTRUCCIONES_DE_PRUEBA,
124
+ tarea: TAREA_DE_PRUEBA,
125
+ permitirEscritura: false,
126
+ agente: "prueba-de-conexion",
127
+ senal: peticion.senal,
128
+ ...(peticion.camino === "con-ejecucion" ? { ejecucion: { scripts: [], entorno: peticion.entornoLimpio, lecturas: [] } } : {}),
129
+ });
130
+ }
131
+ /**
132
+ * La salida de un proceso que contesta TAMBIÉN cuando sale con otro código: `claude auth status`
133
+ * sin sesión imprime su JSON y sale con 1 (medido). Un tope o un binario que no está sí lanzan.
134
+ */
135
+ async function salidaAunqueFalle(promesa) {
136
+ try {
137
+ return (await promesa).stdout;
138
+ }
139
+ catch (error) {
140
+ const e = error;
141
+ if (e !== null && typeof e === "object" && e.killed !== true && typeof e.code === "number" && typeof e.stdout === "string") {
142
+ return e.stdout;
143
+ }
144
+ throw error;
145
+ }
146
+ }
147
+ /** Lo que se cuenta de un error: una línea, sin rutas ni enlaces. */
148
+ function motivoDe(error, topeMs) {
149
+ return recortar(sinUrls(mensajeSeguro(describirFallo(error, topeMs))));
150
+ }
151
+ export function crearServicioDeMotoresLocales(deps) {
152
+ const plataforma = deps.plataforma ?? process.platform;
153
+ const entorno = () => deps.entorno ?? process.env;
154
+ const ahora = () => (deps.ahora ?? (() => new Date()))().toISOString();
155
+ const binarioDeClaude = deps.binarioDeClaude ?? (() => binarioDeClaudeDelSdk());
156
+ const ejecutar = deps.ejecutar ?? ejecutarReal;
157
+ const lanzar = deps.lanzar ?? lanzarReal;
158
+ const probarMotor = deps.probar ?? probarReal;
159
+ const abrir = deps.abrir ?? ((url) => abrirEnSistema(new URL(url)));
160
+ const abrirTerminal = deps.abrirTerminal ?? abrirTerminalReal;
161
+ const admiteConsola = deps.abrirTerminal !== undefined || plataforma === "win32" || plataforma === "darwin";
162
+ const leerModelo = deps.leerModelo ?? ((motor) => (motor === "opencode" ? modeloDeOpencodeGuardado() : undefined));
163
+ const guardarModelo = deps.guardarModelo ??
164
+ ((motor, modelo) => {
165
+ if (motor === "opencode")
166
+ guardarModeloDeOpencode(undefined, modelo);
167
+ });
168
+ /** Lo que la tarjeta necesita para el selector: que lo admite, y cuál hay. */
169
+ const deModelo = (motor) => {
170
+ if (!MOTORES_CON_MODELO.includes(motor))
171
+ return {};
172
+ const modelo = leerModelo(motor);
173
+ return { admiteModelo: true, ...(modelo === undefined ? {} : { modelo }) };
174
+ };
175
+ const estados = new Map();
176
+ const logins = new Map();
177
+ let medida;
178
+ const poner = (motor, cambio, quitar = []) => {
179
+ const antes = estados.get(motor) ?? { motor, instalado: "fallo", medido: ahora() };
180
+ const nuevo = { ...antes, ...cambio };
181
+ for (const campo of quitar)
182
+ delete nuevo[campo];
183
+ estados.set(motor, nuevo);
184
+ deps.alCambiar();
185
+ };
186
+ async function medirClaude() {
187
+ const bin = binarioDeClaude();
188
+ if (bin === undefined) {
189
+ return { instalado: "no-encontrado", detalle: "el SDK de Claude Code no trae binario para este sistema" };
190
+ }
191
+ let version;
192
+ try {
193
+ version = versionDeSalida((await ejecutar(bin, ["--version"], { timeout: TOPE_DE_MEDIDA_MS, entorno: entorno() })).stdout);
194
+ }
195
+ catch (error) {
196
+ return { instalado: "fallo", detalle: motivoDe(error, TOPE_DE_MEDIDA_MS) };
197
+ }
198
+ const base = { instalado: "ok", admiteLogin: true, ...(admiteConsola ? { admiteConsola: true } : {}), ...(version === undefined ? {} : { version }) };
199
+ try {
200
+ const sesion = interpretarAuthStatusDeClaude(await salidaAunqueFalle(ejecutar(bin, ["auth", "status", "--json"], { timeout: TOPE_DE_MEDIDA_MS, entorno: limpio(entorno()) })));
201
+ if (sesion === undefined)
202
+ return { ...base, detalle: "no se pudo leer el estado de la sesión" };
203
+ let conClave = false;
204
+ if (heredaClaveDeAnthropic(entorno())) {
205
+ const heredada = interpretarAuthStatusDeClaude(await salidaAunqueFalle(ejecutar(bin, ["auth", "status", "--json"], { timeout: TOPE_DE_MEDIDA_MS, entorno: entorno() })));
206
+ conClave = heredada?.porClave === true;
207
+ }
208
+ return { ...base, conSesion: sesion.iniciada, sesion: lineaDeSesionDeClaude(sesion), ...(conClave ? { conClave: true } : {}) };
209
+ }
210
+ catch (error) {
211
+ return { ...base, detalle: `no se pudo leer la sesión: ${motivoDe(error, TOPE_DE_MEDIDA_MS)}` };
212
+ }
213
+ }
214
+ /**
215
+ * Codex y OpenCode: si están y qué versión. La sesión de Codex se lee de `codex login status`,
216
+ * que sale con 0 solo con sesión (y dice cuál en una línea). La de OpenCode NO se lee: `auth
217
+ * list` pinta una tabla para personas, y adivinar de ella sería afirmar sin medida — lo dice la
218
+ * prueba. Límite declarado: ninguno de los dos estaba instalado donde se escribió esto.
219
+ */
220
+ async function medirOtro(motor) {
221
+ const bin = motor === "codex" ? binarioDeCodex() : binarioDeOpencode();
222
+ let version;
223
+ try {
224
+ const s = await ejecutar(bin, ["--version"], { timeout: TOPE_DE_MEDIDA_MS, entorno: entorno() });
225
+ version = versionDeSalida(`${s.stdout}\n${s.stderr}`);
226
+ }
227
+ catch (error) {
228
+ const e = error;
229
+ const noEsta = e?.code === "ENOENT" ||
230
+ e?.code === 127 ||
231
+ (e?.code === 1 && typeof e.stderr === "string" && /not recognized|no se reconoce/i.test(e.stderr));
232
+ return noEsta
233
+ ? { instalado: "no-encontrado", detalle: `${motor} no está instalado o no está en el PATH` }
234
+ : { instalado: "fallo", detalle: motivoDe(error, TOPE_DE_MEDIDA_MS) };
235
+ }
236
+ const base = { instalado: "ok", ...(version === undefined ? {} : { version }) };
237
+ if (motor === "opencode")
238
+ return base;
239
+ try {
240
+ const s = await ejecutar(bin, ["login", "status"], { timeout: TOPE_DE_MEDIDA_MS, entorno: entorno() });
241
+ const linea = ultimaLinea(`${s.stdout}\n${s.stderr}`);
242
+ return { ...base, conSesion: true, ...(linea === undefined ? {} : { sesion: linea }) };
243
+ }
244
+ catch (error) {
245
+ const e = error;
246
+ if (e?.killed === true)
247
+ return { ...base, detalle: motivoDe(error, TOPE_DE_MEDIDA_MS) };
248
+ const linea = ultimaLinea(`${typeof e?.stdout === "string" ? e.stdout : ""}\n${typeof e?.stderr === "string" ? e.stderr : ""}`);
249
+ return { ...base, conSesion: false, sesion: linea ?? "Sin sesión iniciada" };
250
+ }
251
+ }
252
+ async function medirTodos() {
253
+ const medidas = await Promise.all(MOTORES_LOCALES.map(async (motor) => [motor, motor === "claude-code" ? await medirClaude() : await medirOtro(motor)]));
254
+ const medido = ahora();
255
+ for (const [motor, medidaDelMotor] of medidas) {
256
+ const antes = estados.get(motor);
257
+ // Lo que no es de la medida —las pruebas, el login en curso, «probando»— se conserva:
258
+ // volver a medir no borra la respuesta que se acaba de ver.
259
+ const conserva = {
260
+ ...(antes?.pruebas === undefined ? {} : { pruebas: antes.pruebas }),
261
+ ...(antes?.probando === undefined ? {} : { probando: antes.probando }),
262
+ ...(antes?.login === undefined ? {} : { login: antes.login }),
263
+ };
264
+ estados.set(motor, { motor, ...medidaDelMotor, ...deModelo(motor), ...conserva, medido });
265
+ }
266
+ deps.alCambiar();
267
+ }
268
+ const servicio = {
269
+ foto: () => (estados.size === 0 ? undefined : MOTORES_LOCALES.flatMap((m) => estados.get(m) ?? [])),
270
+ medir() {
271
+ // Dos «Volver a comprobar» seguidos esperan a la MISMA medida en vez de lanzar otra.
272
+ medida ??= medirTodos().finally(() => {
273
+ medida = undefined;
274
+ });
275
+ return medida;
276
+ },
277
+ async probar(motor) {
278
+ if (estados.get(motor)?.probando === true)
279
+ return;
280
+ const caminos = motor === "claude-code" && heredaClaveDeAnthropic(entorno()) ? ["sin-ejecucion", "con-ejecucion"] : ["unico"];
281
+ poner(motor, { probando: true });
282
+ const pruebas = [];
283
+ for (const camino of caminos) {
284
+ const controlador = new AbortController();
285
+ const tope = setTimeout(() => controlador.abort(), TOPE_DE_PRUEBA_MS);
286
+ const inicio = Date.now();
287
+ try {
288
+ const respuesta = await probarMotor({ motor, camino, entornoLimpio: limpio(entorno()), senal: controlador.signal });
289
+ const ok = respuestaDePruebaValida(respuesta);
290
+ pruebas.push({
291
+ camino,
292
+ ok,
293
+ detalle: ok ? `contestó «${recortar(sinUrls(respuesta), 60)}»` : `contestó otra cosa: «${recortar(sinUrls(respuesta), 100)}»`,
294
+ ms: Date.now() - inicio,
295
+ medido: ahora(),
296
+ });
297
+ }
298
+ catch (error) {
299
+ const detalle = controlador.signal.aborted
300
+ ? `no contestó en ${Math.round(TOPE_DE_PRUEBA_MS / 1000)} s`
301
+ : recortar(sinUrls(mensajeSeguro(error instanceof Error ? error.message : String(error))));
302
+ pruebas.push({ camino, ok: false, detalle, ms: Date.now() - inicio, medido: ahora() });
303
+ }
304
+ finally {
305
+ clearTimeout(tope);
306
+ }
307
+ }
308
+ poner(motor, { pruebas }, ["probando"]);
309
+ },
310
+ iniciarSesion(motor, modo) {
311
+ if (motor !== "claude-code" || logins.has(motor))
312
+ return false;
313
+ const bin = binarioDeClaude();
314
+ if (bin === undefined) {
315
+ poner(motor, { login: { fase: "fallo", detalle: "el SDK de Claude Code no trae binario para este sistema", desde: ahora() } });
316
+ return false;
317
+ }
318
+ let hijo;
319
+ try {
320
+ hijo = lanzar(bin, ["auth", "login", modo === "console" ? "--console" : "--claudeai"], { entorno: limpio(entorno()) });
321
+ }
322
+ catch (error) {
323
+ poner(motor, { login: { fase: "fallo", detalle: motivoDe(error, TOPE_DE_LOGIN_MS), desde: ahora() } });
324
+ return false;
325
+ }
326
+ const desde = ahora();
327
+ let salida = "";
328
+ const vivo = {
329
+ hijo,
330
+ cancelado: false,
331
+ tope: setTimeout(() => {
332
+ vivo.cancelado = true;
333
+ hijo.kill();
334
+ cerrar("fallo", `no se terminó en ${Math.round(TOPE_DE_LOGIN_MS / 60_000)} minutos`);
335
+ }, TOPE_DE_LOGIN_MS),
336
+ };
337
+ logins.set(motor, vivo);
338
+ poner(motor, { login: { fase: "esperando", desde } });
339
+ let cerrado = false;
340
+ const cerrar = (fase, detalle) => {
341
+ if (cerrado)
342
+ return;
343
+ cerrado = true;
344
+ clearTimeout(vivo.tope);
345
+ logins.delete(motor);
346
+ poner(motor, { login: { fase, desde, ...(detalle === undefined ? {} : { detalle }) } });
347
+ // La sesión acaba de cambiar (o no): la foto se rehace en vez de suponerla. DESPUÉS de la
348
+ // medida que esté en vuelo, no unida a ella: esa empezó antes del login y diría «sin
349
+ // sesión» al lado de «Sesión iniciada».
350
+ void (medida ?? Promise.resolve())
351
+ .catch(() => { })
352
+ .then(() => servicio.medir())
353
+ .catch(() => { });
354
+ };
355
+ const alSalir = (trozo) => {
356
+ salida += trozo.toString();
357
+ vivo.url ??= urlDeAutorizacion(salida);
358
+ const login = estados.get(motor)?.login;
359
+ if (pideCodigo(salida) && login?.fase === "esperando" && login.pideCodigo !== true) {
360
+ poner(motor, { login: { ...login, pideCodigo: true } });
361
+ }
362
+ };
363
+ hijo.stdout?.on("data", alSalir);
364
+ hijo.stderr?.on("data", alSalir);
365
+ hijo.on("error", (error) => cerrar("fallo", motivoDe(error, TOPE_DE_LOGIN_MS)));
366
+ hijo.on("exit", (codigo) => {
367
+ if (vivo.cancelado)
368
+ cerrar("cancelado");
369
+ else if (codigo === 0)
370
+ cerrar("hecho");
371
+ else
372
+ cerrar("fallo", ultimaLinea(salida) ?? `terminó con código ${String(codigo)}`);
373
+ });
374
+ return true;
375
+ },
376
+ enviarCodigo(motor, codigo) {
377
+ const vivo = logins.get(motor);
378
+ const limpioDeCodigo = codigo.trim();
379
+ // Un código de OAuth es una línea de texto imprimible y corta: otra cosa no se le escribe
380
+ // a un proceso, que leería un salto de línea de más como una segunda respuesta.
381
+ if (vivo === undefined || limpioDeCodigo === "" || limpioDeCodigo.length > 2000 || /[\u0000-\u001f\u007f]/.test(limpioDeCodigo)) {
382
+ return false;
383
+ }
384
+ vivo.hijo.stdin?.write(`${limpioDeCodigo}\n`);
385
+ return true;
386
+ },
387
+ cancelarSesion(motor) {
388
+ const vivo = logins.get(motor);
389
+ if (vivo === undefined)
390
+ return false;
391
+ vivo.cancelado = true;
392
+ vivo.hijo.kill();
393
+ return true;
394
+ },
395
+ abrirNavegador(motor) {
396
+ const url = logins.get(motor)?.url;
397
+ if (url === undefined)
398
+ return false;
399
+ abrir(url);
400
+ return true;
401
+ },
402
+ abrirConsola(motor) {
403
+ if (motor !== "claude-code" || !admiteConsola)
404
+ return false;
405
+ const bin = binarioDeClaude();
406
+ if (bin === undefined)
407
+ return false;
408
+ return abrirTerminal(bin, ["auth", "login"], limpio(entorno()));
409
+ },
410
+ elegirModelo(motor, modelo) {
411
+ if (!MOTORES_CON_MODELO.includes(motor))
412
+ return false;
413
+ const limpioDeModelo = modelo?.trim() === "" ? undefined : modelo?.trim();
414
+ if (limpioDeModelo !== undefined && motivoDeModeloDeMotorInaceptable(limpioDeModelo) !== undefined)
415
+ return false;
416
+ try {
417
+ guardarModelo(motor, limpioDeModelo);
418
+ }
419
+ catch {
420
+ return false;
421
+ }
422
+ // La prueba de antes era con OTRO modelo: se quita, para que nadie lea un «✓» que ya no vale.
423
+ poner(motor, deModelo(motor), ["pruebas", ...(limpioDeModelo === undefined ? ["modelo"] : [])]);
424
+ return true;
425
+ },
426
+ };
427
+ return servicio;
428
+ }
429
+ //# sourceMappingURL=motoresLocales.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motoresLocales.js","sourceRoot":"","sources":["../../../src/agent/motores/motoresLocales.ts"],"names":[],"mappings":"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"}
@@ -25,11 +25,11 @@
25
25
  */
26
26
  import { TOPE_DE_PREGUNTAS_CONTESTADAS_SOLAS, opcionRecomendada } from "../../../core/modoDeEscritura.js";
27
27
  import { claseDeTrabajo } from "../../../core/esfuerzo.js";
28
- import { existsSync, readdirSync, readFileSync } from "node:fs";
28
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
29
29
  import { join } from "node:path";
30
30
  import winston from "winston";
31
31
  import { AgentThread, AgentThreadOrchestrator, EventType, NOOP_AGENT_TRACING, askUserQuestion, contextCompaction, dynamicSubAgents } from "./trueforge.js";
32
- import { TOPE_DE_LLAMADAS_DEL_CONDUCTOR, TOPE_DE_LLAMADAS_DEL_ESPECIALISTA, UMBRAL_RESUMEN_TOKENS } from "../../turno/resumenDeContexto.js";
32
+ import { TOPE_DE_LLAMADAS_DEL_CONDUCTOR, TOPE_DE_LLAMADAS_DEL_ESPECIALISTA } from "../../turno/resumenDeContexto.js";
33
33
  import { crearSubagenteExterno } from "../../subagentes/subagenteExterno.js";
34
34
  import { inventarioDelProyecto, opcionesDeSubagenteExterno } from "../../subagentes/escrituraExterna.js";
35
35
  import { sumarConsumo, SIN_CONSUMO } from "../../subagentes/consumoExterno.js";
@@ -75,6 +75,10 @@ import { crearEsperas } from "./esperas.js";
75
75
  import { conResumenSeguro } from "./resumenSeguro.js";
76
76
  import { crearControlDeDetencion, RESUMEN_DE_RELLENO } from "./detencion.js";
77
77
  import { crearNavegacionXone } from "../../grafo/navegacionXone.js";
78
+ import { crearValidarFicheroXone } from "../../grafo/validarFicheroXone.js";
79
+ import { topeResuelto, umbralDeCompactacion } from "../../../core/contextos.js";
80
+ import { parsear } from "../../../core/modelos.js";
81
+ import { cargar as cargarConfig } from "../../config/configEnDisco.js";
78
82
  import { hechosDelProyectoDe } from "../../navegacion/hechosEnDisco.js";
79
83
  import { conHechosDelProyecto } from "../../../core/hechosDelProyecto.js";
80
84
  import { crearBusquedaRegex } from "../../grafo/busquedaRegex.js";
@@ -88,10 +92,13 @@ import { crearCriticaVisual } from "../../grafo/criticaVisual.js";
88
92
  import { crearCompararCapturas } from "../../grafo/compararCapturas.js";
89
93
  import { crearAtributosXone, NOMBRE_ATRIBUTOS_XONE } from "../../grafo/atributosXone.js";
90
94
  import { crearDiferenciaDeCapturas } from "../../grafo/diferenciaDeCapturas.js";
91
- import { crearLectorDeReferencias } from "../../grafo/lectorDeReferencias.js";
95
+ import { crearLectorDeReferencias, crearLocalizadorDeHtmlDeMaqueta } from "../../grafo/lectorDeReferencias.js";
96
+ import { cajasDeMaqueta, medidasDeImagen, viewportDeMaqueta } from "../../dispositivos/cajasDeMaqueta.js";
97
+ import { geometriaDeCaptura } from "../../dispositivos/geometriaEnDisco.js";
98
+ import { decodificarImagen } from "../../dispositivos/decodificarImagen.js";
92
99
  import { crearDescribirImagen } from "../../grafo/describirImagen.js";
93
100
  import { crearTraerDeLaMaquina } from "../../grafo/traerDeLaMaquina.js";
94
- import { invocarVisualConModelos } from "../../dispositivos/juezVisual.js";
101
+ import { describirPantalla, invocarVisualConModelos } from "../../dispositivos/juezVisual.js";
95
102
  import { estilosDeDisco, indiceEnDisco } from "../../navegacion/indiceEnDisco.js";
96
103
  /** El hilo raíz de TrueForge. Se llama así en la librería y no se elige. */
97
104
  const HILO_RAIZ = "main";
@@ -545,6 +552,25 @@ export async function abrirSesionTrueforge(opciones) {
545
552
  let porModelo = {};
546
553
  const modeloDeHilo = new Map();
547
554
  const idDelPapel = (papel) => modelos.idDePapel?.(papel) ?? `papel ${papel}`;
555
+ /**
556
+ * El umbral de compactación del raíz, según la ventana de SU modelo (`core/contextos.ts
557
+ * #umbralDeCompactacion`), con la MISMA resolución que la barra (`topeResuelto`: lo fijado a mano
558
+ * en el proyecto, luego en el global, luego la tabla). Sin id de modelo o sin tope conocido, el
559
+ * 32.000 de siempre. Se lee al construir el raíz: un `/modelo` lo rehace.
560
+ */
561
+ const umbralDelRaiz = () => {
562
+ const id = modelos.idDePapel?.("trabajo");
563
+ if (id === undefined)
564
+ return umbralDeCompactacion(undefined);
565
+ try {
566
+ const { proveedor, modelo } = parsear(id);
567
+ const { config } = cargarConfig(raiz);
568
+ return umbralDeCompactacion(topeResuelto(proveedor, modelo, { proyecto: config.proyecto?.contextos, global: config.global?.contextos })?.tope);
569
+ }
570
+ catch {
571
+ return umbralDeCompactacion(undefined);
572
+ }
573
+ };
548
574
  const apuntarModelo = (id, cuenta, c) => {
549
575
  porModelo = sumarPorModelo(porModelo, { [id]: { cuenta, ...c } });
550
576
  };
@@ -613,6 +639,11 @@ export async function abrirSesionTrueforge(opciones) {
613
639
  ...(carpeta === undefined ? {} : { artefactos: carpeta }),
614
640
  ...(opciones.adjuntos === undefined ? {} : { adjuntos: opciones.adjuntos }),
615
641
  });
642
+ const localizadorDeHtml = crearLocalizadorDeHtmlDeMaqueta({
643
+ raiz,
644
+ ...(carpeta === undefined ? {} : { artefactos: carpeta }),
645
+ ...(opciones.adjuntos === undefined ? {} : { adjuntos: opciones.adjuntos }),
646
+ });
616
647
  /** El crítico y la medida, con las MISMAS piezas para quien las tenga: el raíz, y con el bucle encendido el desarrollador. */
617
648
  const herramientasDeJuicio = () => carpeta === undefined
618
649
  ? []
@@ -620,8 +651,27 @@ export async function abrirSesionTrueforge(opciones) {
620
651
  crearCriticaVisual({
621
652
  leerArtefacto: async (nombre) => readFileSync(join(carpeta, nombre)),
622
653
  invocar: invocarVisualConModelos({ paraPapel: (p) => modelos.paraPapel(p) }),
654
+ // La maqueta y la captura, cada una descrita SOLA con el mismo esquema: geometría y luego estilo.
655
+ describirPantalla: (imagen, existen) => describirPantalla(imagen, invocarVisualConModelos({ paraPapel: (p) => modelos.paraPapel(p) }), existen),
656
+ // El estilo de cada control se MIDE en sus píxeles: hace falta sacarlos de la imagen.
657
+ decodificar: decodificarImagen,
658
+ // El informe se queda junto a la captura, para poder auditar qué se le dijo al agente.
659
+ guardarInforme: async (nombre, informe) => {
660
+ mkdirSync(carpetaDeHotswap(carpeta), { recursive: true });
661
+ writeFileSync(join(carpetaDeHotswap(carpeta), `${nombre.replace(/\.[A-Za-z0-9]{2,4}$/, "")}.critica.txt`), informe, "utf8");
662
+ },
623
663
  // La maqueta casi nunca está en /artefactos/: la trae la persona (/adjuntos/) o vive en /diseno/.
624
664
  leerReferencia: lectorDeReferencias,
665
+ // La GEOMETRÍA: el árbol guardado con la captura, y las cajas de la maqueta si trae `code.html`.
666
+ leerGeometria: async (nombre) => geometriaDeCaptura(carpetaDeHotswap(carpeta), nombre),
667
+ cajasDeMaqueta: async (imagen, bytes) => {
668
+ const html = localizadorDeHtml(imagen);
669
+ const medidas = medidasDeImagen(bytes);
670
+ if (html === undefined || medidas === undefined)
671
+ return undefined;
672
+ const { ancho, alto } = viewportDeMaqueta(medidas.ancho, medidas.alto);
673
+ return cajasDeMaqueta(html, ancho, alto);
674
+ },
625
675
  }),
626
676
  // Medir la estructura contra la maqueta: la otra mitad del crítico, con el raíz como él.
627
677
  crearCompararCapturas({ leerArtefacto: async (nombre) => readFileSync(join(carpeta, nombre)), leerReferencia: lectorDeReferencias }),
@@ -658,8 +708,12 @@ export async function abrirSesionTrueforge(opciones) {
658
708
  const traerDeStitch = () => opciones.conectores !== undefined && carpeta !== undefined && conStitch
659
709
  ? [crearTraerDeStitch({ conectores: opciones.conectores, carpeta, alEscribir: anotarArtefacto })]
660
710
  : [];
711
+ // ¿Está bien este .xne/.xml/.css/.js? A TODOS, el raíz incluido: es quien recibe el error que pega la persona, y
712
+ // sin ella lo comprobaba leyendo el fichero a ojo (soporte de APPSalud). Pura y de lectura.
713
+ const validarFichero = () => crearValidarFicheroXone(backend);
661
714
  const propiasDelRaiz = [
662
715
  navegacion(),
716
+ validarFichero(),
663
717
  atributos,
664
718
  describirImagen(),
665
719
  ...herramientasDeJuicio(),
@@ -669,6 +723,7 @@ export async function abrirSesionTrueforge(opciones) {
669
723
  const propiasDe = (agente) => [
670
724
  crearBusquedaRegex(backend),
671
725
  navegacion(),
726
+ validarFichero(),
672
727
  atributos,
673
728
  describirImagen(),
674
729
  ...(carpeta !== undefined && (agente.escribeEn ?? []).length > 0
@@ -731,6 +786,18 @@ export async function abrirSesionTrueforge(opciones) {
731
786
  };
732
787
  const razonamientoDeSalida = (salida) => razonamientoPendiente.get(salida)?.shift();
733
788
  const llm = modeloParaTrueforge({ modelo: () => clienteDe("papel:trabajo:", () => modelos.paraPapel("trabajo")), senal: () => aborto?.signal, alRazonar });
789
+ /**
790
+ * El modelo de la COMPACTACIÓN: el mismo del raíz, con el pensamiento APAGADO donde el modelo lo
791
+ * admite (`core/esfuerzo.ts#pensamientoAplicable`: hoy DeepSeek; en los demás no se manda nada que
792
+ * no esté medido, así que se quedan como el raíz). Resumir no necesita razonar, y medido en dos
793
+ * sesiones de soporte la compactación sí razonaba: hasta 13.650 tokens de razonamiento para un
794
+ * resumen de ~4.000, 72 s de los 164 del turno, y en otro, 13 compactaciones en 30 min.
795
+ */
796
+ const llmDeCompactacion = modeloParaTrueforge({
797
+ modelo: () => clienteDe("papel:trabajo:compactacion", () => modelos.paraPapel("trabajo", undefined, undefined, "apagado")),
798
+ senal: () => aborto?.signal,
799
+ alRazonar,
800
+ });
734
801
  /**
735
802
  * El hilo de un hijo EXTERNO: un `AgentThread` normal con UNA llamada, cuyo «modelo» es el
736
803
  * producto (`modeloExterno.ts`). Sin tools, sin capabilities y sin compactación: el bucle vive
@@ -1006,15 +1073,16 @@ export async function abrirSesionTrueforge(opciones) {
1006
1073
  capacidadDeInformes,
1007
1074
  ]),
1008
1075
  /**
1009
- * **La conversación se RESUME al mismo umbral que deepagents** (`UMBRAL_RESUMEN_TOKENS`):
1010
- * sin esto no se compactaba nunca y cada turno reenviaba la sesión entera. La
1011
- * compactación de TrueForge sustituye el contexto ENTERO por el resumen, y por eso las
1012
- * instrucciones van en el prompt de sistema —aquí `instruction`, en un hijo su
1013
- * capability—, que no se compacta.
1076
+ * **La conversación se RESUME a un umbral que depende de la ventana del modelo**
1077
+ * (`umbralDelRaiz`): sin compactar, cada turno reenviaba la sesión entera; con el 32.000
1078
+ * fijo de deepagents, DeepSeek compactaba cada dos o tres lecturas. La compactación de
1079
+ * TrueForge sustituye el contexto ENTERO por el resumen, y por eso las instrucciones van
1080
+ * en el prompt de sistema —aquí `instruction`, en un hijo su capability—, que no se
1081
+ * compacta. Y resume con el pensamiento APAGADO (`llmDeCompactacion`).
1014
1082
  */
1015
1083
  contextCompaction({
1016
- definition: { ...definicion, modelClient: conResumenSeguro(definicion.modelClient, (t) => anotarPaso("trueforge.compactacion", t)()) },
1017
- compactionThresholdTokens: UMBRAL_RESUMEN_TOKENS,
1084
+ definition: { ...definicion, modelClient: conResumenSeguro(llmDeCompactacion, (t) => anotarPaso("trueforge.compactacion", t)()) },
1085
+ compactionThresholdTokens: umbralDelRaiz(),
1018
1086
  }),
1019
1087
  // `ask_user_question`, SOLO en el raíz —la librería tampoco se la da a un hijo—: es el
1020
1088
  // único que tiene a una persona delante.