xonecode 0.31.0 → 0.34.2
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-Cj0knNmP.js} +1 -1
- package/apps/web/dist/assets/index-Ga8fTlWp.js +499 -0
- package/apps/web/dist/assets/{index-IptObD2z.css → index-R3kXj69E.css} +1 -1
- package/apps/web/dist/assets/{php-B91ZcS-9.js → php-MVUx_K96.js} +1 -1
- package/apps/web/dist/assets/{ruby-DrxrTSz0.js → ruby-n-r-AXdi.js} +1 -1
- package/apps/web/dist/index.html +2 -2
- package/dist/agent/config/fuentesEnRed.js +80 -0
- package/dist/agent/config/fuentesEnRed.js.map +1 -0
- 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 +218 -0
- package/dist/agent/dispositivos/cajasDeMaqueta.js.map +1 -0
- package/dist/agent/dispositivos/geometriaEnDisco.js +107 -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 +246 -11
- package/dist/agent/grafo/criticaVisual.js.map +1 -1
- package/dist/agent/grafo/fuentesDeGoogle.js +133 -0
- package/dist/agent/grafo/fuentesDeGoogle.js.map +1 -0
- package/dist/agent/grafo/incorporarAdjunto.js +52 -42
- package/dist/agent/grafo/incorporarAdjunto.js.map +1 -1
- package/dist/agent/grafo/lectorDeReferencias.js +21 -0
- package/dist/agent/grafo/lectorDeReferencias.js.map +1 -1
- package/dist/agent/grafo/perfiles.js +2 -0
- package/dist/agent/grafo/perfiles.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/capacidades.js +9 -6
- package/dist/agent/motores/trueforge/capacidades.js.map +1 -1
- package/dist/agent/motores/trueforge/informesDeHijos.js +39 -7
- package/dist/agent/motores/trueforge/informesDeHijos.js.map +1 -1
- package/dist/agent/motores/trueforge/memoriaDeEspecialistas.js +75 -37
- package/dist/agent/motores/trueforge/memoriaDeEspecialistas.js.map +1 -1
- package/dist/agent/motores/trueforge/memoriaTrueforge.js +24 -4
- package/dist/agent/motores/trueforge/memoriaTrueforge.js.map +1 -1
- package/dist/agent/motores/trueforge/modeloLangchain.js +28 -4
- package/dist/agent/motores/trueforge/modeloLangchain.js.map +1 -1
- package/dist/agent/motores/trueforge/proponerTareas.js +67 -0
- package/dist/agent/motores/trueforge/proponerTareas.js.map +1 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.js +133 -13
- 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 +192 -5
- package/dist/agent/sesiones/adjuntosDeSesion.js.map +1 -1
- package/dist/agent/subagentes/agentesEnDisco.js +12 -4
- package/dist/agent/subagentes/agentesEnDisco.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/agent/tareas/aumentador.js +4 -3
- package/dist/agent/tareas/aumentador.js.map +1 -1
- package/dist/agent/turno/informeDeTraza.js +2 -1
- package/dist/agent/turno/informeDeTraza.js.map +1 -1
- package/dist/agent/turno/interrupts.js +12 -0
- package/dist/agent/turno/interrupts.js.map +1 -1
- package/dist/agent/turno/resumenDeTool.js +4 -0
- package/dist/agent/turno/resumenDeTool.js.map +1 -1
- package/dist/agent/turno/turnoReal.js +3 -0
- package/dist/agent/turno/turnoReal.js.map +1 -1
- package/dist/cli/consola.js.map +1 -1
- package/dist/cli/main.js +2 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/tui/transcript.js +5 -0
- package/dist/cli/tui/transcript.js.map +1 -1
- package/dist/core/actos.js.map +1 -1
- package/dist/core/adjuntos.js +10 -2
- package/dist/core/adjuntos.js.map +1 -1
- package/dist/core/agentes.js +10 -0
- package/dist/core/agentes.js.map +1 -1
- package/dist/core/analisisDeSesion.js +1 -1
- package/dist/core/analisisDeSesion.js.map +1 -1
- package/dist/core/descripcionDePantalla.js +367 -0
- package/dist/core/descripcionDePantalla.js.map +1 -0
- package/dist/core/estiloMedido.js +352 -0
- package/dist/core/estiloMedido.js.map +1 -0
- package/dist/core/fuentes.js +174 -0
- package/dist/core/fuentes.js.map +1 -0
- package/dist/core/geometriaDePantalla.js +537 -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/notify.js +4 -0
- package/dist/core/notify.js.map +1 -1
- package/dist/core/nucleoXone.js +6 -6
- package/dist/core/nucleoXone.js.map +1 -1
- package/dist/core/ports.js +35 -0
- package/dist/core/ports.js.map +1 -1
- package/dist/core/repartoDeEncargo.js +87 -0
- package/dist/core/repartoDeEncargo.js.map +1 -0
- package/dist/core/settings.js +5 -0
- package/dist/core/settings.js.map +1 -1
- package/dist/core/shellDeAgente.js +36 -0
- package/dist/core/shellDeAgente.js.map +1 -1
- package/dist/core/tareas.js +7 -0
- package/dist/core/tareas.js.map +1 -1
- package/dist/core/turno.js +15 -0
- package/dist/core/turno.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 +201 -13
- package/dist/web/servidor/arranque.js.map +1 -1
- package/dist/web/servidor/consolaWeb.js +5 -0
- package/dist/web/servidor/consolaWeb.js.map +1 -1
- package/dist/web/servidor/interrupcion.js +52 -0
- package/dist/web/servidor/interrupcion.js.map +1 -0
- package/dist/web/servidor/pielWeb.js +36 -0
- package/dist/web/servidor/pielWeb.js.map +1 -1
- package/dist/web/servidor/transporte.js +1 -0
- package/dist/web/servidor/transporte.js.map +1 -1
- package/dist/web/servidor/vestibulo.js +30 -2
- package/dist/web/servidor/vestibulo.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 +83 -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-development/references/xml-ui/atributos-coll-group-frame.md +4 -4
- package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +4 -4
- 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
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El crítico VISUAL de una pantalla: mira una captura del aparato y dice qué se ve mal.
|
|
3
|
+
*
|
|
4
|
+
* Existe porque hay una clase de fallo que ninguna de las otras tres fuentes ve. Medido sobre
|
|
5
|
+
* la Calculadora de AppDemo: `xone-simulator validate` en verde, `smoke --interact` con
|
|
6
|
+
* `renderOk: true` y `jsErrors: 0`, el log del aparato sin un solo error… y la captura
|
|
7
|
+
* enseñaba **todas las etiquetas cortadas por la mitad**. La aritmética era correcta —`75 + 3`
|
|
8
|
+
* daba `78`— y la pantalla era ilegible. Eso no lo dice nadie más que una imagen.
|
|
9
|
+
*
|
|
10
|
+
* TRES REGLAS, y las tres salieron de medirlo tres veces contra el modelo real:
|
|
11
|
+
*
|
|
12
|
+
* - **Lo que devuelve son OBSERVACIONES, no hallazgos, y la diferencia está MEDIDA.** Las tres
|
|
13
|
+
* primeras vueltas describieron el texto como «rotado 180°, boca abajo». No está rotado:
|
|
14
|
+
* está CORTADO por la mitad. Es un error sistemático, no ruido.
|
|
15
|
+
*
|
|
16
|
+
* **Y pedirle en el prompt que no diagnostique NO lo arregla**: se probó —«describe lo que
|
|
17
|
+
* se ve, no la causa»— y las tres vueltas siguientes volvieron a decir «girado 180°». El
|
|
18
|
+
* modelo no está razonando de más: está PERCIBIENDO eso. La instrucción se queda porque no
|
|
19
|
+
* estorba y acota el resto, pero el remedio no puede estar ahí: quien enseñe estas
|
|
20
|
+
* observaciones tiene que decir que la REDACCIÓN no es fiable, aunque el sitio al que
|
|
21
|
+
* apuntan sí lo sea. En las seis vueltas acertó siempre QUÉ control estaba mal.
|
|
22
|
+
* - **NO es una huella, y por eso no puede frenar el bucle.** La MISMA captura, seis vueltas:
|
|
23
|
+
* 4, 2, 4, 5, 3 y 5 observaciones, con redacción distinta cada vez. La
|
|
24
|
+
* guarda de «no progreso» de `turnoReal.ts#conVerificacion` se queda en los sensores
|
|
25
|
+
* deterministas; esto opina, como `juezDeTarea`.
|
|
26
|
+
* - **Fail-closed: lo que no se entiende NO es verde**, igual que el juez de tareas y que la
|
|
27
|
+
* aprobación humana. Y un ROJO sin nada que enseñar tampoco vale: nadie sabría qué mirar.
|
|
28
|
+
*
|
|
29
|
+
* Y que no se pueda preguntar es fallo del ENTORNO, no un veredicto: se LANZA. Un fallo de red
|
|
30
|
+
* convertido en rojo culparía al trabajo del agente de un problema de la máquina.
|
|
31
|
+
*/
|
|
32
|
+
import { createHash } from "node:crypto";
|
|
33
|
+
import { interpretarDescripcion, promptDescribirPantalla } from "../../core/descripcionDePantalla.js";
|
|
1
34
|
import { objetoDe } from "../tareas/juezDeTarea.js";
|
|
2
35
|
/** El papel del juez, el mismo que el de tareas. `core/modelos.ts` lo reserva para esto. */
|
|
3
36
|
export const PAPEL_DEL_JUEZ_VISUAL = "afilado";
|
|
@@ -9,7 +42,11 @@ export const PAPEL_DEL_JUEZ_VISUAL = "afilado";
|
|
|
9
42
|
* ver la cabecera— sino para que quepa.
|
|
10
43
|
*/
|
|
11
44
|
export const TOPE_DE_OBSERVACIONES = 8;
|
|
12
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Cuánto ocupa cada una. Era 200, y medido sobre la calculadora de MyAllXOne cortaba la primera
|
|
47
|
+
* observación a media frase («…en su lugar aparece una flech…»): quien la leía no sabía qué faltaba.
|
|
48
|
+
*/
|
|
49
|
+
const TOPE_DE_OBSERVACION = 500;
|
|
13
50
|
/**
|
|
14
51
|
* Cuántas pantallas puede pedir de una vez.
|
|
15
52
|
*
|
|
@@ -127,9 +164,26 @@ export async function juzgarPantalla(imagen, contexto, invocar,
|
|
|
127
164
|
* `cli/` no cambian: lo que hace un `xonecode` de diagnóstico es mirar una pantalla, no
|
|
128
165
|
* compararla contra nada.
|
|
129
166
|
*/
|
|
130
|
-
referencia
|
|
167
|
+
referencia,
|
|
168
|
+
/**
|
|
169
|
+
* HECHOS MEDIDOS de la geometría (`core/geometriaDePantalla.ts`): qué está tapado, qué falta, filas y
|
|
170
|
+
* tamaños, sacados del árbol de controles y no de mirar. Van en el prompt para que el modelo no tenga
|
|
171
|
+
* que adivinar la estructura —medido: no vio una «=» tapada y se inventó colores— y para que su
|
|
172
|
+
* texto no los contradiga. Él se queda con lo que solo se ve: formas, colores, jerarquía.
|
|
173
|
+
*/
|
|
174
|
+
hechos = []) {
|
|
131
175
|
const base = referencia === undefined ? PROMPT_VISUAL : PROMPT_VISUAL_CON_REFERENCIA;
|
|
132
|
-
const
|
|
176
|
+
const conHechos = hechos.length === 0
|
|
177
|
+
? ""
|
|
178
|
+
: [
|
|
179
|
+
"",
|
|
180
|
+
"",
|
|
181
|
+
"HECHOS YA MEDIDOS del árbol de controles del aparato (exactos: NO los contradigas ni los",
|
|
182
|
+
"repitas, ya se le dicen a quien te lee). Céntrate en lo que solo se VE: formas, colores,",
|
|
183
|
+
"tamaño del texto, jerarquía, iconos.",
|
|
184
|
+
...hechos.map((h) => `- ${h}`),
|
|
185
|
+
].join("\n");
|
|
186
|
+
const prompt = `${base}${conHechos}\n\nLa captura es de la pantalla «${contexto.pantalla}».`;
|
|
133
187
|
let texto;
|
|
134
188
|
try {
|
|
135
189
|
texto = await invocar(PAPEL_DEL_JUEZ_VISUAL, prompt, imagen, referencia);
|
|
@@ -168,6 +222,33 @@ referencia) {
|
|
|
168
222
|
return { veredicto: "rojo", observaciones, necesito };
|
|
169
223
|
return { veredicto: "indeterminado", observaciones, necesito };
|
|
170
224
|
}
|
|
225
|
+
/** Las pantallas ya descritas, por la huella de la imagen y de la estructura dada: una maqueta no cambia entre rondas. */
|
|
226
|
+
const descritas = new Map();
|
|
227
|
+
/**
|
|
228
|
+
* Una pantalla DESCRITA (`core/descripcionDePantalla.ts`): el modelo mira UNA imagen sola y cuenta primero su
|
|
229
|
+
* geometría y después el estilo de cada control, con el mismo esquema para la maqueta y para la captura. A la
|
|
230
|
+
* captura se le pasan los controles que EXISTEN (`controlesQueExisten`, del árbol), para que no invente estructura.
|
|
231
|
+
*
|
|
232
|
+
* Se guarda por huella: cada ronda compara contra la MISMA descripción de la maqueta, no contra una nueva que varía.
|
|
233
|
+
* Lo que no se entiende es `undefined` (y no se guarda); no poder preguntar LANZA, como `juzgarPantalla`.
|
|
234
|
+
*/
|
|
235
|
+
export async function describirPantalla(imagen, invocar, controlesQueExisten) {
|
|
236
|
+
const huella = createHash("sha256").update(imagen.base64).update(JSON.stringify(controlesQueExisten ?? [])).digest("hex");
|
|
237
|
+
const guardada = descritas.get(huella);
|
|
238
|
+
if (guardada !== undefined)
|
|
239
|
+
return guardada;
|
|
240
|
+
let texto;
|
|
241
|
+
try {
|
|
242
|
+
texto = await invocar(PAPEL_DEL_JUEZ_VISUAL, promptDescribirPantalla(controlesQueExisten), imagen);
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
throw new ErrorDelJuezVisual(error instanceof Error ? error.message : String(error));
|
|
246
|
+
}
|
|
247
|
+
const descrita = interpretarDescripcion(objetoDe(texto));
|
|
248
|
+
if (descrita !== undefined)
|
|
249
|
+
descritas.set(huella, descrita);
|
|
250
|
+
return descrita;
|
|
251
|
+
}
|
|
171
252
|
/**
|
|
172
253
|
* El `invocar` de PRODUCCIÓN, sobre `ModelosPort`.
|
|
173
254
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"juezVisual.js","sourceRoot":"","sources":["../../../src/agent/dispositivos/juezVisual.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"juezVisual.js","sourceRoot":"","sources":["../../../src/agent/dispositivos/juezVisual.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,9 @@ import { tool } from "@langchain/core/tools";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { esRutaDeArtefacto, mimeDeArtefacto, nombreDeArtefacto, rutaRelativaDeArtefacto, } from "../../core/artefactos.js";
|
|
4
4
|
import { imagenReferida } from "../../core/referenciasDeImagen.js";
|
|
5
|
+
import { cajaParaElEstilo, compararConMaqueta, controlesDelArbol, filas as filasDeCajas, filasDelAparato, hallazgosDeGeometria, informeDeGeometria, } from "../../core/geometriaDePantalla.js";
|
|
6
|
+
import { compararDescripciones, hayQueArreglar, informeDeComparacion, maquetaDeLaDescripcion, } from "../../core/descripcionDePantalla.js";
|
|
7
|
+
import { compararBloques, pantallaMedida } from "../../core/estiloMedido.js";
|
|
5
8
|
import { juzgarPantalla, TOPE_DE_PETICIONES, } from "../dispositivos/juezVisual.js";
|
|
6
9
|
/**
|
|
7
10
|
* `xone_critica_visual`: enseñarle una captura al crítico y traer su veredicto.
|
|
@@ -52,6 +55,110 @@ const Entrada = z.object({
|
|
|
52
55
|
"la maqueta (forma, tamaños, colocación). SIN ella solo busco roturas y NO digo nada " +
|
|
53
56
|
"sobre si se parece al diseño."),
|
|
54
57
|
});
|
|
58
|
+
/**
|
|
59
|
+
* La geometría de esta captura (`core/geometriaDePantalla.ts`), o `undefined` si este montaje no la tiene.
|
|
60
|
+
* Nunca lanza: lo que no se puede medir se dice en el bloque, y el crítico sigue con su opinión.
|
|
61
|
+
*/
|
|
62
|
+
async function geometriaDe(entrada, referida, referencia, deps,
|
|
63
|
+
/**
|
|
64
|
+
* Describir la maqueta con un modelo, SOLO si hace falta: cuando no trae `code.html` medible es su única
|
|
65
|
+
* estructura. Con `code.html` ya no se pide (ver `estructuraDescrita`).
|
|
66
|
+
*/
|
|
67
|
+
describir) {
|
|
68
|
+
if (deps.leerGeometria === undefined)
|
|
69
|
+
return undefined;
|
|
70
|
+
let crudo;
|
|
71
|
+
try {
|
|
72
|
+
crudo = await deps.leerGeometria(nombreDeArtefacto(entrada.captura));
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
crudo = undefined;
|
|
76
|
+
}
|
|
77
|
+
const g = crudo;
|
|
78
|
+
if (g === undefined || g.arbol === undefined || g.pantalla === undefined) {
|
|
79
|
+
return {
|
|
80
|
+
lineas: [
|
|
81
|
+
"GEOMETRÍA: esta captura no trae su árbol de controles, así que no hay nada MEDIDO (qué está tapado, qué",
|
|
82
|
+
"falta, filas, tamaños). Sácala con `xone-captura-android` o `xone-hotswap shot`, que lo guardan a la vez.",
|
|
83
|
+
],
|
|
84
|
+
hechos: [],
|
|
85
|
+
bloqueante: false,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const controles = controlesDelArbol(g.arbol);
|
|
89
|
+
// Una captura de UN CONTROL (`shot name=…`) es más pequeña que lo que ocupa el árbol: sus cajas son de la pantalla
|
|
90
|
+
// entera y medirían píxeles que no son. El script ya no la guarda así; esto cubre las de antes.
|
|
91
|
+
// La pantalla la dice la barra de navegación; sin ella, lo que ocupa el árbol (que puede pasarse: un pie flotante).
|
|
92
|
+
const navegacion = g.barras?.navegacion;
|
|
93
|
+
const extension = navegacion !== undefined
|
|
94
|
+
? { ancho: navegacion.derecha, alto: navegacion.abajo }
|
|
95
|
+
: controles.reduce((e, c) => ({ ancho: Math.max(e.ancho, c.caja.x + c.caja.ancho), alto: Math.max(e.alto, c.caja.y + c.caja.alto) }), { ancho: 0, alto: 0 });
|
|
96
|
+
if (g.pantalla.alto < extension.alto * 0.95 || g.pantalla.ancho < extension.ancho * 0.95) {
|
|
97
|
+
return {
|
|
98
|
+
lineas: [
|
|
99
|
+
"GEOMETRÍA: esta captura es de una PARTE de la pantalla (un control), no de la pantalla entera, así que no hay nada",
|
|
100
|
+
"MEDIDO. Para comparar con la maqueta, captura la pantalla entera (`xone-hotswap shot` sin `name=`).",
|
|
101
|
+
],
|
|
102
|
+
hechos: [],
|
|
103
|
+
bloqueante: false,
|
|
104
|
+
parcial: true,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const aparato = {
|
|
108
|
+
pantalla: g.pantalla,
|
|
109
|
+
...(g.barras === undefined ? {} : { barras: g.barras }),
|
|
110
|
+
controles,
|
|
111
|
+
};
|
|
112
|
+
let maqueta;
|
|
113
|
+
let sinCajas;
|
|
114
|
+
if (referida !== undefined && referencia !== undefined && deps.cajasDeMaqueta !== undefined) {
|
|
115
|
+
let medida;
|
|
116
|
+
try {
|
|
117
|
+
medida = await deps.cajasDeMaqueta(referida, Buffer.from(referencia.base64, "base64"));
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
medida = { motivo: "no se pudo medir" };
|
|
121
|
+
}
|
|
122
|
+
if (medida === undefined)
|
|
123
|
+
sinCajas = "la maqueta es solo una imagen (sin code.html al lado): aquí, solo lo que se ve en el propio aparato";
|
|
124
|
+
else if ("motivo" in medida)
|
|
125
|
+
sinCajas = `no pude medir las cajas de la maqueta: ${medida.motivo}. Aquí, solo lo del propio aparato`;
|
|
126
|
+
else
|
|
127
|
+
maqueta = medida;
|
|
128
|
+
}
|
|
129
|
+
// Sin cajas medidas, la descripción es la única estructura de la maqueta; con ellas no se pide (`estructuraDescrita`).
|
|
130
|
+
const descrita = maqueta === undefined ? await describir() : undefined;
|
|
131
|
+
const notas = sinCajas === undefined ? [] : [`${sinCajas}${descrita === undefined ? "" : " (la estructura de la maqueta va abajo, según su descripción)"}.`];
|
|
132
|
+
const h = hallazgosDeGeometria(aparato, maqueta);
|
|
133
|
+
const lineas = informeDeGeometria({ ...h, notas: [...h.notas, ...notas] }, maqueta !== undefined);
|
|
134
|
+
if (descrita !== undefined)
|
|
135
|
+
lineas.push(...estructuraDescrita(descrita, aparato));
|
|
136
|
+
return {
|
|
137
|
+
lineas,
|
|
138
|
+
hechos: [...h.bloqueantes, ...h.diferencias],
|
|
139
|
+
bloqueante: h.bloqueantes.length > 0,
|
|
140
|
+
aparato,
|
|
141
|
+
...(maqueta === undefined ? {} : { maqueta }),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Lo que aporta la maqueta DESCRITA, en un bloque APARTE del medido: nunca decide el rojo. Solo existe **sin
|
|
146
|
+
* `code.html`**: es la única estructura de la maqueta que hay, sus filas, orden y anchos contra el árbol medido. Así
|
|
147
|
+
* una maqueta que es solo un PNG también dice «la = va en otra fila».
|
|
148
|
+
*
|
|
149
|
+
* **Con `code.html` la maqueta ya no se describe.** Antes la descripción vigilaba que la imagen y el HTML contaran lo
|
|
150
|
+
* mismo, en un bloque que no decidía nada y costaba una llamada a un modelo por crítica; y como lo decía un modelo,
|
|
151
|
+
* se equivocaba: en la calculadora daba «DEC de la imagen no está en su code.html», y sí estaba.
|
|
152
|
+
*/
|
|
153
|
+
function estructuraDescrita(descrita, aparato) {
|
|
154
|
+
const h = compararConMaqueta(maquetaDeLaDescripcion(descrita), aparato, { aproximada: true });
|
|
155
|
+
return [
|
|
156
|
+
"",
|
|
157
|
+
"ESTRUCTURA CONTRA LA MAQUETA DESCRITA (las filas, el orden y los anchos de la maqueta los dijo un modelo mirándola sola; los del aparato están medidos. Orientativo: compruébalo antes de cambiar nada):",
|
|
158
|
+
...(h.diferencias.length === 0 ? ["- Nada: las filas y el orden cuadran con lo descrito."] : h.diferencias.map((d) => `- ${d}`)),
|
|
159
|
+
...h.notas.map((n) => `- (nota) ${n}`),
|
|
160
|
+
];
|
|
161
|
+
}
|
|
55
162
|
/**
|
|
56
163
|
* Qué es esta ruta, o el motivo en palabras. **Comprueba y NO lee.**
|
|
57
164
|
*
|
|
@@ -127,6 +234,62 @@ function sinJuzgar(motivo) {
|
|
|
127
234
|
"llamarme.",
|
|
128
235
|
].join("\n");
|
|
129
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* La comparación de estilo MEDIDA, o `undefined` si no hay con qué (sin decodificador, sin árbol, o la imagen no se
|
|
239
|
+
* pudo leer). `completa`: hubo maqueta con cajas y la comparación es control a control; si no, solo los recortes de
|
|
240
|
+
* la captura. Nunca lanza.
|
|
241
|
+
*/
|
|
242
|
+
function medirEstilo(captura, referencia, geometria, deps) {
|
|
243
|
+
if (deps.decodificar === undefined || geometria?.aparato === undefined)
|
|
244
|
+
return undefined;
|
|
245
|
+
try {
|
|
246
|
+
// El estilo de un texto se mide en la caja de su ENVOLTORIO si lo tiene (`cajaParaElEstilo`): el frame que hace de
|
|
247
|
+
// botón o de píldora, que es donde están el borde y el fondo.
|
|
248
|
+
const comoMedir = (fila) => fila.map((c) => {
|
|
249
|
+
const envoltorio = cajaParaElEstilo(c, geometria.aparato);
|
|
250
|
+
return { texto: c.texto ?? `[${c.nombre ?? "sin nombre"}]`, caja: c.caja, ...(envoltorio === c.caja ? {} : { envoltorio }) };
|
|
251
|
+
});
|
|
252
|
+
const imagenDeLaCaptura = deps.decodificar(Buffer.from(captura.base64, "base64"));
|
|
253
|
+
const vista = pantallaMedida(imagenDeLaCaptura, filasDelAparato(geometria.aparato).map(comoMedir));
|
|
254
|
+
if (referencia === undefined || geometria.maqueta === undefined) {
|
|
255
|
+
const sola = compararDescripciones({ filas: [], extras: [] }, vista);
|
|
256
|
+
return { comparacion: { diferencias: [], faltan: [], recortes: sola.recortes, extras: { maqueta: [], captura: [] } }, completa: false };
|
|
257
|
+
}
|
|
258
|
+
// Las cajas del `code.html` están en el viewport de la maqueta; la imagen puede estar a 2x o 3x.
|
|
259
|
+
const imagen = deps.decodificar(Buffer.from(referencia.base64, "base64"));
|
|
260
|
+
const escala = imagen.ancho / geometria.maqueta.ancho;
|
|
261
|
+
const m = geometria.maqueta;
|
|
262
|
+
const indice = filasDeCajas(m.elementos.map((e) => e.caja));
|
|
263
|
+
const porFila = new Map();
|
|
264
|
+
m.elementos.forEach((e, i) => {
|
|
265
|
+
const aEscala = (c) => ({ x: c.x * escala, y: c.y * escala, ancho: c.ancho * escala, alto: c.alto * escala });
|
|
266
|
+
const caja = aEscala(e.caja);
|
|
267
|
+
// Un botón con su texto en un elemento propio: la letra en la caja del texto y la forma en la del botón, como el
|
|
268
|
+
// envoltorio del lado del aparato. Una caja que abraza su texto no dice nada de su alineación.
|
|
269
|
+
const control = e.cajaDelTexto !== undefined
|
|
270
|
+
? { texto: e.texto, caja: aEscala(e.cajaDelTexto), envoltorio: caja, ajustado: true }
|
|
271
|
+
: { texto: e.texto, caja, ...(e.boton === true ? {} : { ajustado: true }) };
|
|
272
|
+
porFila.set(indice[i], [...(porFila.get(indice[i]) ?? []), control]);
|
|
273
|
+
});
|
|
274
|
+
const filasDeLaMaqueta = [...porFila.entries()].sort((a, b) => a[0] - b[0]).map(([, f]) => f.sort((a, b) => a.caja.x - b.caja.x));
|
|
275
|
+
const comparacion = compararDescripciones(pantallaMedida(imagen, filasDeLaMaqueta), vista);
|
|
276
|
+
// Y los BLOQUES anchos (cabecera, visor, panel): su color y su forma también son el diseño.
|
|
277
|
+
const g = geometria.aparato;
|
|
278
|
+
const util = { arriba: g.barras?.estado?.abajo ?? 0, abajo: g.barras?.navegacion?.arriba ?? g.pantalla.alto };
|
|
279
|
+
const bloquesDelAparato = g.controles
|
|
280
|
+
.filter((c) => (c.tipo === "frame" || c.tipo === "group") && c.caja.ancho >= g.pantalla.ancho * 0.85 && c.caja.alto >= 40 && c.caja.alto <= g.pantalla.alto * 0.6 && c.caja.y >= util.arriba - 2)
|
|
281
|
+
.map((c) => c.caja);
|
|
282
|
+
const bloques = m.bloques === undefined || bloquesDelAparato.length === 0
|
|
283
|
+
? []
|
|
284
|
+
: compararBloques({ img: imagen, bloques: m.bloques.map((b) => ({ x: b.x * escala, y: b.y * escala, ancho: b.ancho * escala, alto: b.alto * escala })), util: { arriba: 0, abajo: m.alto * escala } }, { img: imagenDeLaCaptura, bloques: bloquesDelAparato, util });
|
|
285
|
+
return { comparacion: { ...comparacion, diferencias: [...bloques, ...comparacion.diferencias] }, completa: true };
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
return undefined;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/** La tabla de traducción de Tailwind a XOne de la skill, por su ruta virtual. */
|
|
292
|
+
export const TABLA_DE_TRADUCCION = "`read_file /skills/xone-development/references/css/de-una-maqueta-a-xone.md`";
|
|
130
293
|
export function crearCriticaVisual(deps) {
|
|
131
294
|
return tool(async (entrada) => {
|
|
132
295
|
// Se comprueban las DOS antes de abrir ninguna: ver `veredictoDeImagen`.
|
|
@@ -165,9 +328,50 @@ export function crearCriticaVisual(deps) {
|
|
|
165
328
|
return sinJuzgar(abiertaRef);
|
|
166
329
|
referencia = abiertaRef;
|
|
167
330
|
}
|
|
331
|
+
// Lo MEDIDO primero: el modelo lo recibe como hechos y no tiene que adivinar la estructura.
|
|
332
|
+
// La maqueta, DESCRITA aparte y antes —geometría y luego estilo—: sin ella, el estilo queda a la memoria
|
|
333
|
+
// del modelo y una maqueta sin code.html no tiene estructura. No poder describirla no impide juzgar.
|
|
334
|
+
const describir = async () => {
|
|
335
|
+
if (referencia === undefined || deps.describirPantalla === undefined)
|
|
336
|
+
return undefined;
|
|
337
|
+
try {
|
|
338
|
+
return await deps.describirPantalla(referencia);
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
return undefined;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
const geometria = await geometriaDe(entrada, referida, referencia, deps, describir);
|
|
345
|
+
/**
|
|
346
|
+
* **Con maqueta, la foto de UN CONTROL no se juzga**: la maqueta es la pantalla entera, y comparar contra un
|
|
347
|
+
* trozo es la opinión de un modelo sobre lo que falta alrededor. Medido en la calculadora: el desarrollador pasaba
|
|
348
|
+
* una y otra vez la foto del visor, el crítico le decía «captura la pantalla entera» y opinaba igual. Se contesta
|
|
349
|
+
* al momento y sin modelo, con el paso siguiente escrito.
|
|
350
|
+
*/
|
|
351
|
+
if (referencia !== undefined && geometria?.parcial === true) {
|
|
352
|
+
return [
|
|
353
|
+
"NO he juzgado la captura: es de UN CONTROL (un trozo de la pantalla), y la maqueta es la pantalla entera.",
|
|
354
|
+
"Comparar un trozo contra el diseño entero no dice nada. Pide al conductor una captura de la PANTALLA ENTERA",
|
|
355
|
+
"con `xone-hotswap shot` (sin `name=`) y vuelve a llamarme con ella y con la misma `referencia`.",
|
|
356
|
+
].join("\n");
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* **El estilo se MIDE en los píxeles de cada control**, con el MISMO esquema para la maqueta y para la captura
|
|
360
|
+
* (`core/estiloMedido.ts`): en la captura, en las cajas del árbol; en la maqueta, en las de su `code.html`.
|
|
361
|
+
* Describirlo con el modelo no valía —medido sobre la calculadora: la misma imagen descrita dos veces difería en
|
|
362
|
+
* diecisiete teclas, y ninguna pasada vio el texto recortado—; medido, cada vez sale lo mismo, en milisegundos.
|
|
363
|
+
* Sin `code.html` no hay cajas en la maqueta: se mide solo lo que se ve mal en el propio aparato (el recorte).
|
|
364
|
+
*/
|
|
365
|
+
const estilo = medirEstilo(abierta, referencia, geometria, deps);
|
|
366
|
+
const comparacion = estilo?.comparacion;
|
|
168
367
|
let veredicto;
|
|
169
368
|
try {
|
|
170
|
-
|
|
369
|
+
// Con la comparación MEDIDA contra la maqueta, decide ella; sin maqueta que medir, el crítico opina y los
|
|
370
|
+
// recortes medidos le llegan como hechos.
|
|
371
|
+
veredicto =
|
|
372
|
+
comparacion !== undefined && estilo?.completa === true
|
|
373
|
+
? { veredicto: hayQueArreglar(comparacion) ? "rojo" : "verde", observaciones: [], necesito: [] }
|
|
374
|
+
: await juzgarPantalla(abierta, { pantalla: entrada.pantalla }, deps.invocar, referencia, [...(geometria?.hechos ?? []), ...(comparacion?.recortes ?? [])]);
|
|
171
375
|
}
|
|
172
376
|
catch (error) {
|
|
173
377
|
// Fallo del ENTORNO —sin modelo, sin clave, sin red—: se dice, y no se convierte en un
|
|
@@ -181,9 +385,31 @@ export function crearCriticaVisual(deps) {
|
|
|
181
385
|
* quien llama: devolvérselo entero es el eco que ya paga el campo `pantalla`.
|
|
182
386
|
*/
|
|
183
387
|
const comparado = referencia === undefined ? "" : " (comparado con la referencia)";
|
|
388
|
+
/**
|
|
389
|
+
* **Lo medido decide.** Un control tapado, fuera de la pantalla o que falta es rojo aunque el modelo
|
|
390
|
+
* diga verde: lo saca el árbol de controles, no una opinión — y medido, el modelo no vio la «=»
|
|
391
|
+
* tapada de la calculadora.
|
|
392
|
+
*/
|
|
393
|
+
const medidoEnRojo = geometria?.bloqueante === true || (comparacion !== undefined && comparacion.recortes.length > 0);
|
|
394
|
+
const final = medidoEnRojo ? "rojo" : veredicto.veredicto;
|
|
184
395
|
const lineas = [
|
|
185
|
-
`Veredicto visual de «${entrada.pantalla}»${comparado}: ${veredicto.veredicto}.`,
|
|
396
|
+
`Veredicto visual de «${entrada.pantalla}»${comparado}: ${final}${medidoEnRojo && veredicto.veredicto !== "rojo" ? " (lo decide lo medido)" : ""}.`,
|
|
186
397
|
];
|
|
398
|
+
if (geometria !== undefined)
|
|
399
|
+
lineas.push("", ...geometria.lineas, "");
|
|
400
|
+
if (comparacion !== undefined) {
|
|
401
|
+
lineas.push(...(estilo?.completa === true
|
|
402
|
+
? [
|
|
403
|
+
...informeDeComparacion(comparacion, "medida"),
|
|
404
|
+
// Lo que falla aquí es casi siempre CÓMO se escribe en XOne una clase de Tailwind (una píldora, un
|
|
405
|
+
// botón sin contorno, una fuente): la tabla está medida en el aparato. Se nombra donde hace falta.
|
|
406
|
+
...(hayQueArreglar(comparacion) ? [`Cómo se escribe en XOne cada clase de la maqueta (medido en el aparato): ${TABLA_DE_TRADUCCION}`] : []),
|
|
407
|
+
]
|
|
408
|
+
: [
|
|
409
|
+
"MEDIDO en los píxeles de la captura (sin cajas de la maqueta que medir, solo lo que se ve mal en el aparato):",
|
|
410
|
+
...(comparacion.recortes.length === 0 ? ["- Ningún texto recortado."] : comparacion.recortes.map((r) => `- ${r}`)),
|
|
411
|
+
]), "");
|
|
412
|
+
}
|
|
187
413
|
if (veredicto.observaciones.length > 0) {
|
|
188
414
|
/**
|
|
189
415
|
* **El aviso no es cortesía: está medido.** Seis vueltas sobre la misma captura
|
|
@@ -191,7 +417,9 @@ export function crearCriticaVisual(deps) {
|
|
|
191
417
|
* diagnostique no lo evitó. A dónde apunta sí acertó las seis veces. Sin esta línea,
|
|
192
418
|
* el desarrollador se pone a buscar una rotación que no existe.
|
|
193
419
|
*/
|
|
194
|
-
lineas.push(
|
|
420
|
+
lineas.push(geometria === undefined
|
|
421
|
+
? "Lo que dice que ve (la REDACCIÓN no es fiable: describe mal la causa. Fíate de QUÉ"
|
|
422
|
+
: "ESTILO, lo que dice el modelo que ve (una OPINIÓN; la redacción no es fiable: fíate de QUÉ", "control señala, no de su explicación, y míralo tú):");
|
|
195
423
|
for (const o of veredicto.observaciones)
|
|
196
424
|
lineas.push(`- ${o}`);
|
|
197
425
|
}
|
|
@@ -226,15 +454,13 @@ export function crearCriticaVisual(deps) {
|
|
|
226
454
|
* (`conVerificacion`), y eso pide conducir el aparato desde código — medido: no se
|
|
227
455
|
* puede, porque llegar a una pantalla necesita abrir cajones y mirar el árbol.
|
|
228
456
|
*/
|
|
229
|
-
if (
|
|
457
|
+
if (final === "rojo") {
|
|
230
458
|
/**
|
|
231
|
-
* **
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* tamaño equivocado… también cuando se arregle en un `.xne`»). Sin referencia el
|
|
235
|
-
* hallazgo puede ser cualquier cosa, así que esa rama se queda como estaba.
|
|
459
|
+
* **El arreglo es de `developer-xone`, haya maqueta o no.** Mandaba a `designer-xone` con referencia, y el
|
|
460
|
+
* diseñador ya solo escribe en `icons/`: el layout y el CSS, también lo que se ve mal, son del desarrollador.
|
|
461
|
+
* Un rojo dirigido a quien no puede tocar el `.xne` era un arreglo sin dueño.
|
|
236
462
|
*/
|
|
237
|
-
const aQuien =
|
|
463
|
+
const aQuien = "developer-xone";
|
|
238
464
|
lineas.push("Esto es un defecto del proyecto SIN ARREGLAR, y qué hacer con él depende de TU", "encargo — que lo sabes tú y no yo:", `- Si el encargo incluye ARREGLAR o dejar la app bien: encárgaselo a \`${aQuien}\``, " pasándole estas observaciones tal cual, y cuando lo haya corregido manda otra vez", " al conductor a esta misma pantalla y vuelve a llamarme con la captura nueva.", referencia === undefined
|
|
239
465
|
? " No des la pantalla por buena hasta que yo la vea en verde."
|
|
240
466
|
: " Y vuelve CON LA MISMA `referencia`: sin ella mi verde solo diría que nada" +
|
|
@@ -243,7 +469,16 @@ export function crearCriticaVisual(deps) {
|
|
|
243
469
|
if (veredicto.necesito.length > 0) {
|
|
244
470
|
lineas.push(`Necesita ver ${veredicto.necesito.length === 1 ? "otra pantalla" : "otras pantallas"} para dictaminar: ${veredicto.necesito.join(", ")}.`, `Encarga al conductor que llegue ahí y capture, y vuelve a llamarme con esa captura (como mucho ${TOPE_DE_PETICIONES} veces).`);
|
|
245
471
|
}
|
|
246
|
-
|
|
472
|
+
const informe = lineas.join("\n");
|
|
473
|
+
if (deps.guardarInforme !== undefined) {
|
|
474
|
+
try {
|
|
475
|
+
await deps.guardarInforme(nombreDeArtefacto(entrada.captura), informe);
|
|
476
|
+
}
|
|
477
|
+
catch {
|
|
478
|
+
// Guardarlo es para auditar: que falle no cambia lo que se contesta.
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return informe;
|
|
247
482
|
}, {
|
|
248
483
|
name: "xone_critica_visual",
|
|
249
484
|
description: "Enseña una captura de pantalla del aparato a un revisor visual y devuelve qué se ve " +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"criticaVisual.js","sourceRoot":"","sources":["../../../src/agent/grafo/criticaVisual.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAuB,MAAM,mCAAmC,CAAC;AACxF,OAAO,EACL,cAAc,EACd,kBAAkB,GAGnB,MAAM,+BAA+B,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC;IACvB,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,CAAC,qFAAqF,CAAC;IAClG,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,CAAC,8EAA8E,CAAC;IAC3F;;;;;;;OAOG;IACH,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,sJAAsJ;QACpJ,qFAAqF;QACrF,sFAAsF;QACtF,+BAA+B,CAClC;CACJ,CAAC,CAAC;AAgBH;;;;;;;;;;;GAWG;AACH,SAAS,iBAAiB,CAAC,IAAY,EAAE,GAAW;IAClD,yFAAyF;IACzF,mEAAmE;IACnE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,IAAI,WAAW,GAAG,iEAAiE,CAAC;IACjG,CAAC;IACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,OAAO,IAAI,MAAM,oDAAoD,CAAC;IACxE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,IAAI,CACjB,IAAY,EACZ,IAAY,EACZ,IAA2B;IAE3B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;QACtE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,qFAAqF;QACrF,oBAAoB;QACpB,OAAO,kBAAkB,iBAAiB,CAAC,IAAI,CAAC,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC;IAC1G,CAAC;AACH,CAAC;AAED,kGAAkG;AAClG,KAAK,UAAU,YAAY,CACzB,MAAsB,EACtB,IAAY,EACZ,cAA2D;IAE3D,IAAI,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,CAAC,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;IAC7E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,6FAA6F;QAC7F,MAAM,MAAM,GAAI,KAA4B,CAAC,IAAI,CAAC;QAClD,OAAO,kBAAkB,MAAM,CAAC,MAAM,MAAM,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC;IAChG,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAAC,MAAc;IAC/B,OAAO;QACL,MAAM;QACN,wFAAwF;QACxF,qFAAqF;QACrF,sFAAsF;QACtF,WAAW;KACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAA2B;IAC5D,OAAO,IAAI,CACT,KAAK,EAAE,OAAgB,EAAE,EAAE;QACzB,yEAAyE;QACzE,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QACtE,IAAI,OAAO,WAAW,KAAK,QAAQ;YAAE,OAAO,WAAW,CAAC;QACxD,wGAAwG;QACxG,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,KAAK,SAAS,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACxI,IAAI,OAAO,QAAQ,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC7D,MAAM,cAAc,GAClB,OAAO,CAAC,UAAU,KAAK,SAAS;YAC9B,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,QAAQ,KAAK,SAAS;gBACtB,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,EAAE;gBACvF,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QAC/D,IAAI,OAAO,cAAc,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC,cAAc,CAAC,CAAC;QAEzE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACpE,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,OAAO,CAAC;QAEhD,IAAI,UAAyC,CAAC;QAC9C,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACrE,MAAM,UAAU,GACd,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS;gBACzD,CAAC,CAAC,MAAM,YAAY,CAAC,QAAQ,EAAE,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC;gBACxE,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAChE;;;;;;;;eAQG;YACH,IAAI,OAAO,UAAU,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAC,UAAU,CAAC,CAAC;YACjE,UAAU,GAAG,UAAU,CAAC;QAC1B,CAAC;QAED,IAAI,SAAS,CAAC;QACd,IAAI,CAAC;YACH,SAAS,GAAG,MAAM,cAAc,CAC9B,OAAO,EACP,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,EAC9B,IAAI,CAAC,OAAO,EACZ,UAAU,CACX,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,uFAAuF;YACvF,iFAAiF;YACjF,OAAO,2CAA2C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACvG,CAAC;QAED;;;;;WAKG;QACH,MAAM,SAAS,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gCAAgC,CAAC;QACnF,MAAM,MAAM,GAAG;YACb,wBAAwB,OAAO,CAAC,QAAQ,IAAI,SAAS,KAAK,SAAS,CAAC,SAAS,GAAG;SACjF,CAAC;QACF,IAAI,SAAS,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvC;;;;;eAKG;YACH,MAAM,CAAC,IAAI,CACT,oFAAoF,EACpF,qDAAqD,CACtD,CAAC;YACF,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,aAAa;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjE,CAAC;QACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA8BG;QACH,IAAI,SAAS,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;YACnC;;;;;;eAMG;YACH,MAAM,MAAM,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe,CAAC;YAC7E,MAAM,CAAC,IAAI,CACT,gFAAgF,EAChF,oCAAoC,EACpC,yEAAyE,MAAM,IAAI,EACnF,qFAAqF,EACrF,gFAAgF,EAChF,UAAU,KAAK,SAAS;gBACtB,CAAC,CAAC,8DAA8D;gBAChE,CAAC,CAAC,6EAA6E;oBAC7E,yDAAyD,EAC7D,qFAAqF,EACrF,sEAAsE,EACtE,2DAA2D,CAC5D,CAAC;QACJ,CAAC;QACD,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CACT,gBAAgB,SAAS,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,iBAAiB,qBAAqB,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAC1I,kGAAkG,kBAAkB,UAAU,CAC/H,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC,EACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EACT,sFAAsF;YACtF,mFAAmF;YACnF,kFAAkF;YAClF,sFAAsF;YACtF,mFAAmF;YACnF,wDAAwD;QAC1D,MAAM,EAAE,OAAO;KAChB,CACF,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"criticaVisual.js","sourceRoot":"","sources":["../../../src/agent/grafo/criticaVisual.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { tool } from "@langchain/core/tools";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { claveDeEstilo, estilosLegibles, LIMITES_DE_BUSQUEDA_DE_FUENTES, motivoDeFamiliaInaceptable, motivoDePesoInaceptable, nombreDeFicheroDeFuente, NOMBRE_BUSCAR_FUENTE, NOMBRE_TRAER_FUENTE, PESOS, recibeFuentes, rutaDeFuente, } from "../../core/fuentes.js";
|
|
6
|
+
import { motivoDeDestino, motivoDeDestinoEnDisco } from "./incorporarAdjunto.js";
|
|
7
|
+
export { NOMBRE_BUSCAR_FUENTE, NOMBRE_TRAER_FUENTE, recibeFuentes };
|
|
8
|
+
/**
|
|
9
|
+
* Traer una fuente de Google Fonts a `fonts/`, para que una pantalla use la tipografía de su
|
|
10
|
+
* maqueta (las de Stitch declaran `fontFamily`) y no la del sistema. Dos tools, porque solo UNA
|
|
11
|
+
* escribe:
|
|
12
|
+
*
|
|
13
|
+
* - **`buscar_fuente`**, de LECTURA: qué familias encajan, con sus estilos y el nombre de fichero
|
|
14
|
+
* de cada uno. Sin aprobación.
|
|
15
|
+
* - **`traer_fuente`**, que ESCRIBE un binario en el proyecto, y por eso pasa por la APROBACIÓN por
|
|
16
|
+
* su NOMBRE (`capacidades.ts`), con su tarjeta de `[fichero binario]` (`interrupts.ts#cambioDe`).
|
|
17
|
+
* Un `.ttf` no sobrevive a `write_file` (es texto), así que es el harness quien escribe los
|
|
18
|
+
* bytes, como `incorporar_adjunto`.
|
|
19
|
+
*
|
|
20
|
+
* ## El destino lo decide el CÓDIGO
|
|
21
|
+
*
|
|
22
|
+
* `file_path` está en la entrada porque es la clave que leen la tarjeta, `seDetieneEn` y el modo
|
|
23
|
+
* autónomo al anotar la ruta; pero solo vale EXACTAMENTE `rutaDeFuente(familia, peso, cursiva)`.
|
|
24
|
+
* Así el nombre sigue la convención de Google (`Inter-Bold.ttf`) que la skill documenta para
|
|
25
|
+
* `fontname`, y la guarda de texto se reduce a comparar con él. Las del DISCO (enlaces, fuera de
|
|
26
|
+
* la raíz) y el permiso del perfil se reaplican a mano con las MISMAS funciones de
|
|
27
|
+
* `incorporar_adjunto`: una tool propia no pasa por el middleware de permisos.
|
|
28
|
+
*
|
|
29
|
+
* ## Los rechazos se DEVUELVEN, nunca se lanzan
|
|
30
|
+
*
|
|
31
|
+
* Sin red, la tool lo DICE y no escribe nada. Lo que se descarga ya llega comprobado por el puerto
|
|
32
|
+
* (firma TrueType, tope de tamaño, host de Google).
|
|
33
|
+
*
|
|
34
|
+
* **Límite declarado**: solo TrueForge; la fuente llega al aparato DESPLEGANDO entero (la recarga
|
|
35
|
+
* en caliente no lleva `fonts/`), y la respuesta lo dice.
|
|
36
|
+
*/
|
|
37
|
+
const ESQUEMA_BUSCAR = z.object({
|
|
38
|
+
consulta: z.string().min(1).max(64).describe("El nombre de la familia o parte de él, como lo trae la maqueta (Inter, Roboto Mono)."),
|
|
39
|
+
limite: z.coerce.number().int().min(1).max(LIMITES_DE_BUSQUEDA_DE_FUENTES.maximo).optional()
|
|
40
|
+
.describe(`Por omisión ${LIMITES_DE_BUSQUEDA_DE_FUENTES.porOmision}.`),
|
|
41
|
+
});
|
|
42
|
+
const ESQUEMA_TRAER = z.object({
|
|
43
|
+
familia: z.string().min(1).max(64).describe("El nombre EXACTO de la familia, como lo devuelve buscar_fuente."),
|
|
44
|
+
peso: z.coerce.number().int().describe("100 a 900: 400 es el normal, 700 la negrita."),
|
|
45
|
+
cursiva: z.boolean().optional().describe("Cursiva. Por omisión, no."),
|
|
46
|
+
file_path: z.string().describe("La ruta que te dio buscar_fuente para ese estilo (/fonts/Inter-Bold.ttf). Pide aprobación."),
|
|
47
|
+
});
|
|
48
|
+
export function crearBuscarFuente(fuentes) {
|
|
49
|
+
return tool(async ({ consulta, limite }) => {
|
|
50
|
+
try {
|
|
51
|
+
const familias = await fuentes.buscar(consulta, limite ?? LIMITES_DE_BUSQUEDA_DE_FUENTES.porOmision);
|
|
52
|
+
if (familias.length === 0)
|
|
53
|
+
return `Ninguna familia de Google Fonts para «${consulta}». Prueba con menos palabras.`;
|
|
54
|
+
return [
|
|
55
|
+
`${familias.length} familias para «${consulta}»:`,
|
|
56
|
+
...familias.map((f) => {
|
|
57
|
+
const rectos = f.estilos.filter((e) => !e.endsWith("i"));
|
|
58
|
+
const clave = f.estilos.includes("400") ? "400" : (rectos[0] ?? f.estilos[0]);
|
|
59
|
+
const ejemplo = Number(clave.replace("i", ""));
|
|
60
|
+
const cursiva = clave.endsWith("i");
|
|
61
|
+
return `- ${f.familia} (${f.categoria}): pesos ${estilosLegibles(f.estilos)}. Fichero del ${ejemplo}${cursiva ? " cursiva" : ""}: ${rutaDeFuente(f.familia, ejemplo, cursiva)} (los demás estilos, igual: -Bold, -Medium, -Italic…)`;
|
|
62
|
+
}),
|
|
63
|
+
`Siguiente paso: ${NOMBRE_TRAER_FUENTE} con la familia, el peso y su file_path, UNO por estilo que use la pantalla.`,
|
|
64
|
+
].join("\n");
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return `No se pudo buscar: ${causa(error)}. No inventes el fichero: dilo, y la pantalla sigue con la fuente del sistema.`;
|
|
68
|
+
}
|
|
69
|
+
}, {
|
|
70
|
+
name: NOMBRE_BUSCAR_FUENTE,
|
|
71
|
+
description: "Busca una familia en Google Fonts y dice qué pesos tiene y cómo se llamaría cada fichero en fonts/. Úsala " +
|
|
72
|
+
"cuando la maqueta declare una tipografía (fontFamily). Solo LEE; para traer el fichero, " + NOMBRE_TRAER_FUENTE + ".",
|
|
73
|
+
schema: ESQUEMA_BUSCAR,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export function crearTraerFuente(fuentes, donde) {
|
|
77
|
+
return tool(async ({ familia, peso, cursiva, file_path }) => {
|
|
78
|
+
const enCursiva = cursiva === true;
|
|
79
|
+
const problema = motivoDeFamiliaInaceptable(familia) ?? motivoDePesoInaceptable(peso);
|
|
80
|
+
if (problema !== undefined)
|
|
81
|
+
return `${problema}.`;
|
|
82
|
+
const elPeso = peso;
|
|
83
|
+
const destino = rutaDeFuente(familia, elPeso, enCursiva);
|
|
84
|
+
const pedido = file_path.trim().startsWith("/") ? file_path.trim() : `/${file_path.trim()}`;
|
|
85
|
+
if (pedido !== destino) {
|
|
86
|
+
return `El fichero de ${familia} ${peso}${enCursiva ? " cursiva" : ""} es ${destino}, no «${file_path}»: vuelve a llamar con ese file_path.`;
|
|
87
|
+
}
|
|
88
|
+
const porTexto = motivoDeDestino(donde.perfil, destino);
|
|
89
|
+
if (porTexto !== undefined)
|
|
90
|
+
return porTexto;
|
|
91
|
+
const porDisco = motivoDeDestinoEnDisco(donde, destino);
|
|
92
|
+
if (porDisco !== undefined)
|
|
93
|
+
return porDisco;
|
|
94
|
+
let bytes;
|
|
95
|
+
try {
|
|
96
|
+
const f = await fuentes.familia(familia);
|
|
97
|
+
if (f === undefined)
|
|
98
|
+
return `Google Fonts no tiene la familia «${familia}». Búscala con ${NOMBRE_BUSCAR_FUENTE}: el nombre va exacto.`;
|
|
99
|
+
if (!f.estilos.includes(claveDeEstilo(elPeso, enCursiva))) {
|
|
100
|
+
return `${familia} no tiene ${peso}${enCursiva ? " cursiva" : ""}: tiene ${estilosLegibles(f.estilos)}. Usa el más cercano.`;
|
|
101
|
+
}
|
|
102
|
+
bytes = await fuentes.ttf(familia, elPeso, enCursiva);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
return `No se pudo traer la fuente: ${causa(error)}. No se ha escrito nada; la pantalla sigue con la fuente del sistema.`;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const real = resolve(donde.raiz, destino.slice(1));
|
|
109
|
+
mkdirSync(dirname(real), { recursive: true });
|
|
110
|
+
writeFileSync(real, bytes, { mode: 0o644 });
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
const code = error?.code;
|
|
114
|
+
return `No se pudo escribir ${destino} (${typeof code === "string" ? code : "error"}).`;
|
|
115
|
+
}
|
|
116
|
+
const nombre = nombreDeFicheroDeFuente(familia, elPeso, enCursiva);
|
|
117
|
+
return [
|
|
118
|
+
`Escrito ${destino} (${bytes.length} bytes). En el CSS: fontname: ${nombre}; (el nombre a secas: XOne lo busca en fonts/).`,
|
|
119
|
+
"Para verla en el aparato hay que DESPLEGAR la app entera: la recarga en caliente no lleva fonts/, y un fontname que el",
|
|
120
|
+
"aparato no tiene saca un diálogo de error y el control no se pinta.",
|
|
121
|
+
].join(" ");
|
|
122
|
+
}, {
|
|
123
|
+
name: NOMBRE_TRAER_FUENTE,
|
|
124
|
+
description: "Trae el .ttf de UN estilo (familia + peso + cursiva) de Google Fonts a fonts/ del proyecto, para usarlo con " +
|
|
125
|
+
"fontname en el CSS. El nombre del fichero lo da " + NOMBRE_BUSCAR_FUENTE + ". Escribe un binario y pasa por la " +
|
|
126
|
+
`aprobación de la persona. Pesos: ${PESOS.join(", ")}.`,
|
|
127
|
+
schema: ESQUEMA_TRAER,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function causa(error) {
|
|
131
|
+
return error instanceof Error ? error.message : "fallo desconocido";
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=fuentesDeGoogle.js.map
|