xonecode 0.31.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.
- package/apps/web/dist/assets/{EditorDeFichero-ChyJtiiz.js → EditorDeFichero-H_kGeZt2.js} +1 -1
- package/apps/web/dist/assets/{index-IptObD2z.css → index-CWBaotdZ.css} +1 -1
- package/apps/web/dist/assets/index-DnGuOvbb.js +499 -0
- package/apps/web/dist/assets/{php-B91ZcS-9.js → php-CMFQiZgk.js} +1 -1
- package/apps/web/dist/assets/{ruby-DrxrTSz0.js → ruby-Dj3BOBHc.js} +1 -1
- package/apps/web/dist/index.html +2 -2
- package/dist/agent/config/modelosDeMotor.js +4 -2
- package/dist/agent/config/modelosDeMotor.js.map +1 -1
- package/dist/agent/config/settingsEnDisco.js +26 -0
- package/dist/agent/config/settingsEnDisco.js.map +1 -1
- package/dist/agent/dispositivos/cajasDeMaqueta.js +130 -0
- package/dist/agent/dispositivos/cajasDeMaqueta.js.map +1 -0
- package/dist/agent/dispositivos/geometriaEnDisco.js +25 -0
- package/dist/agent/dispositivos/geometriaEnDisco.js.map +1 -0
- package/dist/agent/dispositivos/juezVisual.js +84 -3
- package/dist/agent/dispositivos/juezVisual.js.map +1 -1
- package/dist/agent/grafo/criticaVisual.js +240 -11
- package/dist/agent/grafo/criticaVisual.js.map +1 -1
- package/dist/agent/grafo/lectorDeReferencias.js +21 -0
- package/dist/agent/grafo/lectorDeReferencias.js.map +1 -1
- package/dist/agent/motores/motoresLocales.js +429 -0
- package/dist/agent/motores/motoresLocales.js.map +1 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.js +30 -3
- package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
- package/dist/agent/motores/trueforge/toolsDeFichero.js +24 -6
- package/dist/agent/motores/trueforge/toolsDeFichero.js.map +1 -1
- package/dist/agent/sesiones/adjuntosDeSesion.js +125 -5
- package/dist/agent/sesiones/adjuntosDeSesion.js.map +1 -1
- package/dist/agent/subagentes/ejecutableEnWindows.js +139 -0
- package/dist/agent/subagentes/ejecutableEnWindows.js.map +1 -0
- package/dist/agent/subagentes/subagenteCodex.js +7 -2
- package/dist/agent/subagentes/subagenteCodex.js.map +1 -1
- package/dist/agent/subagentes/subagenteOpencode.js +12 -5
- package/dist/agent/subagentes/subagenteOpencode.js.map +1 -1
- package/dist/core/adjuntos.js +10 -2
- package/dist/core/adjuntos.js.map +1 -1
- package/dist/core/descripcionDePantalla.js +354 -0
- package/dist/core/descripcionDePantalla.js.map +1 -0
- package/dist/core/estiloMedido.js +332 -0
- package/dist/core/estiloMedido.js.map +1 -0
- package/dist/core/geometriaDePantalla.js +437 -0
- package/dist/core/geometriaDePantalla.js.map +1 -0
- package/dist/core/motoresLocales.js +128 -0
- package/dist/core/motoresLocales.js.map +1 -0
- package/dist/core/nucleoXone.js +6 -6
- package/dist/core/nucleoXone.js.map +1 -1
- package/dist/core/settings.js +5 -0
- package/dist/core/settings.js.map +1 -1
- package/dist/core/shellDeAgente.js +13 -0
- package/dist/core/shellDeAgente.js.map +1 -1
- package/dist/core/zipDeAdjunto.js +79 -0
- package/dist/core/zipDeAdjunto.js.map +1 -0
- package/dist/web/servidor/arranque.js +84 -0
- package/dist/web/servidor/arranque.js.map +1 -1
- package/dist/web/servidor/transporte.js.map +1 -1
- package/package.json +1 -1
- package/skills/xone-development/SKILL.md +2 -1
- package/skills/xone-development/references/css/buenas-practicas-y-parser.md +2 -1
- package/skills/xone-development/references/css/de-una-maqueta-a-xone.md +81 -0
- package/skills/xone-development/references/css/patrones-material-y-temas.md +15 -13
- package/skills/xone-development/references/css/propiedades-y-herencia.md +2 -2
- package/skills/xone-development/references/css/selectores-unidades-colores.md +8 -3
- package/skills/xone-development/references/indice-completo.md +1 -0
- package/skills/xone-hotswap/lib/geometria.mjs +147 -0
- package/skills/xone-hotswap/scripts/xone-captura-android +6 -0
- package/skills/xone-hotswap/scripts/xone-hotswap +8 -0
- package/skills/xone-hotswap/scripts/xone-recargar-android +15 -0
- 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,7 +25,7 @@
|
|
|
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";
|
|
@@ -92,10 +92,13 @@ import { crearCriticaVisual } from "../../grafo/criticaVisual.js";
|
|
|
92
92
|
import { crearCompararCapturas } from "../../grafo/compararCapturas.js";
|
|
93
93
|
import { crearAtributosXone, NOMBRE_ATRIBUTOS_XONE } from "../../grafo/atributosXone.js";
|
|
94
94
|
import { crearDiferenciaDeCapturas } from "../../grafo/diferenciaDeCapturas.js";
|
|
95
|
-
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";
|
|
96
99
|
import { crearDescribirImagen } from "../../grafo/describirImagen.js";
|
|
97
100
|
import { crearTraerDeLaMaquina } from "../../grafo/traerDeLaMaquina.js";
|
|
98
|
-
import { invocarVisualConModelos } from "../../dispositivos/juezVisual.js";
|
|
101
|
+
import { describirPantalla, invocarVisualConModelos } from "../../dispositivos/juezVisual.js";
|
|
99
102
|
import { estilosDeDisco, indiceEnDisco } from "../../navegacion/indiceEnDisco.js";
|
|
100
103
|
/** El hilo raíz de TrueForge. Se llama así en la librería y no se elige. */
|
|
101
104
|
const HILO_RAIZ = "main";
|
|
@@ -636,6 +639,11 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
636
639
|
...(carpeta === undefined ? {} : { artefactos: carpeta }),
|
|
637
640
|
...(opciones.adjuntos === undefined ? {} : { adjuntos: opciones.adjuntos }),
|
|
638
641
|
});
|
|
642
|
+
const localizadorDeHtml = crearLocalizadorDeHtmlDeMaqueta({
|
|
643
|
+
raiz,
|
|
644
|
+
...(carpeta === undefined ? {} : { artefactos: carpeta }),
|
|
645
|
+
...(opciones.adjuntos === undefined ? {} : { adjuntos: opciones.adjuntos }),
|
|
646
|
+
});
|
|
639
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. */
|
|
640
648
|
const herramientasDeJuicio = () => carpeta === undefined
|
|
641
649
|
? []
|
|
@@ -643,8 +651,27 @@ export async function abrirSesionTrueforge(opciones) {
|
|
|
643
651
|
crearCriticaVisual({
|
|
644
652
|
leerArtefacto: async (nombre) => readFileSync(join(carpeta, nombre)),
|
|
645
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
|
+
},
|
|
646
663
|
// La maqueta casi nunca está en /artefactos/: la trae la persona (/adjuntos/) o vive en /diseno/.
|
|
647
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
|
+
},
|
|
648
675
|
}),
|
|
649
676
|
// Medir la estructura contra la maqueta: la otra mitad del crítico, con el raíz como él.
|
|
650
677
|
crearCompararCapturas({ leerArtefacto: async (nombre) => readFileSync(join(carpeta, nombre)), leerReferencia: lectorDeReferencias }),
|