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
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El despachador. Cada comando expone `cmdX(...)` y se registra aquí.
|
|
3
|
+
*
|
|
4
|
+
* Sin librería de argumentos a propósito: hoy hay un comando y una bandera, y una
|
|
5
|
+
* dependencia más es una dependencia más que fijar y vigilar. Cuando haya cinco, se mete.
|
|
6
|
+
*/
|
|
7
|
+
import * as readline from "node:readline";
|
|
8
|
+
import { randomUUID } from "node:crypto";
|
|
9
|
+
import { basename } from "node:path";
|
|
10
|
+
import { cmdRun } from "./run.js";
|
|
11
|
+
import { cmdDescribe } from "./describe.js";
|
|
12
|
+
import { cmdConfig } from "./config.js";
|
|
13
|
+
import { cmdDoctor } from "./doctor.js";
|
|
14
|
+
import { cmdVerify } from "./verify.js";
|
|
15
|
+
import { ModeloMalEscrito, parsear, resolver } from "../core/modelos.js";
|
|
16
|
+
import { topeResuelto } from "../core/contextos.js";
|
|
17
|
+
import { cargar } from "../agent/configEnDisco.js";
|
|
18
|
+
import { COMANDOS, correrConsola, crearCompleter, } from "./consola.js";
|
|
19
|
+
import { crearLeerSecreto, crearPreguntar, crearPielStdio, escribirEnStdout } from "./stdio.js";
|
|
20
|
+
import { crearTema } from "./tema.js";
|
|
21
|
+
import { pedirDecisiones } from "./aprobar.js";
|
|
22
|
+
import { inspeccionar } from "../agent/entorno.js";
|
|
23
|
+
import { SkillsEnDisco } from "../agent/skills.js";
|
|
24
|
+
import { Modelos } from "../agent/modelos.js";
|
|
25
|
+
import { abrirSesionReal, ficherosDelProyecto } from "../agent/turnoReal.js";
|
|
26
|
+
import { crearProyecto } from "../agent/crearProyecto.js";
|
|
27
|
+
import { createTokenTracker } from "../vendor/tokenTracking.js";
|
|
28
|
+
/**
|
|
29
|
+
* Estilo, y solo con TTY detrás.
|
|
30
|
+
*
|
|
31
|
+
* Los códigos viven en `cli/tema.ts` — el único fichero con ANSI de todo `src/`,
|
|
32
|
+
* vigilado por `cli/tema.test.ts` — y este fichero pide SIGNIFICADO (`tema.mudo`),
|
|
33
|
+
* nunca color. Sin TTY el tema apagado lo convierte todo en cadena vacía, así que
|
|
34
|
+
* las tuberías y los logs de CI quedan limpios sin ramificar por aquí.
|
|
35
|
+
*/
|
|
36
|
+
const CON_COLOR = process.stdout.isTTY === true;
|
|
37
|
+
const tema = crearTema(CON_COLOR);
|
|
38
|
+
const DIM = tema.mudo;
|
|
39
|
+
const BOLD = tema.negrita;
|
|
40
|
+
const RESET = tema.reset;
|
|
41
|
+
/** El prompt. Se ve dónde acaba la respuesta y empieza lo que uno escribe. */
|
|
42
|
+
const PROMPT = CON_COLOR ? `${tema.prompt}❯${tema.reset} ` : "> ";
|
|
43
|
+
/**
|
|
44
|
+
* Envuelve las líneas de `readline` para pintar la barra y el prompt ANTES de cada una.
|
|
45
|
+
*
|
|
46
|
+
* Hace falta un envoltorio porque `readline.Interface` es un `AsyncIterable` que NO pinta
|
|
47
|
+
* el prompt por su cuenta al iterarlo: hay que llamar a `rl.prompt()` a mano, y el sitio
|
|
48
|
+
* correcto es justo antes de esperar cada línea. Iterándolo a pelo —como estaba— la consola
|
|
49
|
+
* no enseña nada y parece colgada.
|
|
50
|
+
*
|
|
51
|
+
* Sin TTY no se pinta ni barra ni prompt: en una tubería son ruido que ensucia la salida
|
|
52
|
+
* que alguien va a comparar o a parsear.
|
|
53
|
+
*/
|
|
54
|
+
async function* conPrompt(rl, escribir, barra) {
|
|
55
|
+
if (CON_COLOR) {
|
|
56
|
+
escribir(barra());
|
|
57
|
+
rl.prompt();
|
|
58
|
+
}
|
|
59
|
+
for await (const linea of rl) {
|
|
60
|
+
yield linea;
|
|
61
|
+
// Tras el turno o el comando, la barra vuelve a decir dónde estás: el modelo puede
|
|
62
|
+
// haber cambiado con /modelo y los tokens haber subido.
|
|
63
|
+
if (CON_COLOR) {
|
|
64
|
+
escribir(barra());
|
|
65
|
+
rl.prompt();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const AYUDA = `xonecode — harness de XOne
|
|
70
|
+
|
|
71
|
+
xonecode run "<peticion>" un turno, de un disparo (pipeable)
|
|
72
|
+
xonecode run --real "<peticion>" el agente real sobre el proyecto del cwd
|
|
73
|
+
xonecode describe qué hay montado y qué es de pega (sin red)
|
|
74
|
+
xonecode config qué config y credenciales cogería (sin claves)
|
|
75
|
+
xonecode config --json lo mismo, en JSON parseable
|
|
76
|
+
xonecode doctor ¿hay un proyecto aquí? ¿responde el simulador?
|
|
77
|
+
xonecode verify [ruta] valida el proyecto con xone-simulator (por omisión, aquí)
|
|
78
|
+
xonecode --guion la consola con el agente de pega, sin gastar
|
|
79
|
+
xonecode --help esto
|
|
80
|
+
|
|
81
|
+
Modelo:
|
|
82
|
+
--modelo <proveedor>/<modelo> fija los tres papeles
|
|
83
|
+
--modelo-rapido / --modelo-trabajo / --modelo-afilado <p>/<m> fija uno
|
|
84
|
+
XONECODE_MODELO=<p>/<m> por entorno
|
|
85
|
+
|
|
86
|
+
Proveedores: gemini, openai, anthropic, ollama
|
|
87
|
+
`;
|
|
88
|
+
/**
|
|
89
|
+
* Las banderas de modelo llevan valor suelto (`--modelo x`, no `--modelo=x`), y ese
|
|
90
|
+
* valor NO empieza por `--`: si no se quita aquí, el join de la petición en `run` lo
|
|
91
|
+
* comería como texto. Devuelve las fuentes ya resueltas y el argv SIN las banderas ni
|
|
92
|
+
* sus valores sueltos, para que `--lento` y el filtro de `--` sigan funcionando igual.
|
|
93
|
+
*/
|
|
94
|
+
export function extraerBanderasDeModelo(argv) {
|
|
95
|
+
let bandera;
|
|
96
|
+
const porPapel = {};
|
|
97
|
+
const resto = [];
|
|
98
|
+
/** Qué papel fija cada bandera específica. `undefined` = no es una de ellas. */
|
|
99
|
+
const papelDeBandera = (n) => n === "--modelo-rapido" ? "rapido" : n === "--modelo-trabajo" ? "trabajo" : n === "--modelo-afilado" ? "afilado" : undefined;
|
|
100
|
+
for (let i = 0; i < argv.length; i++) {
|
|
101
|
+
const a = argv[i];
|
|
102
|
+
const nombre = a.slice(0, a.indexOf("=") === -1 ? undefined : a.indexOf("="));
|
|
103
|
+
const valorConIgual = a.indexOf("=") === -1 ? undefined : a.slice(a.indexOf("=") + 1);
|
|
104
|
+
const papel = papelDeBandera(nombre);
|
|
105
|
+
if (nombre === "--modelo" || papel) {
|
|
106
|
+
if (valorConIgual !== undefined) {
|
|
107
|
+
// Forma con '=': el valor viene pegado a la bandera.
|
|
108
|
+
if (nombre === "--modelo")
|
|
109
|
+
bandera = valorConIgual;
|
|
110
|
+
else
|
|
111
|
+
porPapel[papel] = valorConIgual;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// Forma con espacio: el valor suelto siguiente se consume, sea o sea '--'.
|
|
115
|
+
const valor = argv[i + 1];
|
|
116
|
+
if (valor === undefined) {
|
|
117
|
+
throw new ModeloMalEscrito(`la bandera «${nombre}» necesita un valor <proveedor>/<modelo>`);
|
|
118
|
+
}
|
|
119
|
+
if (nombre === "--modelo")
|
|
120
|
+
bandera = valor;
|
|
121
|
+
else
|
|
122
|
+
porPapel[papel] = valor;
|
|
123
|
+
i++;
|
|
124
|
+
}
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
resto.push(a);
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
fuentes: { bandera, porPapel, entorno: { XONECODE_MODELO: process.env.XONECODE_MODELO } },
|
|
131
|
+
resto,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Token compacto para la línea de estado: `0 tokens` hasta 999, `12.8K tokens` a partir
|
|
136
|
+
* de 1000. Un decimal basta para un indicador de cabecera; la cifra exacta la da quien
|
|
137
|
+
* la necesita (printTokenUsage al final de los experimentos).
|
|
138
|
+
*/
|
|
139
|
+
function formatearTokens(total) {
|
|
140
|
+
return total < 1000 ? `${total} tokens` : `${(total / 1000).toFixed(1)}K tokens`;
|
|
141
|
+
}
|
|
142
|
+
/** El tope de contexto, compacto: `131K`, `200K`, `1M`. Sin decimales de cortesía. */
|
|
143
|
+
function formatearTope(tope) {
|
|
144
|
+
if (tope >= 1_000_000)
|
|
145
|
+
return `${tope / 1_000_000}M`;
|
|
146
|
+
return `${Math.round(tope / 1000)}K`;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* La barra de estado como función PURA: la compone quien tiene los valores y
|
|
150
|
+
* la pinta quien tiene el color. Así la barra se puede probar sin TTY — y es
|
|
151
|
+
* que solo se pinta con TTY, que es justo el caso que los tests no pueden ser.
|
|
152
|
+
*
|
|
153
|
+
* La sección `ctx` solo existe si hay algo que medir, y el porcentaje solo si
|
|
154
|
+
* hay tope: sin tope conocido, la cifra va pelada antes que calcular un
|
|
155
|
+
* porcentaje sobre un número inventado.
|
|
156
|
+
*/
|
|
157
|
+
export function formatearBarra(p) {
|
|
158
|
+
const ctx = p.contexto > 0
|
|
159
|
+
? ` · ctx ${formatearTokens(p.contexto).replace(" tokens", "")}` +
|
|
160
|
+
(p.tope !== undefined
|
|
161
|
+
? `/${formatearTope(p.tope)} (${Math.round((p.contexto / p.tope) * 100)}%)`
|
|
162
|
+
: "")
|
|
163
|
+
: "";
|
|
164
|
+
return `─ ${p.proyecto} (${p.colecciones} colls) · ${p.modelo} · ${formatearTokens(p.tokens)}${ctx} · /ayuda`;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* El ejecutor de turno REAL de la consola: cada línea de prosa corre sobre una `SesionReal`
|
|
168
|
+
* que sobrevive entre turnos (mismo agente, mismo hilo).
|
|
169
|
+
*
|
|
170
|
+
* La sesión se construye PEREZOSA, en el primer turno de prosa y no al arrancar
|
|
171
|
+
* `entrarEnConsola`, por dos razones:
|
|
172
|
+
* - El `Entorno` completo lo pide `inspeccionar` (el real de `agent/entorno.js`), no el
|
|
173
|
+
* doble `{colecciones}` de la cabecera, y abrir la sesión construye el grafo: hacerlo en
|
|
174
|
+
* el arranque gastaría en una consola que quizá solo se use para `/ayuda` o `/config`.
|
|
175
|
+
* - El detector de `/modelo` y `/nuevo` es la comparación de `estado` entre turnos: los
|
|
176
|
+
* manejadores de `consola.ts` no tocan la sesión (no la conocen), así que la única
|
|
177
|
+
* costura es el `estado` que este ejecutor recibe en cada llamada.
|
|
178
|
+
*
|
|
179
|
+
* `alAbrirSesion` se llama UNA vez, justo tras `abrirSesionReal`, y es la costura por la
|
|
180
|
+
* que `entrarEnConsola` apunta la barra de estado al tracker de la sesión (que alimenta
|
|
181
|
+
* el agente; el de `createTokenTracker()` de cabecera se descarta al reasignarse).
|
|
182
|
+
*/
|
|
183
|
+
function crearEjecutorReal(alAbrirSesion) {
|
|
184
|
+
let sesion;
|
|
185
|
+
let fuentesVistas;
|
|
186
|
+
let hiloVisto;
|
|
187
|
+
return async (peticion, estado, consolaReal) => {
|
|
188
|
+
if (sesion === undefined) {
|
|
189
|
+
// Mismo diagnóstico y mismas frases que `run --real`: no se construye NADA sobre un
|
|
190
|
+
// sitio que no es un proyecto XOne, y la consola sigue viva para otros comandos.
|
|
191
|
+
const entorno = await inspeccionar(estado.raiz);
|
|
192
|
+
if (!entorno.esProyectoXone) {
|
|
193
|
+
consolaReal.escribir(`${entorno.raiz} (no hay app.xml aquí)\n`);
|
|
194
|
+
consolaReal.escribir("✗ falta algo imprescindible: xonecode no puede trabajar aquí.\n");
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
sesion = await abrirSesionReal({
|
|
198
|
+
raiz: estado.raiz,
|
|
199
|
+
modelos: new Modelos(estado.fuentes),
|
|
200
|
+
skills: new SkillsEnDisco(),
|
|
201
|
+
entorno,
|
|
202
|
+
// Las aprobaciones entran por el `preguntar` de la propia consola: el turno para
|
|
203
|
+
// y pregunta DENTRO de la sesión, sin salir de ella ni montar otro lector de stdin.
|
|
204
|
+
pedirAprobacion: (lista, ficheros, diffs) => pedirDecisiones(lista, consolaReal.preguntar, consolaReal.escribir, {
|
|
205
|
+
interactive: consolaReal.interactivo,
|
|
206
|
+
fichero: (id) => ficheros.get(id),
|
|
207
|
+
diff: (id) => diffs.get(id),
|
|
208
|
+
}),
|
|
209
|
+
});
|
|
210
|
+
alAbrirSesion(sesion);
|
|
211
|
+
// Recién construida: no hay cambio que detectar en esta primera vuelta.
|
|
212
|
+
fuentesVistas = estado.fuentes;
|
|
213
|
+
hiloVisto = estado.hilo;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
// `/modelo` solo actualizó `estado.fuentes`; aquí es donde deja de ser un cambio
|
|
217
|
+
// cosmético: el agente se reconstruye con el modelo nuevo y el hilo SE CONSERVA.
|
|
218
|
+
if (JSON.stringify(estado.fuentes) !== JSON.stringify(fuentesVistas)) {
|
|
219
|
+
await sesion.cambiarModelos(new Modelos(estado.fuentes));
|
|
220
|
+
consolaReal.escribir(" (agente reconstruido con el modelo nuevo — el hilo se conserva)\n");
|
|
221
|
+
fuentesVistas = estado.fuentes;
|
|
222
|
+
}
|
|
223
|
+
// `/nuevo` generó su propio UUID, que no coincide con el hilo interno de la sesión:
|
|
224
|
+
// lo que importa es que CAMBIÓ, y se abre uno nuevo. El aviso ya lo imprimió el
|
|
225
|
+
// manejador de consola.ts.
|
|
226
|
+
if (estado.hilo !== hiloVisto) {
|
|
227
|
+
// **Se le pasa el id de la consola.** Sin esto había DOS ids para un mismo hilo —
|
|
228
|
+
// el de la consola y el que generaba la sesión— y `/hilo` enseñaba el que NO usaba
|
|
229
|
+
// el grafo. Un identificador que no identifica es peor que no darlo.
|
|
230
|
+
sesion.nuevoHilo(estado.hilo);
|
|
231
|
+
hiloVisto = estado.hilo;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
await sesion.turno(peticion, crearPielStdio(consolaReal.escribir));
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* La sesión interactiva: `xonecode` a secas.
|
|
239
|
+
*
|
|
240
|
+
* Mismo patrón de inyección que `cmdDescribe(fuentes, escribir, raiz)`: todo lo que toca
|
|
241
|
+
* el exterior (cwd, stdout, el proceso del simulador dentro de `inspeccionar`, y el
|
|
242
|
+
* propio stdin a través de readline) entra como parámetro con su valor de producción por
|
|
243
|
+
* omisión, así el test la recorre entera sin TTY ni procesos externos.
|
|
244
|
+
*
|
|
245
|
+
* Devuelve el código de salida, que es el que devuelva `correrConsola` (0 tanto por
|
|
246
|
+
* `/salir` como por EOF).
|
|
247
|
+
*/
|
|
248
|
+
/** ¿La respuesta a una pregunta sí/no es SÍ? Enter a secas y cualquier otra cosa: NO. */
|
|
249
|
+
function esSi(respuesta) {
|
|
250
|
+
return ["s", "si", "y", "yes"].includes(respuesta.trim().toLowerCase());
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* El asistente de creación de proyecto: cuatro preguntas y el esqueleto en disco.
|
|
254
|
+
*
|
|
255
|
+
* La oferta inicial es sí/no con **omisión No**, como las aprobaciones: crear
|
|
256
|
+
* ficheros en la carpeta del usuario es opt-in, y quien no ha entendido la
|
|
257
|
+
* pregunta no ha pedido nada. Lo que se escribe es `core/esqueleto.ts` (el
|
|
258
|
+
* «Hola Mundo» de la documentación XOne, nada inventado), a través de
|
|
259
|
+
* `agent/crearProyecto.ts`, que no pisa lo que ya exista.
|
|
260
|
+
*/
|
|
261
|
+
async function ofrecerCrearProyecto(raiz, consola) {
|
|
262
|
+
const respuesta = await consola.preguntar("¿Creo un proyecto XOne aquí? (s/N) ");
|
|
263
|
+
if (!esSi(respuesta))
|
|
264
|
+
return false;
|
|
265
|
+
const datos = await preguntarDatos(consola);
|
|
266
|
+
const informe = crearProyecto(raiz, datos);
|
|
267
|
+
consola.escribir(`✓ proyecto creado: ${informe.creados.length} ficheros` +
|
|
268
|
+
`${informe.saltados.length > 0 ? ` (${informe.saltados.length} existentes no tocados: ${informe.saltados.join(", ")})` : ""}\n`);
|
|
269
|
+
// Las carpetas del runtime van VACÍAS a propósito, y eso hay que decirlo: quien
|
|
270
|
+
// no sepa que el .db lo genera el simulador pensará que falta algo.
|
|
271
|
+
consola.escribir(" (bd/, icons/ y files/ están vacías: la base de datos la genera el simulador y los iconos se añaden a mano)\n");
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
/** Las cuatro preguntas, cada una re-preguntada hasta que la respuesta sirva. */
|
|
275
|
+
async function preguntarDatos(consola) {
|
|
276
|
+
// El nombre interno no admite espacios (es `Name=` del app.ini y el prefijo de
|
|
277
|
+
// las clases de pantallas): re-preguntar, no «arreglarlo» por debajo.
|
|
278
|
+
let nombre = "";
|
|
279
|
+
for (;;) {
|
|
280
|
+
nombre = (await consola.preguntar("Nombre interno de la app (sin espacios): ")).trim();
|
|
281
|
+
if (nombre.length > 0 && !/\s/.test(nombre))
|
|
282
|
+
break;
|
|
283
|
+
consola.escribir(" (sin espacios y no vacío)\n");
|
|
284
|
+
}
|
|
285
|
+
const titulo = (await consola.preguntar(`Título visible [${nombre}]: `)).trim() || nombre;
|
|
286
|
+
let orientacion = "portrait";
|
|
287
|
+
for (;;) {
|
|
288
|
+
const respuesta = (await consola.preguntar("Orientación (portrait/landscape) [portrait]: "))
|
|
289
|
+
.trim()
|
|
290
|
+
.toLowerCase();
|
|
291
|
+
if (respuesta === "")
|
|
292
|
+
break;
|
|
293
|
+
if (respuesta === "portrait" || respuesta === "landscape") {
|
|
294
|
+
orientacion = respuesta;
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
consola.escribir(" (portrait o landscape)\n");
|
|
298
|
+
}
|
|
299
|
+
const login = esSi(await consola.preguntar("¿La app lleva login? (s/N) "));
|
|
300
|
+
return { nombre, titulo, orientacion, login };
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* El completer que monta la consola: comandos Y, tras una «@», ficheros del proyecto.
|
|
304
|
+
*
|
|
305
|
+
* Los ficheros se piden en el momento del Tab (`() => ficherosDelProyecto(raiz)`, no la
|
|
306
|
+
* lista ya hecha): el completer se construye una sola vez al arrancar el rl y la lista
|
|
307
|
+
* quedaría congelada en el primer instante de la sesión.
|
|
308
|
+
*/
|
|
309
|
+
export function crearCompleterDelProyecto(raiz, escribir = escribirEnStdout) {
|
|
310
|
+
return crearCompleter(escribir, () => ficherosDelProyecto(raiz));
|
|
311
|
+
}
|
|
312
|
+
export async function entrarEnConsola(fuentes, raiz = process.cwd(), escribir = escribirEnStdout, inspeccionarProyecto = inspeccionar, crearRl = () => readline.createInterface({
|
|
313
|
+
input: process.stdin,
|
|
314
|
+
output: process.stdout,
|
|
315
|
+
terminal: process.stdin.isTTY === true,
|
|
316
|
+
completer: crearCompleterDelProyecto(raiz),
|
|
317
|
+
// **El prompt.** Sin él la consola es un cursor pelado: no se sabe que espera, ni
|
|
318
|
+
// dónde acaba la respuesta y empieza lo que uno escribió. `readline` no lo pinta si
|
|
319
|
+
// no se le da uno Y se llama a `rl.prompt()` — las dos cosas hacen falta.
|
|
320
|
+
prompt: PROMPT,
|
|
321
|
+
}), guion = false,
|
|
322
|
+
/** Costura de test del «¿hay alguien al otro lado?»: sin TTY no se pregunta nada. */
|
|
323
|
+
interactivo = process.stdin.isTTY === true) {
|
|
324
|
+
// `let` porque el asistente de creación puede cambiarlo TODO: si el usuario acepta,
|
|
325
|
+
// la carpeta pasa de «0 colls, sin app.xml» a proyecto de verdad, y la cabecera se
|
|
326
|
+
// re-inspecciona para no mentir en la primera línea que se ve.
|
|
327
|
+
let entorno = await inspeccionarProyecto(raiz);
|
|
328
|
+
// El papel `trabajo` es el que representa a la sesión. Sin el sufijo `(origen)` que
|
|
329
|
+
// añade `Modelos.descripcion()`: la cabecera es breve y la procedencia se puede ver
|
|
330
|
+
// con /describe. `let` porque /modelo <p>/<m> la cambia EN CALIENTE dentro de la sesión.
|
|
331
|
+
let modeloTrabajo;
|
|
332
|
+
{
|
|
333
|
+
const { proveedor, modelo } = resolver(fuentes).trabajo;
|
|
334
|
+
modeloTrabajo = `${proveedor}/${modelo}`;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Los tokens acumulados de la sesión. Con `--guion` se queda en 0 a propósito: el turno
|
|
338
|
+
* guionizado no corre ningún modelo. Sin ella, la sesión real se construye PEREZOSA (al
|
|
339
|
+
* primer turno de prosa) y entonces esta variable se REASIGNA al tracker de la sesión —
|
|
340
|
+
* `let` y no `const` por eso: `barraDeEstado` y `cabecera` leen la variable en cada
|
|
341
|
+
* llamada (no una copia congelada), así que empiezan a leer del tracker real en cuanto
|
|
342
|
+
* la sesión existe. Lo que importa es que el OBJETO no se copia: el agente sigue
|
|
343
|
+
* alimentando ese mismo tracker, y la barra lo refleja sin tocar nada más.
|
|
344
|
+
*/
|
|
345
|
+
let tracker = createTokenTracker();
|
|
346
|
+
// Las dos líneas de cabecera, construidas por una función porque se emiten DOS veces:
|
|
347
|
+
// al arrancar y tras cada /nuevo o /modelo. La lista de comandos se GENERA recorriendo
|
|
348
|
+
// el registro — una lista escrita a mano se queda vieja en cuanto alguien añade uno.
|
|
349
|
+
/**
|
|
350
|
+
* El tope de la ventana del modelo ACTUAL: tabla de `core/contextos.ts` + lo que el
|
|
351
|
+
* usuario haya fijado en `config.json` (lo de proyecto gana a lo global, como los
|
|
352
|
+
* modelos). Se lee en cada barra y no en el arranque porque `modeloTrabajo` cambia
|
|
353
|
+
* en caliente con /modelo, y un tope del modelo equivocado es un porcentaje que miente.
|
|
354
|
+
* Si el id no parsea —no debería, viene de `resolver`—, no hay tope y no pasa nada.
|
|
355
|
+
*/
|
|
356
|
+
const topeDelModelo = (id) => {
|
|
357
|
+
try {
|
|
358
|
+
const { proveedor, modelo } = parsear(id);
|
|
359
|
+
const { config } = cargar(raiz);
|
|
360
|
+
// Misma resolución que /config (`topeResuelto`): proyecto gana a global, y la
|
|
361
|
+
// tabla es el último recurso. El origen aquí no se mira, pero así no puede
|
|
362
|
+
// divergir entre lo que la barra calcula y lo que /config declara.
|
|
363
|
+
return topeResuelto(proveedor, modelo, {
|
|
364
|
+
proyecto: config.proyecto?.contextos,
|
|
365
|
+
global: config.global?.contextos,
|
|
366
|
+
})?.tope;
|
|
367
|
+
}
|
|
368
|
+
catch {
|
|
369
|
+
return undefined;
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
/**
|
|
373
|
+
* La barra de estado, al estilo de la de opencode: lo que uno necesita tener delante sin
|
|
374
|
+
* pedirlo. En stdio no se puede clavar al fondo de la pantalla —eso pide control de
|
|
375
|
+
* cursor, y es lo que trae la TUI de Ink— así que se emite ANTES de cada prompt, que es
|
|
376
|
+
* el sitio donde de verdad se mira.
|
|
377
|
+
*
|
|
378
|
+
* Lleva el modelo porque es lo que uno olvida haber cambiado, el proyecto porque la
|
|
379
|
+
* consola se lanza desde donde toque y equivocarse de carpeta es fácil, los tokens
|
|
380
|
+
* porque es el coste acumulándose, y el contexto porque es el margen que va
|
|
381
|
+
* consumiéndose — la cifra que dice si toca resumir el hilo.
|
|
382
|
+
*/
|
|
383
|
+
const barraDeEstado = () => `${DIM}${formatearBarra({
|
|
384
|
+
proyecto: basename(raiz),
|
|
385
|
+
colecciones: entorno.colecciones,
|
|
386
|
+
modelo: modeloTrabajo,
|
|
387
|
+
tokens: tracker.input + tracker.output,
|
|
388
|
+
contexto: tracker.contexto,
|
|
389
|
+
tope: topeDelModelo(modeloTrabajo),
|
|
390
|
+
})}${RESET}\n`;
|
|
391
|
+
/** La cabecera larga: solo al arrancar y tras /nuevo o /modelo, nunca por turno. */
|
|
392
|
+
const cabecera = () => {
|
|
393
|
+
const comandos = Object.keys(COMANDOS)
|
|
394
|
+
.map((nombre) => `/${nombre}`)
|
|
395
|
+
.join(" ");
|
|
396
|
+
return (`${BOLD}xonecode${RESET} · ${basename(raiz)} (${entorno.colecciones} colls) · ${modeloTrabajo} · ` +
|
|
397
|
+
`${formatearTokens(tracker.input + tracker.output)}\n` +
|
|
398
|
+
`${DIM}${Object.keys(COMANDOS).length} comandos: ${comandos}${RESET}\n`);
|
|
399
|
+
};
|
|
400
|
+
const lineaDeEstado = cabecera; // el nombre que ya usan los tests
|
|
401
|
+
// El rl y la consola se crean ANTES de la cabecera: si la carpeta no es un proyecto
|
|
402
|
+
// XOne, la oferta de crearlo se pregunta aquí mismo, y para preguntar hace falta
|
|
403
|
+
// el `preguntar` de la consola (que comparte este rl con el lazo de líneas).
|
|
404
|
+
const rl = crearRl();
|
|
405
|
+
const consola = {
|
|
406
|
+
// Envuelto para que pinte la barra de estado y el prompt antes de cada línea. Ver
|
|
407
|
+
// `conPrompt`: `readline` no pinta el prompt solo al iterarlo como AsyncIterable.
|
|
408
|
+
lineas: conPrompt(rl, escribir, barraDeEstado),
|
|
409
|
+
escribir: (t) => {
|
|
410
|
+
escribir(t);
|
|
411
|
+
// La línea de estado se reimprime tras /nuevo y /modelo (los DOS, no
|
|
412
|
+
// /modelo-rapido/-trabajo/-afilado: así lo pide la tarea). Ambos manejadores
|
|
413
|
+
// escriben su resultado en UNA sola llamada a escribir, así que basta con anclar
|
|
414
|
+
// al principio de esa cadena exacta:
|
|
415
|
+
// "modelo (los tres papeles): <p>/<m>\n" → /modelo
|
|
416
|
+
// "hilo nuevo: <id>\n" → /nuevo
|
|
417
|
+
const comoModelo = /^modelo \(los tres papeles\): (.+)\n$/.exec(t);
|
|
418
|
+
if (comoModelo) {
|
|
419
|
+
modeloTrabajo = comoModelo[1];
|
|
420
|
+
escribir(lineaDeEstado());
|
|
421
|
+
}
|
|
422
|
+
else if (/^hilo nuevo: /.test(t)) {
|
|
423
|
+
escribir(lineaDeEstado());
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
preguntar: crearPreguntar(rl),
|
|
427
|
+
interactivo,
|
|
428
|
+
leerSecreto: crearLeerSecreto(rl),
|
|
429
|
+
};
|
|
430
|
+
// El asistente de creación: la única escritura fuera de un turno del agente, y
|
|
431
|
+
// por eso la única que pregunta ANTES de escribir. Si se crea, la carpeta ya ES
|
|
432
|
+
// un proyecto XOne y `entorno` se re-inspecciona; si no, la consola sigue viva
|
|
433
|
+
// para /config, /doctor o lo que haga falta (el control del primer turno de
|
|
434
|
+
// prosa sigue ahí como red de seguridad).
|
|
435
|
+
if (!entorno.esProyectoXone) {
|
|
436
|
+
consola.escribir(`✗ ${basename(raiz)} no es un proyecto XOne (falta app.xml)\n`);
|
|
437
|
+
if (interactivo && (await ofrecerCrearProyecto(raiz, consola))) {
|
|
438
|
+
entorno = await inspeccionarProyecto(raiz);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
escribir(cabecera());
|
|
442
|
+
// Mismo patrón de prefijo que run.ts y el manejador /nuevo de consola.ts.
|
|
443
|
+
const estado = { hilo: `xonecode-${randomUUID()}`, raiz, fuentes };
|
|
444
|
+
// `--guion` conserva el agente de pega (el valor por omisión de `correrConsola`): es lo
|
|
445
|
+
// que permite ver la consola correr sin gastar. Sin ella, el ejecutor real corre cada
|
|
446
|
+
// línea de prosa sobre una sesión que se abre en el PRIMER turno y sobrevive a los demás.
|
|
447
|
+
const ejecutar = guion
|
|
448
|
+
? undefined
|
|
449
|
+
: crearEjecutorReal((sesion) => {
|
|
450
|
+
tracker = sesion.tracker;
|
|
451
|
+
});
|
|
452
|
+
const codigo = await correrConsola(consola, estado, ejecutar);
|
|
453
|
+
// Siempre, tanto si se sale por /salir como por EOF: sin rl.close() el proceso queda
|
|
454
|
+
// escuchando stdin y `xonecode` no vuelve nunca a la shell.
|
|
455
|
+
rl.close();
|
|
456
|
+
return codigo;
|
|
457
|
+
}
|
|
458
|
+
export async function main(argv) {
|
|
459
|
+
const [comando, ...resto] = argv;
|
|
460
|
+
// Las banderas de la consola (`--guion` y las de modelo) no son subcomandos:
|
|
461
|
+
// `xonecode --guion` entra en la consola igual que `xonecode` a secas, pero con el
|
|
462
|
+
// agente de pega. `--help`/`-h` NO entran aquí: son el subcomando de ayuda de abajo.
|
|
463
|
+
// El resto de banderas (`--real`, `--json`, …) pertenecen a otros subcomandos y siguen
|
|
464
|
+
// cayendo en «no conozco el comando».
|
|
465
|
+
// `--guion` se quita del argv ANTES de extraerBanderasDeModelo: no es una bandera de
|
|
466
|
+
// modelo y no debe llegar como `resto` a ninguna parte.
|
|
467
|
+
if (!comando || comando === "--guion" || comando.startsWith("--modelo")) {
|
|
468
|
+
const guion = argv.includes("--guion");
|
|
469
|
+
// extraerBanderasDeModelo también con argv vacío, para que fuentes.entorno
|
|
470
|
+
// .XONECODE_MODELO se rellene igual que en todos los demás subcomandos: la consola
|
|
471
|
+
// no puede ser la única vía que ignora esa variable.
|
|
472
|
+
const { fuentes } = extraerBanderasDeModelo(argv.filter((a) => a !== "--guion"));
|
|
473
|
+
return entrarEnConsola(fuentes, undefined, undefined, undefined, undefined, guion);
|
|
474
|
+
}
|
|
475
|
+
if (comando === "--help" || comando === "-h") {
|
|
476
|
+
process.stdout.write(AYUDA);
|
|
477
|
+
return 0;
|
|
478
|
+
}
|
|
479
|
+
try {
|
|
480
|
+
if (comando === "run") {
|
|
481
|
+
const { fuentes, resto: sinModelo } = extraerBanderasDeModelo(resto);
|
|
482
|
+
const peticion = sinModelo.filter((a) => !a.startsWith("--")).join(" ");
|
|
483
|
+
if (!peticion) {
|
|
484
|
+
process.stderr.write("run necesita una petición: xonecode run \"...\"\n");
|
|
485
|
+
return 64; // EX_USAGE
|
|
486
|
+
}
|
|
487
|
+
const lento = sinModelo.includes("--lento");
|
|
488
|
+
const real = sinModelo.includes("--real");
|
|
489
|
+
return cmdRun({ peticion, retardoMs: lento ? 120 : 0, real, fuentes });
|
|
490
|
+
}
|
|
491
|
+
if (comando === "describe") {
|
|
492
|
+
const { fuentes } = extraerBanderasDeModelo(resto);
|
|
493
|
+
return cmdDescribe(fuentes);
|
|
494
|
+
}
|
|
495
|
+
if (comando === "config") {
|
|
496
|
+
const { fuentes, resto: sinModelo } = extraerBanderasDeModelo(resto);
|
|
497
|
+
const json = sinModelo.includes("--json");
|
|
498
|
+
return cmdConfig(fuentes, { json });
|
|
499
|
+
}
|
|
500
|
+
if (comando === "doctor") {
|
|
501
|
+
return await cmdDoctor();
|
|
502
|
+
}
|
|
503
|
+
if (comando === "verify") {
|
|
504
|
+
const ruta = resto.filter((a) => !a.startsWith("--"))[0] ?? process.cwd();
|
|
505
|
+
return await cmdVerify(ruta);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
catch (e) {
|
|
509
|
+
// Un modelo mal escrito es un error del USUARIO, no del harness: su mensaje, sin
|
|
510
|
+
// traza, y código de uso (64). No se propaga como un fallo de software.
|
|
511
|
+
if (e instanceof ModeloMalEscrito) {
|
|
512
|
+
process.stderr.write(`${e.message}\n`);
|
|
513
|
+
return 64; // EX_USAGE
|
|
514
|
+
}
|
|
515
|
+
throw e;
|
|
516
|
+
}
|
|
517
|
+
process.stderr.write(`no conozco el comando «${comando}». xonecode --help\n`);
|
|
518
|
+
return 64;
|
|
519
|
+
}
|
|
520
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El markdown del asistente, pintado en una consola que NO repinta.
|
|
3
|
+
*
|
|
4
|
+
* Esa es la regla que gobierna todo el módulo: **lo escrito, escrito está**. Una línea
|
|
5
|
+
* solo se puede renderizar cuando su texto es definitivo, y un párrafo largo que llega
|
|
6
|
+
* en trozos solo se puede cortar por donde el corte no rompa un marcador — de ahí
|
|
7
|
+
* `puntoSeguro`. No hay reflow posible: el historial vive en el scrollback del
|
|
8
|
+
* terminal, que no es direccionable.
|
|
9
|
+
*
|
|
10
|
+
* Se pinta lo que los modelos EMITEN de verdad (medido): negritas, `código` en línea,
|
|
11
|
+
* cabeceras, viñetas y cercos ```. Lo que no empareja queda literal — inventarse un
|
|
12
|
+
* cierre sería un bug mudo delante del usuario.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Los marcadores EN LÍNEA: `**negrita**` y `` `código` ``.
|
|
16
|
+
*
|
|
17
|
+
* Puro: recibe el tema y devuelve la línea lista para escribir. Con un tema sin color
|
|
18
|
+
* (pipe, CI) los tokens son cadena vacía y la salida queda limpia.
|
|
19
|
+
*/
|
|
20
|
+
export function renderizarInline(texto, tema) {
|
|
21
|
+
// **Sin color no se despinta el markdown.** Los marcadores son la única pista del
|
|
22
|
+
// énfasis que le queda a un pipe o a un CI que lea esta salida; quitárselos es
|
|
23
|
+
// quitarle información y no darle nada a cambio.
|
|
24
|
+
if (tema.negrita === "" && tema.mudo === "")
|
|
25
|
+
return texto;
|
|
26
|
+
return texto
|
|
27
|
+
.replace(/\*\*([^*\n]+)\*\*/g, (_, t) => `${tema.negrita}${t}${tema.reset}`)
|
|
28
|
+
.replace(/`([^`\n]+)`/g, (_, t) => `${tema.mudo}${t}${tema.reset}`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Por dónde cortar un párrafo que llega en trozos y aún no ha visto su `\n`.
|
|
32
|
+
*
|
|
33
|
+
* El streaming tiene que verse (un colchón que solo se suelta al final es un `ainvoke`
|
|
34
|
+
* disfrazado), pero cortar por donde sea rompe marcadores: un `**` partido entre dos
|
|
35
|
+
* escrituras queda literal para siempre. Así que el corte es en un ESPACIO, con los
|
|
36
|
+
* pares `**` y `` ` `` CERRADOS en lo escrito. Se devuelve el ÚLTIMO corte seguro
|
|
37
|
+
* (menos escrituras), y `undefined` si no hay ninguno — entonces se espera.
|
|
38
|
+
*/
|
|
39
|
+
export function puntoSeguro(colchon, minimo) {
|
|
40
|
+
let corte;
|
|
41
|
+
for (let i = minimo; i <= colchon.length; i++) {
|
|
42
|
+
if (colchon[i - 1] !== " ")
|
|
43
|
+
continue;
|
|
44
|
+
const prefijo = colchon.slice(0, i);
|
|
45
|
+
if (prefijo.split("**").length % 2 !== 1)
|
|
46
|
+
continue; // una negrita abierta
|
|
47
|
+
if (prefijo.split("`").length % 2 !== 1)
|
|
48
|
+
continue; // un código abierto
|
|
49
|
+
corte = i;
|
|
50
|
+
}
|
|
51
|
+
return corte;
|
|
52
|
+
}
|
|
53
|
+
/** El estado de bloque que sobrevive entre líneas: solo el cerco de código. */
|
|
54
|
+
export class RenderizadorDeMarkdown {
|
|
55
|
+
tema;
|
|
56
|
+
enCerco = false;
|
|
57
|
+
constructor(tema) {
|
|
58
|
+
this.tema = tema;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Una línea (o un corte de párrafo) tal como llega del flujo, SIN su `\n`.
|
|
62
|
+
*
|
|
63
|
+
* `inicioDeLinea` dice si este trozo empieza línea de verdad: una continuación de
|
|
64
|
+
* párrafo no puede ser cabecera ni viñeta, aunque empiece por «##» o «- ».
|
|
65
|
+
*
|
|
66
|
+
* **Sin color (pipe, CI), la línea sale tal cual**: no se quitan «##», ni «- » se
|
|
67
|
+
* vuelve «•», ni el cerco desaparece. Despintar el markdown sin dar nada a cambio
|
|
68
|
+
* es quitarle información a quien lee la salida.
|
|
69
|
+
*/
|
|
70
|
+
linea(texto, inicioDeLinea = true) {
|
|
71
|
+
if (this.tema.negrita === "" && this.tema.mudo === "")
|
|
72
|
+
return texto;
|
|
73
|
+
if (texto.trimStart().startsWith("```")) {
|
|
74
|
+
this.enCerco = !this.enCerco;
|
|
75
|
+
return ""; // el cerco es ruido del formato: no se pinta
|
|
76
|
+
}
|
|
77
|
+
if (this.enCerco)
|
|
78
|
+
return `${this.tema.mudo}${texto}${this.tema.reset}`;
|
|
79
|
+
if (inicioDeLinea) {
|
|
80
|
+
const cabecera = /^(#{1,3})\s+(.*)$/.exec(texto.trim());
|
|
81
|
+
if (cabecera)
|
|
82
|
+
return `${this.tema.negrita}${cabecera[2]}${this.tema.reset}`;
|
|
83
|
+
const vineta = /^[-*]\s+(.*)$/.exec(texto.trim());
|
|
84
|
+
if (vineta)
|
|
85
|
+
return `• ${vineta[1]}`;
|
|
86
|
+
}
|
|
87
|
+
return renderizarInline(texto, this.tema);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/cli/markdown.ts"],"names":[],"mappings":"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"}
|