chocolatito-code 1.4.3 → 1.5.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/dist/index.js +6 -0
- package/dist/ui/historial.d.ts +49 -0
- package/dist/ui/historial.js +92 -0
- package/dist/ui/ink/Prompt.js +55 -15
- package/dist/ui/pantalla.d.ts +19 -0
- package/dist/ui/pantalla.js +84 -0
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { codigoDeSalida, EXIT_OK, EXIT_FALLO, EXIT_USO, EXIT_LICENCIA } from "./
|
|
|
15
15
|
import { showBanner, animateStartupBanner, showHelp, showEffortMenu } from "./ui/banner.js";
|
|
16
16
|
import { fijarMotor } from "./ui/motorActual.js";
|
|
17
17
|
import { elegirDeLista } from "./ui/selector.js";
|
|
18
|
+
import { entrarEnPantallaFija, pantallaFijaPedida } from "./ui/pantalla.js";
|
|
18
19
|
import { reafirmarModoCrudo } from "./ui/keyboardGuard.js";
|
|
19
20
|
import { askInteractivePrompt, SLASH_COMMANDS } from "./ui/prompt.js";
|
|
20
21
|
import { changeDir } from "./tools/changeDir.js";
|
|
@@ -235,6 +236,11 @@ ${nodeViejo}
|
|
|
235
236
|
const hookManager = new HookManager(context.cwd);
|
|
236
237
|
const sessionManager = new SessionManager();
|
|
237
238
|
const sessionId = `session_${Date.now()}`;
|
|
239
|
+
// La barra de abajo solo puede quedarse clavada si el programa toma la
|
|
240
|
+
// pantalla entera. Se pide con CHOCOLATITO_PANTALLA=fija y se paga con el
|
|
241
|
+
// historial del terminal: ver ui/pantalla.ts.
|
|
242
|
+
if (pantallaFijaPedida())
|
|
243
|
+
entrarEnPantallaFija();
|
|
238
244
|
let currentModel = DEFAULT_ESPECTRO;
|
|
239
245
|
// La barra de estado lo lee de aqui. Fijarlo al arrancar y no solo al
|
|
240
246
|
// cambiarlo: si no, hasta el primer /effort la barra no dice nada.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LO QUE HA SALIDO POR PANTALLA, GUARDADO EN MEMORIA
|
|
3
|
+
*
|
|
4
|
+
* POR QUE HACE FALTA
|
|
5
|
+
*
|
|
6
|
+
* En la pantalla normal el historial lo lleva el terminal: sale una línea, se va
|
|
7
|
+
* hacia arriba, y la rueda del ratón la recupera. Por eso la barra de abajo sube
|
|
8
|
+
* con el scroll: es una línea más del historial, no una capa encima.
|
|
9
|
+
*
|
|
10
|
+
* En la pantalla alternativa —la que usan vim o htop— el terminal NO guarda
|
|
11
|
+
* nada. A cambio, la barra se queda clavada de verdad. Pero si nadie recuerda lo
|
|
12
|
+
* que salió, la conversación desaparece en cuanto pasa de una pantalla, que sería
|
|
13
|
+
* mucho peor que el problema que se quiere resolver.
|
|
14
|
+
*
|
|
15
|
+
* Así que aquí se guarda. Es el precio de tener la barra fija: el historial deja
|
|
16
|
+
* de ser del terminal y pasa a ser nuestro.
|
|
17
|
+
*
|
|
18
|
+
* POR QUE SE GUARDA POR LÍNEAS Y NO EL FLUJO CRUDO
|
|
19
|
+
*
|
|
20
|
+
* Lo que llega trae códigos de color y a veces medio renglón sin terminar. Para
|
|
21
|
+
* poder pintar "las últimas N líneas" hay que saber dónde acaba cada una, así
|
|
22
|
+
* que se parte por saltos y el resto sin terminar se queda esperando al suyo.
|
|
23
|
+
* Los colores se conservan tal cual: recortarlos aquí sería pintar la
|
|
24
|
+
* conversación en gris.
|
|
25
|
+
*/
|
|
26
|
+
/** Añade lo que se acaba de escribir. Acepta trozos a medio renglón. */
|
|
27
|
+
export declare function apuntar(texto: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Todas las líneas, con el resto sin terminar como última.
|
|
30
|
+
*
|
|
31
|
+
* Se incluye a propósito: mientras el modelo escribe una frase larga, el resto
|
|
32
|
+
* ES lo que está saliendo. Ocultarlo hasta el salto haría que la respuesta
|
|
33
|
+
* apareciera a tirones, un renglón entero de golpe.
|
|
34
|
+
*/
|
|
35
|
+
export declare function todas(): string[];
|
|
36
|
+
export declare function cuantas(): number;
|
|
37
|
+
/** Se llama en cada escritura, para que quien pinte se entere. */
|
|
38
|
+
export declare function alEscribir(cb: () => void): () => void;
|
|
39
|
+
export declare function vaciar(): void;
|
|
40
|
+
/**
|
|
41
|
+
* La ventana visible: `alto` líneas terminando `desdeElFinal` por encima del
|
|
42
|
+
* final.
|
|
43
|
+
*
|
|
44
|
+
* `desdeElFinal` es cuánto se ha subido con el scroll. Cero es el fondo, que es
|
|
45
|
+
* donde se está mientras se trabaja.
|
|
46
|
+
*/
|
|
47
|
+
export declare function ventana(alto: number, desdeElFinal?: number): string[];
|
|
48
|
+
/** Cuánto se puede subir todavía. Sirve para no pasarse del principio. */
|
|
49
|
+
export declare function tope(alto: number): number;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LO QUE HA SALIDO POR PANTALLA, GUARDADO EN MEMORIA
|
|
3
|
+
*
|
|
4
|
+
* POR QUE HACE FALTA
|
|
5
|
+
*
|
|
6
|
+
* En la pantalla normal el historial lo lleva el terminal: sale una línea, se va
|
|
7
|
+
* hacia arriba, y la rueda del ratón la recupera. Por eso la barra de abajo sube
|
|
8
|
+
* con el scroll: es una línea más del historial, no una capa encima.
|
|
9
|
+
*
|
|
10
|
+
* En la pantalla alternativa —la que usan vim o htop— el terminal NO guarda
|
|
11
|
+
* nada. A cambio, la barra se queda clavada de verdad. Pero si nadie recuerda lo
|
|
12
|
+
* que salió, la conversación desaparece en cuanto pasa de una pantalla, que sería
|
|
13
|
+
* mucho peor que el problema que se quiere resolver.
|
|
14
|
+
*
|
|
15
|
+
* Así que aquí se guarda. Es el precio de tener la barra fija: el historial deja
|
|
16
|
+
* de ser del terminal y pasa a ser nuestro.
|
|
17
|
+
*
|
|
18
|
+
* POR QUE SE GUARDA POR LÍNEAS Y NO EL FLUJO CRUDO
|
|
19
|
+
*
|
|
20
|
+
* Lo que llega trae códigos de color y a veces medio renglón sin terminar. Para
|
|
21
|
+
* poder pintar "las últimas N líneas" hay que saber dónde acaba cada una, así
|
|
22
|
+
* que se parte por saltos y el resto sin terminar se queda esperando al suyo.
|
|
23
|
+
* Los colores se conservan tal cual: recortarlos aquí sería pintar la
|
|
24
|
+
* conversación en gris.
|
|
25
|
+
*/
|
|
26
|
+
/** Tope de líneas recordadas. Más allá, se olvidan las de arriba. */
|
|
27
|
+
const MAXIMO = Number(process.env.CHOCOLATITO_HISTORIAL_LINEAS || 5000);
|
|
28
|
+
let lineas = [];
|
|
29
|
+
let resto = "";
|
|
30
|
+
const oyentes = [];
|
|
31
|
+
/** Añade lo que se acaba de escribir. Acepta trozos a medio renglón. */
|
|
32
|
+
export function apuntar(texto) {
|
|
33
|
+
if (!texto)
|
|
34
|
+
return;
|
|
35
|
+
const completo = resto + texto.replace(/\r\n/g, "\n");
|
|
36
|
+
const partes = completo.split("\n");
|
|
37
|
+
// El último trozo no lleva salto: todavía no es una línea terminada.
|
|
38
|
+
resto = partes.pop() ?? "";
|
|
39
|
+
for (const l of partes)
|
|
40
|
+
lineas.push(l);
|
|
41
|
+
if (lineas.length > MAXIMO)
|
|
42
|
+
lineas = lineas.slice(lineas.length - MAXIMO);
|
|
43
|
+
for (const cb of oyentes) {
|
|
44
|
+
try {
|
|
45
|
+
cb();
|
|
46
|
+
}
|
|
47
|
+
catch { }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Todas las líneas, con el resto sin terminar como última.
|
|
52
|
+
*
|
|
53
|
+
* Se incluye a propósito: mientras el modelo escribe una frase larga, el resto
|
|
54
|
+
* ES lo que está saliendo. Ocultarlo hasta el salto haría que la respuesta
|
|
55
|
+
* apareciera a tirones, un renglón entero de golpe.
|
|
56
|
+
*/
|
|
57
|
+
export function todas() {
|
|
58
|
+
return resto ? [...lineas, resto] : lineas;
|
|
59
|
+
}
|
|
60
|
+
export function cuantas() {
|
|
61
|
+
return todas().length;
|
|
62
|
+
}
|
|
63
|
+
/** Se llama en cada escritura, para que quien pinte se entere. */
|
|
64
|
+
export function alEscribir(cb) {
|
|
65
|
+
oyentes.push(cb);
|
|
66
|
+
return () => {
|
|
67
|
+
const i = oyentes.indexOf(cb);
|
|
68
|
+
if (i >= 0)
|
|
69
|
+
oyentes.splice(i, 1);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export function vaciar() {
|
|
73
|
+
lineas = [];
|
|
74
|
+
resto = "";
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* La ventana visible: `alto` líneas terminando `desdeElFinal` por encima del
|
|
78
|
+
* final.
|
|
79
|
+
*
|
|
80
|
+
* `desdeElFinal` es cuánto se ha subido con el scroll. Cero es el fondo, que es
|
|
81
|
+
* donde se está mientras se trabaja.
|
|
82
|
+
*/
|
|
83
|
+
export function ventana(alto, desdeElFinal = 0) {
|
|
84
|
+
const todo = todas();
|
|
85
|
+
const fin = Math.max(0, todo.length - Math.max(0, desdeElFinal));
|
|
86
|
+
const inicio = Math.max(0, fin - Math.max(1, alto));
|
|
87
|
+
return todo.slice(inicio, fin);
|
|
88
|
+
}
|
|
89
|
+
/** Cuánto se puede subir todavía. Sirve para no pasarse del principio. */
|
|
90
|
+
export function tope(alto) {
|
|
91
|
+
return Math.max(0, cuantas() - Math.max(1, alto));
|
|
92
|
+
}
|
package/dist/ui/ink/Prompt.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { Box, Text, useApp, useInput, useStdout } from "ink";
|
|
4
4
|
import { buildPromptFrame } from "../marco.js";
|
|
5
5
|
import { cycleMode } from "../modes.js";
|
|
6
6
|
import { aplicarOpcion, archivosDelProyecto, leerHistorial, mencionEnCurso, opcionesDelDesplegable, } from "../entrada.js";
|
|
7
7
|
import { esGrande, guardarPegado, marcaQueTerminaEn } from "../pegados.js";
|
|
8
|
+
import { alEscribir, tope, ventana } from "../historial.js";
|
|
9
|
+
import { enPantallaFija } from "../pantalla.js";
|
|
8
10
|
/** Marca del cursor. Ink esconde el de verdad, así que este se dibuja. */
|
|
9
11
|
const CARET = "█";
|
|
10
12
|
export function Prompt({ alEnviar, alCancelar, cwd, promptSymbol, avisos, }) {
|
|
@@ -17,6 +19,18 @@ export function Prompt({ alEnviar, alCancelar, cwd, promptSymbol, avisos, }) {
|
|
|
17
19
|
const [, setRedibujar] = useState(0);
|
|
18
20
|
const historial = useRef(leerHistorial());
|
|
19
21
|
const [posHistorial, setPosHistorial] = useState(historial.current.length);
|
|
22
|
+
// Cuanto se ha subido con Re Pag. Cero es el fondo, que es donde se esta
|
|
23
|
+
// mientras se trabaja. Solo se usa en pantalla fija.
|
|
24
|
+
const [subido, setSubido] = useState(0);
|
|
25
|
+
const fija = enPantallaFija();
|
|
26
|
+
// En pantalla fija el terminal ya no guarda nada: lo que sale lo pintamos
|
|
27
|
+
// nosotros, asi que hay que repintar en cada escritura del agente. El
|
|
28
|
+
// historial vive fuera de React y React no puede adivinar que ha crecido.
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!fija)
|
|
31
|
+
return;
|
|
32
|
+
return alEscribir(() => setRedibujar((n) => n + 1));
|
|
33
|
+
}, [fija]);
|
|
20
34
|
// Se escanea UNA vez por prompt, no en cada tecla: recorrer el proyecto entero
|
|
21
35
|
// por cada letra se nota en cuanto el proyecto pasa de mediano.
|
|
22
36
|
const archivos = useMemo(() => {
|
|
@@ -29,6 +43,27 @@ export function Prompt({ alEnviar, alCancelar, cwd, promptSymbol, avisos, }) {
|
|
|
29
43
|
}, [cwd]);
|
|
30
44
|
const opciones = opcionesDelDesplegable(texto, cursor, archivos);
|
|
31
45
|
const indice = opciones.length > 0 ? ((elegido % opciones.length) + opciones.length) % opciones.length : 0;
|
|
46
|
+
const cols = Math.max(20, stdout?.columns || 80);
|
|
47
|
+
const rows = stdout?.rows || 24;
|
|
48
|
+
// El cursor se dibuja: Ink esconde el del terminal.
|
|
49
|
+
const conCaret = texto.slice(0, cursor) + CARET + texto.slice(cursor);
|
|
50
|
+
const marco = buildPromptFrame({
|
|
51
|
+
cols,
|
|
52
|
+
rows,
|
|
53
|
+
promptSymbol,
|
|
54
|
+
input: conCaret,
|
|
55
|
+
cursorIndex: cursor,
|
|
56
|
+
items: opciones,
|
|
57
|
+
selectedIndex: indice,
|
|
58
|
+
});
|
|
59
|
+
// Filas que le quedan a la conversacion una vez puesta la barra. En pantalla
|
|
60
|
+
// fija es lo que se pinta; en la normal no se usa, que ahi el historial es del
|
|
61
|
+
// terminal.
|
|
62
|
+
// Cuando se ha subido, una fila se va en el aviso de que se esta mirando
|
|
63
|
+
// atras. Sin descontarla, el arbol mide una fila mas que la ventana y el
|
|
64
|
+
// terminal desplaza: la barra dejaria de estar clavada justo al usar el scroll,
|
|
65
|
+
// que es para lo que existe este modo.
|
|
66
|
+
const altoDelTexto = Math.max(1, rows - marco.lines.length - (subido > 0 ? 1 : 0));
|
|
32
67
|
function enviar() {
|
|
33
68
|
const orden = texto.trim();
|
|
34
69
|
if (!orden)
|
|
@@ -37,6 +72,15 @@ export function Prompt({ alEnviar, alCancelar, cwd, promptSymbol, avisos, }) {
|
|
|
37
72
|
exit();
|
|
38
73
|
}
|
|
39
74
|
useInput((entrada, tecla) => {
|
|
75
|
+
// ----------------------------------------------- recorrer lo que salio
|
|
76
|
+
//
|
|
77
|
+
// Solo Re Pag y Av Pag. Las flechas y los caracteres son para escribir:
|
|
78
|
+
// robarselos aqui dejaria al usuario sin poder teclear.
|
|
79
|
+
if (fija && (tecla.pageUp || tecla.pageDown)) {
|
|
80
|
+
const salto = Math.max(1, Math.floor(altoDelTexto / 2));
|
|
81
|
+
setSubido((n) => tecla.pageUp ? Math.min(tope(altoDelTexto), n + salto) : Math.max(0, n - salto));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
40
84
|
// ------------------------------------------------------------- salir
|
|
41
85
|
if (tecla.ctrl && entrada === "c") {
|
|
42
86
|
alCancelar();
|
|
@@ -171,18 +215,14 @@ export function Prompt({ alEnviar, alCancelar, cwd, promptSymbol, avisos, }) {
|
|
|
171
215
|
setElegido(0);
|
|
172
216
|
}
|
|
173
217
|
});
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
items: opciones,
|
|
185
|
-
selectedIndex: indice,
|
|
186
|
-
});
|
|
187
|
-
return (_jsxs(Box, { flexDirection: "column", children: [avisos.map((a, i) => (_jsx(Text, { children: a }, `aviso-${i}`))), marco.lines.map((linea, i) => (_jsx(Text, { children: linea }, i)))] }));
|
|
218
|
+
if (!fija) {
|
|
219
|
+
return (_jsxs(Box, { flexDirection: "column", children: [avisos.map((a, i) => (_jsx(Text, { children: a }, `aviso-${i}`))), marco.lines.map((linea, i) => (_jsx(Text, { children: linea }, i)))] }));
|
|
220
|
+
}
|
|
221
|
+
// PANTALLA FIJA: el arbol ocupa la ventana entera y la barra va la ultima, asi
|
|
222
|
+
// que no puede moverse. Lo de arriba se rellena con huecos cuando hay poca
|
|
223
|
+
// conversacion; sin eso la barra subiria a media pantalla, que es justo la
|
|
224
|
+
// queja que este modo viene a resolver.
|
|
225
|
+
const visible = ventana(altoDelTexto, subido);
|
|
226
|
+
const huecos = Math.max(0, altoDelTexto - visible.length);
|
|
227
|
+
return (_jsxs(Box, { flexDirection: "column", height: rows, children: [Array.from({ length: huecos }, (_, i) => (_jsx(Text, { children: " " }, `hueco-${i}`))), visible.map((linea, i) => (_jsx(Text, { children: linea }, `h-${i}`))), subido > 0 && (_jsx(Text, { dimColor: true, children: ` ↑ ${subido} lineas mas arriba · Av Pag para volver al final` })), marco.lines.map((linea, i) => (_jsx(Text, { children: linea }, `b-${i}`)))] }));
|
|
188
228
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare function pantallaFijaPedida(): boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Enciende o apaga el modo a mano, SIN tocar el terminal.
|
|
4
|
+
*
|
|
5
|
+
* Las pruebas lo necesitan: entrar de verdad escribiria la secuencia de la
|
|
6
|
+
* pantalla alternativa en la consola de quien corre las pruebas y le dejaria el
|
|
7
|
+
* informe en una pantalla que desaparece al acabar.
|
|
8
|
+
*/
|
|
9
|
+
export declare function forzarPantallaFija(valor: boolean | null): void;
|
|
10
|
+
export declare function enPantallaFija(): boolean;
|
|
11
|
+
export declare function entrarEnPantallaFija(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Devuelve el terminal como estaba.
|
|
14
|
+
*
|
|
15
|
+
* Se llama al salir del programa, y también si algo revienta: quedarse en la
|
|
16
|
+
* pantalla alternativa deja al usuario en una consola en blanco sin su prompt,
|
|
17
|
+
* y la única salida es cerrar la ventana.
|
|
18
|
+
*/
|
|
19
|
+
export declare function salirDePantallaFija(): void;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { redirigirDibujo } from "./salida.js";
|
|
3
|
+
import { apuntar } from "./historial.js";
|
|
4
|
+
/**
|
|
5
|
+
* LA PANTALLA ALTERNATIVA
|
|
6
|
+
*
|
|
7
|
+
* La barra de abajo sube al hacer scroll porque ES una línea del historial del
|
|
8
|
+
* terminal, no una capa encima. Ninguna secuencia de escape la clava ahí; lo
|
|
9
|
+
* único que lo consigue es que el programa tome la pantalla entera, como hacen
|
|
10
|
+
* vim o htop.
|
|
11
|
+
*
|
|
12
|
+
* QUÉ CAMBIA AL ENTRAR
|
|
13
|
+
*
|
|
14
|
+
* El terminal deja de guardar historial: la rueda del ratón no sirve y al salir
|
|
15
|
+
* la sesión desaparece de la consola. Por eso, mientras dura, TODO lo que se
|
|
16
|
+
* imprime se guarda en memoria (historial.ts) y lo pinta el árbol de Ink.
|
|
17
|
+
*
|
|
18
|
+
* Y por eso hay que interceptar también `console.log`. Aquí no vale con desviar
|
|
19
|
+
* el conducto de dibujo: media docena de sitios —el arranque, la licencia, los
|
|
20
|
+
* avisos— siguen imprimiendo directo, y en la pantalla alternativa eso escribe
|
|
21
|
+
* encima de lo que Ink acaba de dibujar y descuadra el árbol entero.
|
|
22
|
+
*
|
|
23
|
+
* ES UN MODO, NO EL COMPORTAMIENTO NORMAL
|
|
24
|
+
*
|
|
25
|
+
* Cambiar el historial del terminal por uno propio es un intercambio de verdad,
|
|
26
|
+
* no una mejora: quien use mucho la rueda del ratón para releer sale perdiendo.
|
|
27
|
+
* Se activa con CHOCOLATITO_PANTALLA=fija.
|
|
28
|
+
*/
|
|
29
|
+
const ENTRAR = "\x1b[?1049h";
|
|
30
|
+
const SALIR = "\x1b[?1049l";
|
|
31
|
+
let dentro = false;
|
|
32
|
+
let logOriginal = null;
|
|
33
|
+
export function pantallaFijaPedida() {
|
|
34
|
+
return process.env.CHOCOLATITO_PANTALLA === "fija";
|
|
35
|
+
}
|
|
36
|
+
/** `null` = manda el estado real. Las pruebas lo fuerzan. */
|
|
37
|
+
let forzado = null;
|
|
38
|
+
/**
|
|
39
|
+
* Enciende o apaga el modo a mano, SIN tocar el terminal.
|
|
40
|
+
*
|
|
41
|
+
* Las pruebas lo necesitan: entrar de verdad escribiria la secuencia de la
|
|
42
|
+
* pantalla alternativa en la consola de quien corre las pruebas y le dejaria el
|
|
43
|
+
* informe en una pantalla que desaparece al acabar.
|
|
44
|
+
*/
|
|
45
|
+
export function forzarPantallaFija(valor) {
|
|
46
|
+
forzado = valor;
|
|
47
|
+
}
|
|
48
|
+
export function enPantallaFija() {
|
|
49
|
+
return forzado ?? dentro;
|
|
50
|
+
}
|
|
51
|
+
export function entrarEnPantallaFija() {
|
|
52
|
+
if (dentro || !process.stdout.isTTY)
|
|
53
|
+
return;
|
|
54
|
+
dentro = true;
|
|
55
|
+
process.stdout.write(ENTRAR);
|
|
56
|
+
// Lo que se dibujaba en el terminal pasa a ser historial nuestro.
|
|
57
|
+
redirigirDibujo((texto) => apuntar(texto));
|
|
58
|
+
logOriginal = console.log;
|
|
59
|
+
console.log = (...args) => {
|
|
60
|
+
apuntar(args.map((a) => (typeof a === "string" ? a : String(a))).join(" ") + "\n");
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Devuelve el terminal como estaba.
|
|
65
|
+
*
|
|
66
|
+
* Se llama al salir del programa, y también si algo revienta: quedarse en la
|
|
67
|
+
* pantalla alternativa deja al usuario en una consola en blanco sin su prompt,
|
|
68
|
+
* y la única salida es cerrar la ventana.
|
|
69
|
+
*/
|
|
70
|
+
export function salirDePantallaFija() {
|
|
71
|
+
if (!dentro)
|
|
72
|
+
return;
|
|
73
|
+
dentro = false;
|
|
74
|
+
if (logOriginal) {
|
|
75
|
+
console.log = logOriginal;
|
|
76
|
+
logOriginal = null;
|
|
77
|
+
}
|
|
78
|
+
redirigirDibujo(null);
|
|
79
|
+
try {
|
|
80
|
+
process.stdout.write(SALIR);
|
|
81
|
+
}
|
|
82
|
+
catch { }
|
|
83
|
+
}
|
|
84
|
+
process.on("exit", salirDePantallaFija);
|
package/extension/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"minimum_chrome_version": "102",
|
|
4
4
|
"name": "Chocolatito Code",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.5.0",
|
|
6
6
|
"description": "Deja que Chocolatito Code trabaje dentro de tu Chrome, en segundo plano y con tus sesiones ya iniciadas.",
|
|
7
7
|
"permissions": [
|
|
8
8
|
"tabs",
|
package/package.json
CHANGED