xonecode 0.1.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/README.md +167 -0
- package/dist/agent/authEnDisco.js +56 -0
- package/dist/agent/authEnDisco.js.map +1 -0
- package/dist/agent/configEnDisco.js +109 -0
- package/dist/agent/configEnDisco.js.map +1 -0
- package/dist/agent/crearProyecto.js +34 -0
- package/dist/agent/crearProyecto.js.map +1 -0
- package/dist/agent/entorno.js +124 -0
- package/dist/agent/entorno.js.map +1 -0
- package/dist/agent/guionizado.js +53 -0
- package/dist/agent/guionizado.js.map +1 -0
- package/dist/agent/instantanea.js +129 -0
- package/dist/agent/instantanea.js.map +1 -0
- package/dist/agent/interrupts.js +83 -0
- package/dist/agent/interrupts.js.map +1 -0
- package/dist/agent/mensajes.js +24 -0
- package/dist/agent/mensajes.js.map +1 -0
- package/dist/agent/modelos.js +42 -0
- package/dist/agent/modelos.js.map +1 -0
- package/dist/agent/normalizar.js +20 -0
- package/dist/agent/normalizar.js.map +1 -0
- package/dist/agent/perfiles.js +103 -0
- package/dist/agent/perfiles.js.map +1 -0
- package/dist/agent/proyecto.js +107 -0
- package/dist/agent/proyecto.js.map +1 -0
- package/dist/agent/puente.js +142 -0
- package/dist/agent/puente.js.map +1 -0
- package/dist/agent/resumenDeTool.js +48 -0
- package/dist/agent/resumenDeTool.js.map +1 -0
- package/dist/agent/skills.js +65 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/textoDeTool.js +113 -0
- package/dist/agent/textoDeTool.js.map +1 -0
- package/dist/agent/turnoReal.js +173 -0
- package/dist/agent/turnoReal.js.map +1 -0
- package/dist/agent/verificador.js +65 -0
- package/dist/agent/verificador.js.map +1 -0
- package/dist/agent/xoneAgent.js +106 -0
- package/dist/agent/xoneAgent.js.map +1 -0
- package/dist/bin.js +9 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli/aprobar.js +82 -0
- package/dist/cli/aprobar.js.map +1 -0
- package/dist/cli/config.js +133 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/consola.js +346 -0
- package/dist/cli/consola.js.map +1 -0
- package/dist/cli/describe.js +53 -0
- package/dist/cli/describe.js.map +1 -0
- package/dist/cli/doctor.js +45 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/main.js +520 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/markdown.js +90 -0
- package/dist/cli/markdown.js.map +1 -0
- package/dist/cli/run.js +164 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/spinner.js +89 -0
- package/dist/cli/spinner.js.map +1 -0
- package/dist/cli/stdio.js +193 -0
- package/dist/cli/stdio.js.map +1 -0
- package/dist/cli/tema.js +40 -0
- package/dist/cli/tema.js.map +1 -0
- package/dist/cli/verify.js +62 -0
- package/dist/cli/verify.js.map +1 -0
- package/dist/core/bitacora.js +30 -0
- package/dist/core/bitacora.js.map +1 -0
- package/dist/core/config.js +236 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/contextos.js +56 -0
- package/dist/core/contextos.js.map +1 -0
- package/dist/core/deps.js +51 -0
- package/dist/core/deps.js.map +1 -0
- package/dist/core/diff.js +79 -0
- package/dist/core/diff.js.map +1 -0
- package/dist/core/esqueleto.js +366 -0
- package/dist/core/esqueleto.js.map +1 -0
- package/dist/core/events.js +2 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/modelos.js +85 -0
- package/dist/core/modelos.js.map +1 -0
- package/dist/core/notify.js +106 -0
- package/dist/core/notify.js.map +1 -0
- package/dist/core/ports.js +114 -0
- package/dist/core/ports.js.map +1 -0
- package/dist/core/turno.js +127 -0
- package/dist/core/turno.js.map +1 -0
- package/dist/vendor/hitl.js +103 -0
- package/dist/vendor/hitl.js.map +1 -0
- package/dist/vendor/skillLoaders/catalog.js +74 -0
- package/dist/vendor/skillLoaders/catalog.js.map +1 -0
- package/dist/vendor/tokenTracking.js +58 -0
- package/dist/vendor/tokenTracking.js.map +1 -0
- package/package.json +41 -0
- package/skills/xone-debugging/SKILL.md +52 -0
- package/skills/xone-debugging/references/faq.md +561 -0
- package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
- package/skills/xone-development/SKILL.md +105 -0
- package/skills/xone-development/references/anti-patrones.md +94 -0
- package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
- package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
- package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
- package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
- package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
- package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
- package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
- package/skills/xone-development/references/datos/appdata.md +611 -0
- package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
- package/skills/xone-development/references/datos/http.md +366 -0
- package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
- package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
- package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
- package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
- package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
- package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
- package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
- package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
- package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
- package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
- package/skills/xone-development/references/indice-completo.md +77 -0
- package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
- package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
- package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
- package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
- package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
- package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
- package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
- package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
- package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
- package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
- package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
- package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
- package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
- package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
- package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
- package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
- package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
- package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
- package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
- package/skills/xone-development/references/tipos-de-prop.md +28 -0
- package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
- package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
- package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
- package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
- package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
- package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
- package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
- package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
- package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
- package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
- package/skills/xone-development/references/xml-ui/mapas.md +685 -0
- package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
- package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
- package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
- package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
- package/skills/xone-plan-builder/SKILL.md +183 -0
- package/skills/xone-plan-builder/agents/openai.yaml +5 -0
- package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
- package/skills/xone-project-generator/SKILL.md +111 -0
- package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
- package/skills/xone-project-generator/references/colecciones-base.md +16 -0
- package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
- package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
- package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
- package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
- package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
- package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
- package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
- package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
- package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
- package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
- package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
- package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
- package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
- package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
- package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
- package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
- package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
- package/skills/xone-review/SKILL.md +189 -0
- package/skills/xone-spec-builder/SKILL.md +235 -0
- package/skills/xone-spec-builder/agents/openai.yaml +5 -0
- package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
- package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
- package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Los puertos: todo lo caro entra por aquí, con su doble determinista al lado.
|
|
3
|
+
*
|
|
4
|
+
* La regla dura: los puertos se PASAN al construir, nunca se importan dentro de quien
|
|
5
|
+
* los usa. Es lo que hace que el lazo completo se recorra sin API, sin red y sin
|
|
6
|
+
* CloudStudio — la propiedad que sostiene los tests offline del laboratorio.
|
|
7
|
+
*
|
|
8
|
+
* Este fichero es TypeScript puro: no importa langchain, langgraph, deepagents, MCP,
|
|
9
|
+
* Ink ni React. La frontera está probada en `core/imports.test.ts`.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* La marca de «esto es un doble», y por qué es un Symbol y no un booleano.
|
|
13
|
+
*
|
|
14
|
+
* En el harness Python equivalente el flag `verifier_is_stub` no es un campo que alguien
|
|
15
|
+
* rellene: es una propiedad derivada de la CLASE del objeto. La diferencia importa —
|
|
16
|
+
* un booleano se puede olvidar, o poner a false sobre un doble, y entonces los tres
|
|
17
|
+
* avisos de honestidad callan justo cuando más falta hacen.
|
|
18
|
+
*
|
|
19
|
+
* Aquí la traducción fiel es una marca que solo los dobles llevan: un puerto real no
|
|
20
|
+
* puede fingir que no lo es porque no la tiene, y un doble no puede quitársela sin
|
|
21
|
+
* editar su propia definición.
|
|
22
|
+
*/
|
|
23
|
+
export const ES_DOBLE = Symbol.for("xonecode.es-doble");
|
|
24
|
+
export function esDoble(puerto) {
|
|
25
|
+
return typeof puerto === "object" && puerto !== null && ES_DOBLE in puerto;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* La huella de un hallazgo, para detectar NO-PROGRESO: la misma huella dos veces seguidas
|
|
29
|
+
* significa que reparar no está avanzando, y se bloquea ANTES de agotar el presupuesto.
|
|
30
|
+
*
|
|
31
|
+
* Ignora el mensaje a propósito: lleva nombres interpolados que varían sin que el problema
|
|
32
|
+
* cambie. Y tolera la ausencia de línea, que es el caso normal según la medición.
|
|
33
|
+
*/
|
|
34
|
+
export function huella(h) {
|
|
35
|
+
return [h.code, h.fichero ?? "", h.linea ?? ""].join("|");
|
|
36
|
+
}
|
|
37
|
+
// ─────────────────────────── LOS DOBLES ───────────────────────────
|
|
38
|
+
// Viven aquí, junto a los puertos, y NO en una carpeta de tests. El motivo: el modo
|
|
39
|
+
// offline es un modo de USO de primera clase (`xonecode describe` lo enseña al usuario),
|
|
40
|
+
// no un detalle de la suite. Un doble escondido en fixtures no lo puede reportar.
|
|
41
|
+
export class McpVacio {
|
|
42
|
+
[ES_DOBLE] = true;
|
|
43
|
+
async catalogo() {
|
|
44
|
+
return { cloudstudio: [], ide: [] };
|
|
45
|
+
}
|
|
46
|
+
async invocar(tool) {
|
|
47
|
+
throw new Error(`[DOBLE] No hay MCP: la tool «${tool}» no se ha ejecutado y el proyecto NO se ha tocado.`);
|
|
48
|
+
}
|
|
49
|
+
async cerrar() { }
|
|
50
|
+
}
|
|
51
|
+
export class SkillsEnMemoria {
|
|
52
|
+
contenido;
|
|
53
|
+
[ES_DOBLE] = true;
|
|
54
|
+
constructor(contenido = {}) {
|
|
55
|
+
this.contenido = contenido;
|
|
56
|
+
}
|
|
57
|
+
catalogo() {
|
|
58
|
+
return Object.keys(this.contenido).map((nombre) => ({
|
|
59
|
+
nombre,
|
|
60
|
+
descripcion: `[DOBLE] skill en memoria`,
|
|
61
|
+
tokens: Math.ceil(this.contenido[nombre].length / 4),
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
cargar(nombre) {
|
|
65
|
+
const c = this.contenido[nombre];
|
|
66
|
+
if (c === undefined)
|
|
67
|
+
throw new Error(`[DOBLE] no hay skill «${nombre}» en memoria`);
|
|
68
|
+
return c;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export class ModeloGuionizado {
|
|
72
|
+
respuestas;
|
|
73
|
+
[ES_DOBLE] = true;
|
|
74
|
+
constructor(respuestas = ["(respuesta guionizada)"]) {
|
|
75
|
+
this.respuestas = respuestas;
|
|
76
|
+
}
|
|
77
|
+
paraPapel() {
|
|
78
|
+
return { guion: this.respuestas };
|
|
79
|
+
}
|
|
80
|
+
descripcion() {
|
|
81
|
+
return {
|
|
82
|
+
rapido: "[DOBLE] guionizado",
|
|
83
|
+
trabajo: "[DOBLE] guionizado",
|
|
84
|
+
afilado: "[DOBLE] guionizado",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Verificador que siempre dice verde.
|
|
90
|
+
*
|
|
91
|
+
* Peligroso a propósito: es el doble que más miente si nadie lo declara, porque un verde
|
|
92
|
+
* falso deja pasar código roto. Por eso lleva la marca y por eso `describe` lo canta.
|
|
93
|
+
*/
|
|
94
|
+
export class StubVerifier {
|
|
95
|
+
[ES_DOBLE] = true;
|
|
96
|
+
async verificar() {
|
|
97
|
+
return { verde: true, hallazgos: [] };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** Verificador con guion, para recorrer el lazo de reparación sin LLM: [rojo, rojo, verde]. */
|
|
101
|
+
export class VerifierGuionizado {
|
|
102
|
+
guion;
|
|
103
|
+
[ES_DOBLE] = true;
|
|
104
|
+
i = 0;
|
|
105
|
+
constructor(guion) {
|
|
106
|
+
this.guion = guion;
|
|
107
|
+
}
|
|
108
|
+
async verificar() {
|
|
109
|
+
const r = this.guion[Math.min(this.i, this.guion.length - 1)];
|
|
110
|
+
this.i++;
|
|
111
|
+
return r;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=ports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.js","sourceRoot":"","sources":["../../src/core/ports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Bitacora } from "./bitacora.js";
|
|
2
|
+
import { Colapsador } from "./notify.js";
|
|
3
|
+
/** Cómo se le cuenta cada fase al usuario. En un solo sitio, no repartido por el motor. */
|
|
4
|
+
const TEXTO_DE_FASE = {
|
|
5
|
+
entendiendo: "entendiendo la petición",
|
|
6
|
+
planificando: "planificando",
|
|
7
|
+
"esperando-aprobacion": "esperando tu aprobación",
|
|
8
|
+
ejecutando: "desarrollando",
|
|
9
|
+
verificando: "verificando con el simulador",
|
|
10
|
+
juzgando: "revisando el resultado",
|
|
11
|
+
subiendo: "publicando",
|
|
12
|
+
respondiendo: "redactando la respuesta",
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Un turno completo: consume los eventos, cuenta lo que hay que contar, devuelve la
|
|
16
|
+
* bitácora.
|
|
17
|
+
*
|
|
18
|
+
* Nunca deja la línea de tokens abierta: el `finally` la cierra tanto si el turno termina
|
|
19
|
+
* bien como si el flujo revienta a mitad. Sin eso, el mensaje de error se pegaría al final
|
|
20
|
+
* de una respuesta a medio escribir.
|
|
21
|
+
*/
|
|
22
|
+
export async function correrTurno(eventos, piel, opciones = {}) {
|
|
23
|
+
const bitacora = new Bitacora();
|
|
24
|
+
const colapsador = new Colapsador();
|
|
25
|
+
const t0 = Date.now();
|
|
26
|
+
let abierta = false;
|
|
27
|
+
let ultimoId;
|
|
28
|
+
/** Cualquier cosa que no sea un token empieza su propia línea. */
|
|
29
|
+
const escribirLinea = (texto) => {
|
|
30
|
+
if (abierta) {
|
|
31
|
+
piel.cerrarLinea();
|
|
32
|
+
abierta = false;
|
|
33
|
+
}
|
|
34
|
+
piel.linea(texto);
|
|
35
|
+
};
|
|
36
|
+
try {
|
|
37
|
+
for await (const ev of eventos) {
|
|
38
|
+
switch (ev.tipo) {
|
|
39
|
+
case "token":
|
|
40
|
+
if (abierta && ev.msgId !== undefined && ev.msgId !== ultimoId) {
|
|
41
|
+
piel.cerrarLinea();
|
|
42
|
+
abierta = false;
|
|
43
|
+
}
|
|
44
|
+
ultimoId = ev.msgId;
|
|
45
|
+
abierta = true;
|
|
46
|
+
piel.token(ev.texto);
|
|
47
|
+
break;
|
|
48
|
+
case "fase": {
|
|
49
|
+
bitacora.anota(ev.fase, ev.detalle ?? "");
|
|
50
|
+
const texto = `${TEXTO_DE_FASE[ev.fase]}${ev.detalle ? ` — ${ev.detalle}` : ""}`;
|
|
51
|
+
// La fase DURA: la piel que sabe animarla la recibe delegada (con la línea de
|
|
52
|
+
// tokens cerrada, como cualquier otra cosa que empieza su propia línea); la
|
|
53
|
+
// que no, la pinta como la línea estática de siempre.
|
|
54
|
+
if (piel.fase) {
|
|
55
|
+
if (abierta) {
|
|
56
|
+
piel.cerrarLinea();
|
|
57
|
+
abierta = false;
|
|
58
|
+
}
|
|
59
|
+
piel.fase(texto);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
escribirLinea(`· ${texto}`);
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case "tool":
|
|
67
|
+
bitacora.anota("tool", ev.nombre);
|
|
68
|
+
for (const linea of colapsador.lineas({ nombre: ev.nombre, detalle: ev.detalle, error: ev.error })) {
|
|
69
|
+
escribirLinea(linea);
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
case "plan":
|
|
73
|
+
bitacora.anota("plan", `${ev.tareas.length} tareas`);
|
|
74
|
+
escribirLinea(`📋 plan de ${ev.tareas.length} tarea(s):`);
|
|
75
|
+
ev.tareas.forEach((t, i) => escribirLinea(` ${i + 1}. ${t.descripcion}`));
|
|
76
|
+
break;
|
|
77
|
+
case "tarea":
|
|
78
|
+
bitacora.anota("tarea", `${ev.id} ${ev.estado}`);
|
|
79
|
+
escribirLinea(`▶ tarea ${ev.indice}/${ev.total}: ${ev.id} — ${ev.estado}`);
|
|
80
|
+
break;
|
|
81
|
+
case "verificacion":
|
|
82
|
+
bitacora.anota("verify", ev.verde ? "verde" : `${ev.errores} errores`);
|
|
83
|
+
escribirLinea(ev.verde
|
|
84
|
+
? "✓ verificación en verde"
|
|
85
|
+
: `✗ verificación: ${ev.errores} error(es), ${ev.avisos} aviso(s)`);
|
|
86
|
+
break;
|
|
87
|
+
case "reparacion":
|
|
88
|
+
bitacora.anota("reparacion", `${ev.intento}/${ev.tope}`);
|
|
89
|
+
escribirLinea(`🔁 reparando (intento ${ev.intento} de ${ev.tope})`);
|
|
90
|
+
break;
|
|
91
|
+
case "bloqueado":
|
|
92
|
+
bitacora.anota("bloqueado", ev.motivo);
|
|
93
|
+
escribirLinea(`⛔ bloqueado (${ev.motivo}): ${ev.explicacion}`);
|
|
94
|
+
break;
|
|
95
|
+
case "pausa":
|
|
96
|
+
if (abierta) {
|
|
97
|
+
piel.cerrarLinea();
|
|
98
|
+
abierta = false;
|
|
99
|
+
}
|
|
100
|
+
bitacora.anota("pausa", `${ev.pendientes.length} pendiente(s)`);
|
|
101
|
+
piel.pausa(ev.pendientes);
|
|
102
|
+
break;
|
|
103
|
+
case "aviso":
|
|
104
|
+
bitacora.anota("aviso", ev.texto);
|
|
105
|
+
escribirLinea(ev.texto);
|
|
106
|
+
break;
|
|
107
|
+
case "fin":
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
// La cuenta de la última racha de tools, aunque el turno reviente: si se cayó a
|
|
114
|
+
// mitad, el «×17» es justo el dato que explica dónde se quedó.
|
|
115
|
+
const cierre = colapsador.cierre();
|
|
116
|
+
if (cierre)
|
|
117
|
+
escribirLinea(cierre);
|
|
118
|
+
// Los avisos deterministas van DESPUÉS de todo, y también si hubo excepción.
|
|
119
|
+
for (const aviso of opciones.avisos?.(bitacora) ?? [])
|
|
120
|
+
escribirLinea(aviso);
|
|
121
|
+
if (abierta)
|
|
122
|
+
piel.cerrarLinea();
|
|
123
|
+
piel.fin(Date.now() - t0);
|
|
124
|
+
}
|
|
125
|
+
return bitacora;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=turno.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turno.js","sourceRoot":"","sources":["../../src/core/turno.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAyBzC,2FAA2F;AAC3F,MAAM,aAAa,GAAyB;IAC1C,WAAW,EAAE,yBAAyB;IACtC,YAAY,EAAE,cAAc;IAC5B,sBAAsB,EAAE,yBAAyB;IACjD,UAAU,EAAE,eAAe;IAC3B,WAAW,EAAE,8BAA8B;IAC3C,QAAQ,EAAE,wBAAwB;IAClC,QAAQ,EAAE,YAAY;IACtB,YAAY,EAAE,yBAAyB;CACxC,CAAC;AAcF;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAmC,EACnC,IAAU,EACV,WAA6B,EAAE;IAE/B,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;IACpC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACtB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,QAA4B,CAAC;IAEjC,kEAAkE;IAClE,MAAM,aAAa,GAAG,CAAC,KAAa,EAAQ,EAAE;QAC5C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC,CAAC;IAEF,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;YAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;gBAChB,KAAK,OAAO;oBACV,IAAI,OAAO,IAAI,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;wBAC/D,IAAI,CAAC,WAAW,EAAE,CAAC;wBACnB,OAAO,GAAG,KAAK,CAAC;oBAClB,CAAC;oBACD,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC;oBACpB,OAAO,GAAG,IAAI,CAAC;oBACf,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;oBACrB,MAAM;gBAER,KAAK,MAAM,CAAC,CAAC,CAAC;oBACZ,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;oBAC1C,MAAM,KAAK,GAAG,GAAG,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;oBACjF,8EAA8E;oBAC9E,4EAA4E;oBAC5E,sDAAsD;oBACtD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;wBACd,IAAI,OAAO,EAAE,CAAC;4BACZ,IAAI,CAAC,WAAW,EAAE,CAAC;4BACnB,OAAO,GAAG,KAAK,CAAC;wBAClB,CAAC;wBACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACnB,CAAC;yBAAM,CAAC;wBACN,aAAa,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC;oBAC/B,CAAC;oBACD,MAAM;gBACR,CAAC;gBAED,KAAK,MAAM;oBACT,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;oBAClC,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;wBACnG,aAAa,CAAC,KAAK,CAAC,CAAC;oBACvB,CAAC;oBACD,MAAM;gBAER,KAAK,MAAM;oBACT,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;oBACrD,aAAa,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,MAAM,YAAY,CAAC,CAAC;oBAC1D,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;oBAC5E,MAAM;gBAER,KAAK,OAAO;oBACV,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;oBACjD,aAAa,CAAC,YAAY,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;oBAC5E,MAAM;gBAER,KAAK,cAAc;oBACjB,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,OAAO,UAAU,CAAC,CAAC;oBACvE,aAAa,CACX,EAAE,CAAC,KAAK;wBACN,CAAC,CAAC,0BAA0B;wBAC5B,CAAC,CAAC,oBAAoB,EAAE,CAAC,OAAO,eAAe,EAAE,CAAC,MAAM,WAAW,CACtE,CAAC;oBACF,MAAM;gBAER,KAAK,YAAY;oBACf,QAAQ,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;oBACzD,aAAa,CAAC,yBAAyB,EAAE,CAAC,OAAO,OAAO,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC;oBACpE,MAAM;gBAER,KAAK,WAAW;oBACd,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;oBACvC,aAAa,CAAC,gBAAgB,EAAE,CAAC,MAAM,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;oBAC/D,MAAM;gBAER,KAAK,OAAO;oBACV,IAAI,OAAO,EAAE,CAAC;wBACZ,IAAI,CAAC,WAAW,EAAE,CAAC;wBACnB,OAAO,GAAG,KAAK,CAAC;oBAClB,CAAC;oBACD,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,eAAe,CAAC,CAAC;oBAChE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;oBAC1B,MAAM;gBAER,KAAK,OAAO;oBACV,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;oBAClC,aAAa,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;oBACxB,MAAM;gBAER,KAAK,KAAK;oBACR,MAAM;YACV,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,gFAAgF;QAChF,+DAA+D;QAC/D,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;QACnC,IAAI,MAAM;YAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAElC,6EAA6E;QAC7E,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE;YAAE,aAAa,CAAC,KAAK,CAAC,CAAC;QAE5E,IAAI,OAAO;YAAE,IAAI,CAAC,WAAW,EAAE,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aprobación humana de N escrituras concurrentes.
|
|
3
|
+
*
|
|
4
|
+
* La forma de este módulo sale de la verificación en vivo, no de la intuición:
|
|
5
|
+
*
|
|
6
|
+
* 1. Los interrupts de un subagente SÍ propagan al stream de arriba.
|
|
7
|
+
* 2. Con el orquestador emitiendo dos `task` en un turno, quedan DOS interrupts
|
|
8
|
+
* pendientes a la vez (`tasks.length === 2`, `next === ["tools","tools"]`).
|
|
9
|
+
* 3. El resume tiene que ser un MAPA por id de interrupt. Un array pelado falla con
|
|
10
|
+
* "Invalid HITLResponse: decisions must be a non-empty array".
|
|
11
|
+
* 4. El interrupt NO dice de qué subagente viene, así que la atribución viaja en la
|
|
12
|
+
* `description` que cada subagente pone en su `InterruptOnConfig`.
|
|
13
|
+
*
|
|
14
|
+
* De ahí que esto no pueda ser un "pregunta una cosa y reanuda": hay que recoger
|
|
15
|
+
* todos los pendientes, preguntar por cada uno, y reanudar con un único Command.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Tope de rondas de aprobación. Sin él, un modelo que insista tras cada rechazo
|
|
19
|
+
* convierte el bucle en un ciclo automático de ~200k tokens por ronda. Lo comparten
|
|
20
|
+
* da04 y la consola.
|
|
21
|
+
*/
|
|
22
|
+
export const MAX_APPROVAL_ROUNDS = 5;
|
|
23
|
+
/**
|
|
24
|
+
* El mensaje de rechazo tiene que dejar clarísimo que NO se aplicó nada: si solo dice
|
|
25
|
+
* "no la reintentes", el modelo puede sintetizar la respuesta final como si la
|
|
26
|
+
* escritura hubiese quedado lista — la salida contradiciendo lo que realmente pasó.
|
|
27
|
+
*/
|
|
28
|
+
export const REJECT_MESSAGE = "RECHAZADO por el usuario. Esta operación NO se ha ejecutado y el proyecto NO se " +
|
|
29
|
+
"ha modificado. No la reintentes ni la reformules. En tu respuesta final di " +
|
|
30
|
+
"explícitamente que el cambio no se aplicó porque fue rechazado, y explica qué " +
|
|
31
|
+
"pretendías hacer y por qué, para que el usuario pueda decidir.";
|
|
32
|
+
export function collectPending(state) {
|
|
33
|
+
const tasks = state?.tasks;
|
|
34
|
+
if (!Array.isArray(tasks))
|
|
35
|
+
return [];
|
|
36
|
+
const pending = [];
|
|
37
|
+
for (const task of tasks) {
|
|
38
|
+
const interrupts = task.interrupts;
|
|
39
|
+
if (!Array.isArray(interrupts))
|
|
40
|
+
continue;
|
|
41
|
+
for (const interrupt of interrupts) {
|
|
42
|
+
const { id, value } = interrupt;
|
|
43
|
+
const action = value?.actionRequests?.[0];
|
|
44
|
+
if (!id || !action?.name)
|
|
45
|
+
continue;
|
|
46
|
+
pending.push({
|
|
47
|
+
id,
|
|
48
|
+
tool: action.name,
|
|
49
|
+
args: action.args ?? {},
|
|
50
|
+
description: action.description ?? `Ejecutar ${action.name}`,
|
|
51
|
+
allowedDecisions: value?.reviewConfigs?.[0]?.allowedDecisions ?? ["approve", "reject"],
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return pending;
|
|
56
|
+
}
|
|
57
|
+
/** El mapa `{ id → { decisions: [...] } }` que espera `new Command({ resume })`. */
|
|
58
|
+
export function buildResume(decisions) {
|
|
59
|
+
const resume = {};
|
|
60
|
+
for (const [id, decision] of decisions) {
|
|
61
|
+
resume[id] = { decisions: [decision] };
|
|
62
|
+
}
|
|
63
|
+
return resume;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Respuestas que cuentan como aprobar.
|
|
67
|
+
*
|
|
68
|
+
* El Enter a secas ("") solo vale con un terminal de verdad detrás. Fuera de un TTY
|
|
69
|
+
* —un pipe, CI, un cron— una línea en blanco no demuestra que haya nadie mirando, y
|
|
70
|
+
* esto aprueba escrituras sobre un proyecto real. Ahí se exige un "s" explícito.
|
|
71
|
+
*/
|
|
72
|
+
const APPROVALS_TTY = new Set(["", "s", "si", "sí", "y", "yes"]);
|
|
73
|
+
const APPROVALS_NO_TTY = new Set(["s", "si", "sí", "y", "yes"]);
|
|
74
|
+
/**
|
|
75
|
+
* Interpreta una respuesta de aprobación, sin imprimir nada ni preguntar: es la
|
|
76
|
+
* parte pura de promptForDecisions, para que la consola TUI la reutilice.
|
|
77
|
+
*
|
|
78
|
+
* Fail-closed: el Enter a secas solo aprueba con `interactive: true` explícito (un
|
|
79
|
+
* TTY de verdad detrás); cualquier otra respuesta que no se entiende es rechazo.
|
|
80
|
+
*/
|
|
81
|
+
export function interpretAnswer(answer, opts = {}) {
|
|
82
|
+
const approvals = opts.interactive === true ? APPROVALS_TTY : APPROVALS_NO_TTY;
|
|
83
|
+
if (approvals.has(answer.trim().toLowerCase()))
|
|
84
|
+
return { type: "approve" };
|
|
85
|
+
return { type: "reject", message: REJECT_MESSAGE };
|
|
86
|
+
}
|
|
87
|
+
export async function promptForDecisions(pending, ask, opts = {}) {
|
|
88
|
+
const decisions = new Map();
|
|
89
|
+
for (const [i, p] of pending.entries()) {
|
|
90
|
+
console.log(`\n${"─".repeat(64)}`);
|
|
91
|
+
console.log(`APROBACIÓN ${i + 1}/${pending.length}: ${p.description}`);
|
|
92
|
+
console.log(` tool: ${p.tool}`);
|
|
93
|
+
// La `description` propia sustituye a la autogenerada, que era la que traía los
|
|
94
|
+
// args. Hay que imprimirlos aquí o el usuario aprueba a ciegas.
|
|
95
|
+
console.log(` args: ${JSON.stringify(p.args, null, 2).replace(/\n/g, "\n ")}`);
|
|
96
|
+
const answer = await ask("¿Aprobar? [S/n] ");
|
|
97
|
+
const decision = interpretAnswer(answer, opts);
|
|
98
|
+
decisions.set(p.id, decision);
|
|
99
|
+
console.log(decision.type === "approve" ? " → aprobado" : " → rechazado");
|
|
100
|
+
}
|
|
101
|
+
return decisions;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=hitl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hitl.js","sourceRoot":"","sources":["../../src/vendor/hitl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Descubrimiento de skills propio, independiente del middleware de deepagents.
|
|
3
|
+
*
|
|
4
|
+
* Existe porque el experimento necesita construir el catálogo y el cuerpo del skill
|
|
5
|
+
* por su cuenta: el middleware interno solo sabe hacerlo de una manera (metadatos al
|
|
6
|
+
* prompt + `read_file` para el cuerpo), y lo que se quiere medir es justo qué pasa
|
|
7
|
+
* cuando se hace de otras.
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
10
|
+
import { join, relative, sep } from "node:path";
|
|
11
|
+
/**
|
|
12
|
+
* Frontmatter YAML mínimo: `clave: valor` de una línea entre delimitadores `---`.
|
|
13
|
+
* No se usa un parser de YAML a propósito — los skills reales solo necesitan esto y
|
|
14
|
+
* una dependencia más sería ruido en un experimento sobre coste de contexto.
|
|
15
|
+
*/
|
|
16
|
+
export function parseFrontmatter(content) {
|
|
17
|
+
if (!content.startsWith("---"))
|
|
18
|
+
return { data: {}, body: content };
|
|
19
|
+
const end = content.indexOf("\n---", 3);
|
|
20
|
+
if (end === -1)
|
|
21
|
+
return { data: {}, body: content };
|
|
22
|
+
const raw = content.slice(3, end);
|
|
23
|
+
const data = {};
|
|
24
|
+
for (const line of raw.split("\n")) {
|
|
25
|
+
const i = line.indexOf(":");
|
|
26
|
+
if (i === -1)
|
|
27
|
+
continue;
|
|
28
|
+
const key = line.slice(0, i).trim();
|
|
29
|
+
const value = line.slice(i + 1).trim();
|
|
30
|
+
if (key === "name")
|
|
31
|
+
data.name = value;
|
|
32
|
+
else if (key === "description")
|
|
33
|
+
data.description = value;
|
|
34
|
+
}
|
|
35
|
+
// El cuerpo empieza tras la línea de cierre.
|
|
36
|
+
const after = content.indexOf("\n", end + 1);
|
|
37
|
+
return { data, body: after === -1 ? "" : content.slice(after + 1) };
|
|
38
|
+
}
|
|
39
|
+
/** Ficheros del skill salvo el propio SKILL.md, en rutas relativas con `/`, ordenadas. */
|
|
40
|
+
export function listSkillFiles(dir, limit = Infinity) {
|
|
41
|
+
const out = [];
|
|
42
|
+
const walk = (current) => {
|
|
43
|
+
let entries;
|
|
44
|
+
try {
|
|
45
|
+
entries = readdirSync(current);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
for (const entry of entries.sort()) {
|
|
51
|
+
const full = join(current, entry);
|
|
52
|
+
if (statSync(full).isDirectory())
|
|
53
|
+
walk(full);
|
|
54
|
+
else if (full !== join(dir, "SKILL.md"))
|
|
55
|
+
out.push(relative(dir, full).split(sep).join("/"));
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
walk(dir);
|
|
59
|
+
return out.sort().slice(0, limit);
|
|
60
|
+
}
|
|
61
|
+
/** Lee un directorio de skill: frontmatter, cuerpo y ficheros. */
|
|
62
|
+
export function loadSkill(dir, fileLimit = Infinity) {
|
|
63
|
+
const raw = readFileSync(join(dir, "SKILL.md"), "utf-8");
|
|
64
|
+
const { data, body } = parseFrontmatter(raw);
|
|
65
|
+
const fallback = dir.replace(/[/\\]$/, "").split(/[/\\]/).pop() ?? "skill";
|
|
66
|
+
return {
|
|
67
|
+
name: data.name ?? fallback,
|
|
68
|
+
description: data.description ?? "",
|
|
69
|
+
content: body,
|
|
70
|
+
dir,
|
|
71
|
+
files: listSkillFiles(dir, fileLimit),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../../src/vendor/skillLoaders/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createMiddleware } from "langchain";
|
|
2
|
+
export function createTokenTracker() {
|
|
3
|
+
return { input: 0, output: 0, cache: 0, calls: 0, contexto: 0 };
|
|
4
|
+
}
|
|
5
|
+
export function createTokenTrackingMiddleware(tracker) {
|
|
6
|
+
return createMiddleware({
|
|
7
|
+
name: "TokenTrackingMiddleware",
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
afterModel: (state) => {
|
|
10
|
+
const messages = (state?.messages ?? []);
|
|
11
|
+
const lastMsg = messages[messages.length - 1];
|
|
12
|
+
if (!lastMsg)
|
|
13
|
+
return;
|
|
14
|
+
let inputTokens = 0;
|
|
15
|
+
let outputTokens = 0;
|
|
16
|
+
let cacheRead = 0;
|
|
17
|
+
// usage_metadata (LangChain standard)
|
|
18
|
+
const usage = lastMsg.usage_metadata;
|
|
19
|
+
if (usage) {
|
|
20
|
+
inputTokens = usage.input_tokens ?? 0;
|
|
21
|
+
outputTokens = usage.output_tokens ?? 0;
|
|
22
|
+
const inputDetails = usage.input_token_details;
|
|
23
|
+
cacheRead = inputDetails?.cache_read ?? 0;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
// Fallback: response_metadata.token_usage
|
|
27
|
+
const responseMeta = lastMsg.response_metadata;
|
|
28
|
+
const tokenUsage = responseMeta?.token_usage;
|
|
29
|
+
if (tokenUsage) {
|
|
30
|
+
inputTokens = tokenUsage.prompt_tokens ?? 0;
|
|
31
|
+
outputTokens = tokenUsage.completion_tokens ?? 0;
|
|
32
|
+
const details = tokenUsage.prompt_tokens_details;
|
|
33
|
+
cacheRead = details?.cached_tokens ?? 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
tracker.input += inputTokens;
|
|
37
|
+
tracker.output += outputTokens;
|
|
38
|
+
tracker.cache += cacheRead;
|
|
39
|
+
tracker.calls += 1;
|
|
40
|
+
tracker.contexto = inputTokens;
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export function printTokenUsage(tracker, latencyMs) {
|
|
45
|
+
console.log("\n=== Token Usage ===");
|
|
46
|
+
console.log(`Input tokens: ${tracker.input}`);
|
|
47
|
+
console.log(`Output tokens: ${tracker.output}`);
|
|
48
|
+
console.log(`Cache tokens: ${tracker.cache}`);
|
|
49
|
+
console.log(`LLM calls: ${tracker.calls}`);
|
|
50
|
+
if (latencyMs) {
|
|
51
|
+
const tps = latencyMs > 0 && tracker.output > 0
|
|
52
|
+
? (tracker.output / latencyMs) * 1000
|
|
53
|
+
: 0;
|
|
54
|
+
console.log(`Latency: ${latencyMs}ms`);
|
|
55
|
+
console.log(`Speed: ${tps.toFixed(1)} tok/s`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=tokenTracking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenTracking.js","sourceRoot":"","sources":["../../src/vendor/tokenTracking.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xonecode",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Consola CLI y harness de agente para desarrollar aplicaciones XOne",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"bin": {
|
|
8
|
+
"xonecode": "./dist/bin.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"skills",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=20"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && chmod +x dist/bin.js",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:watch": "vitest",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"xonecode": "tsx src/bin.ts"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@langchain/anthropic": "1.5.2",
|
|
27
|
+
"@langchain/core": "1.2.3",
|
|
28
|
+
"@langchain/google-genai": "2.2.0",
|
|
29
|
+
"@langchain/langgraph": "1.4.8",
|
|
30
|
+
"@langchain/ollama": "1.3.0",
|
|
31
|
+
"@langchain/openai": "1.5.5",
|
|
32
|
+
"deepagents": "1.12.0",
|
|
33
|
+
"langchain": "1.5.4"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^20.19.43",
|
|
37
|
+
"tsx": "^4.23.1",
|
|
38
|
+
"typescript": "^5.9.3",
|
|
39
|
+
"vitest": "^4.1.10"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: xone-debugging
|
|
3
|
+
description: Diagnóstico sistemático de errores y rendimiento en aplicaciones XOne. Usar al depurar pantallas vacías, botones que no responden, eventos que no disparan, colecciones sin datos, self null, errores -8100 y -11888, problemas de refresh o de persistencia MAP_, lentitud en listas, o al analizar un fallo con xone-simulator.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# XOne Debugging
|
|
7
|
+
|
|
8
|
+
Diagnostica por capas: reproduce, aísla, corrige y verifica. Antes de cambiar código, ejecuta el caso con `xone-simulator` y confirma el síntoma exacto. No propongas cambios a ciegas: formula una hipótesis comprobable y compruébala.
|
|
9
|
+
|
|
10
|
+
## Proceso
|
|
11
|
+
|
|
12
|
+
1. Reproduce el fallo.
|
|
13
|
+
2. Aísla la capa: XML/UI, evento JavaScript, colección o persistencia.
|
|
14
|
+
3. Busca el síntoma en las referencias.
|
|
15
|
+
4. Corrige con el patrón documentado.
|
|
16
|
+
5. Vuelve a validar y hacer smoke.
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
xone-simulator validate ./proyecto
|
|
20
|
+
xone-simulator run ./proyecto --coll MiColl --event before-edit
|
|
21
|
+
xone-simulator render ./proyecto --coll MiColl
|
|
22
|
+
xone-simulator smoke ./proyecto --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`--coll` acota, `--json` da salida estructurada y `--db-path` debe apuntar a una **copia** de la BD: el simulador puede mutarla. El validador detecta `ANTIPATTERN_LOAD_EVENT` y `ANTIPATTERN_MULTIPLE_BEFORE_EDIT`.
|
|
26
|
+
|
|
27
|
+
## Diagnóstico rápido
|
|
28
|
+
|
|
29
|
+
- **Pantalla vacía**: revisa `loadAll()`, `visible`, `unlock`, `ui.refresh()`, filtros `##FLD_CAMPO##`, que el `contents` del `prop type="Z"` coincida con el `<contents name>`, nombres duplicados en la coll, `special` junto a `sql`, y `newline="false"` en el primer elemento de un frame.
|
|
30
|
+
- **CSS que no se aplica**: comprueba primero `compatibility-mode` en el nodo `<app>` (regla en `xone-development`).
|
|
31
|
+
- **Botón mudo**: `visible`, `disableedit`, solapamientos, y que exista el handler de `onclick` o `method="ExecuteNode(nombre)"` (nunca los dos a la vez).
|
|
32
|
+
- **Evento que no dispara**: nombres exactos y case-sensitive, y errores JavaScript silenciosos.
|
|
33
|
+
- **`onchange` que no salta**: en `type="T"` ocurre al perder el foco; para cada tecla, `ontextchanged`. `onchange` acepta comandos (`refresh`, `refresh(MAP_CAMPO)`), no booleanos.
|
|
34
|
+
- **Refresh que no repinta**: usa el nombre exacto del `<prop>`. Tras `setFieldPropertyValue` hay que llamar a `ui.refresh(prop)`: no repinta solo. En callbacks, conserva `self` y comprueba `ui.getView(...)`.
|
|
35
|
+
- **Datos que no persisten**: los campos `MAP_` son transitorios y el framework los excluye de INSERT y UPDATE. Para guardar, usa un campo con columna.
|
|
36
|
+
- **Pantalla que no se inicializa**: la lógica está en `<load>`. Muévela a `<before-edit>`.
|
|
37
|
+
- **`-8100`**: falta un campo obligatorio.
|
|
38
|
+
- **`-11888`**: distingue `##EXIT##` de `##EXITAPP##` (regla en `xone-development`).
|
|
39
|
+
- **Lentitud**: trabajo pesado en `<load>`, `loadall="true"` en tablas grandes, refrescos dentro de bucles.
|
|
40
|
+
|
|
41
|
+
## Reglas
|
|
42
|
+
|
|
43
|
+
Las reglas de XOne detrás de estos síntomas viven en la skill `xone-development`. Aquí solo se diagnostica: para la forma correcta, consulta allí antes de aplicar una corrección.
|
|
44
|
+
|
|
45
|
+
## Referencias
|
|
46
|
+
|
|
47
|
+
| Para… | Lee |
|
|
48
|
+
|---|---|
|
|
49
|
+
| Preguntas frecuentes por área: general, XML/UI, JavaScript, CSS y estructura de proyecto | [references/faq.md](references/faq.md) |
|
|
50
|
+
| Troubleshooting completo por síntoma (incluye «`load` no inicializa la pantalla») y glosario de términos XOne | [references/troubleshooting-y-glosario.md](references/troubleshooting-y-glosario.md) |
|
|
51
|
+
|
|
52
|
+
Para las reglas y anti-patrones de cada capa, `xone-development`. Para el flujo completo de validación y auditoría, `xone-review`.
|