chocolatito-code 1.6.13 → 1.6.14
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/COMPUTER-USE.md +37 -0
- package/README.md +9 -2
- package/dist/config/permissions.js +4 -0
- package/dist/index.js +129 -24
- package/dist/prompts/systemPrompt.js +15 -11
- package/dist/servidor/archivos.d.ts +69 -0
- package/dist/servidor/archivos.js +156 -0
- package/dist/servidor/fondo.d.ts +85 -0
- package/dist/servidor/fondo.js +134 -0
- package/dist/servidor/pagina.js +266 -2
- package/dist/servidor/puente.d.ts +13 -0
- package/dist/servidor/puente.js +11 -0
- package/dist/servidor/servidor.d.ts +6 -0
- package/dist/servidor/servidor.js +129 -6
- package/dist/tools/computerUse.d.ts +11 -1
- package/dist/tools/computerUse.js +376 -34
- package/dist/tools/toolDefsComputer.js +39 -14
- package/dist/tools/visionBridge.d.ts +4 -2
- package/dist/tools/visionBridge.js +40 -15
- package/dist/tools/win/hostScript.js +300 -29
- package/dist/ui/ink/App.js +23 -3
- package/dist/ui/ink/Prompt.d.ts +5 -1
- package/dist/ui/ink/Prompt.js +92 -4
- package/dist/ui/ink/control.d.ts +2 -0
- package/dist/ui/ink/control.js +15 -0
- package/dist/ui/ink/montarApp.d.ts +0 -19
- package/dist/ui/ink/montarApp.js +3 -0
- package/dist/ui/permissionPrompt.js +44 -9
- package/dist/ui/pieFijo.js +5 -0
- package/dist/ui/prompt.js +6 -0
- package/dist/ui/renderer.d.ts +1 -0
- package/dist/ui/renderer.js +27 -2
- package/dist/ui/selector.js +5 -0
- package/dist/ui/spinner.d.ts +1 -0
- package/dist/ui/spinner.js +6 -0
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
package/dist/ui/ink/Prompt.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo, useRef, useState } from "react";
|
|
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 { solicitarLimpieza } from "./control.js";
|
|
8
9
|
/** Marca del cursor. Ink esconde el de verdad, así que este se dibuja. */
|
|
9
10
|
const CARET = "█";
|
|
10
11
|
/**
|
|
@@ -21,7 +22,7 @@ const CARET = "█";
|
|
|
21
22
|
function conCuerpo(texto) {
|
|
22
23
|
return texto.length > 0 ? texto : " ";
|
|
23
24
|
}
|
|
24
|
-
export function Prompt({ alEnviar, alCancelar, cwd, promptSymbol, avisos, cerrarAlEnviar = true, alto, }) {
|
|
25
|
+
export function Prompt({ alEnviar, alCancelar, cwd, promptSymbol, avisos, cerrarAlEnviar = true, alto, cols: colsProp, filas: filasProp, }) {
|
|
25
26
|
const { stdout } = useStdout();
|
|
26
27
|
const { exit } = useApp();
|
|
27
28
|
const [texto, setTexto] = useState("");
|
|
@@ -29,6 +30,26 @@ export function Prompt({ alEnviar, alCancelar, cwd, promptSymbol, avisos, cerrar
|
|
|
29
30
|
const [elegido, setElegido] = useState(0);
|
|
30
31
|
/** Contador para forzar un dibujado cuando cambia algo de fuera de React. */
|
|
31
32
|
const [, setRedibujar] = useState(0);
|
|
33
|
+
const [tamano, setTamano] = useState(() => ({
|
|
34
|
+
cols: Math.max(20, colsProp ?? (stdout?.columns && stdout.columns > 0 ? stdout.columns : process.stdout?.columns) ?? 80),
|
|
35
|
+
rows: Math.max(6, alto ?? filasProp ?? (stdout?.rows && stdout.rows > 0 ? stdout.rows : process.stdout?.rows) ?? 24),
|
|
36
|
+
}));
|
|
37
|
+
// Reaccionar inmediatamente cuando la ventana se maximiza, restaura o cambia de tamaño
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const alRedimensionar = () => {
|
|
40
|
+
setTamano({
|
|
41
|
+
cols: Math.max(20, colsProp ?? (stdout?.columns && stdout.columns > 0 ? stdout.columns : process.stdout?.columns) ?? 80),
|
|
42
|
+
rows: Math.max(6, alto ?? filasProp ?? (stdout?.rows && stdout.rows > 0 ? stdout.rows : process.stdout?.rows) ?? 24),
|
|
43
|
+
});
|
|
44
|
+
setRedibujar((n) => n + 1);
|
|
45
|
+
};
|
|
46
|
+
stdout?.on("resize", alRedimensionar);
|
|
47
|
+
process.stdout?.on("resize", alRedimensionar);
|
|
48
|
+
return () => {
|
|
49
|
+
stdout?.off("resize", alRedimensionar);
|
|
50
|
+
process.stdout?.off("resize", alRedimensionar);
|
|
51
|
+
};
|
|
52
|
+
}, [stdout, colsProp, alto, filasProp]);
|
|
32
53
|
const historial = useRef(leerHistorial());
|
|
33
54
|
const [posHistorial, setPosHistorial] = useState(historial.current.length);
|
|
34
55
|
// Se escanea UNA vez por prompt, no en cada tecla: recorrer el proyecto entero
|
|
@@ -43,10 +64,10 @@ export function Prompt({ alEnviar, alCancelar, cwd, promptSymbol, avisos, cerrar
|
|
|
43
64
|
}, [cwd]);
|
|
44
65
|
const opciones = opcionesDelDesplegable(texto, cursor, archivos);
|
|
45
66
|
const indice = opciones.length > 0 ? ((elegido % opciones.length) + opciones.length) % opciones.length : 0;
|
|
46
|
-
const cols =
|
|
67
|
+
const cols = colsProp ?? tamano.cols;
|
|
47
68
|
// El alto que da App ya viene descontado de lo que hay por encima; sin él, la
|
|
48
69
|
// ventana entera.
|
|
49
|
-
const rows = Math.max(6, alto ??
|
|
70
|
+
const rows = Math.max(6, alto ?? tamano.rows);
|
|
50
71
|
// El cursor se dibuja: Ink esconde el del terminal.
|
|
51
72
|
const conCaret = texto.slice(0, cursor) + CARET + texto.slice(cursor);
|
|
52
73
|
const marco = buildPromptFrame({
|
|
@@ -87,6 +108,73 @@ export function Prompt({ alEnviar, alCancelar, cwd, promptSymbol, avisos, cerrar
|
|
|
87
108
|
cerrar();
|
|
88
109
|
return;
|
|
89
110
|
}
|
|
111
|
+
// ------------------------------------------------------------- limpiar pantalla (Ctrl+L)
|
|
112
|
+
if (tecla.ctrl && entrada === "l") {
|
|
113
|
+
solicitarLimpieza();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// ------------------------------------------------------------- escape cancela / limpia entrada
|
|
117
|
+
if (tecla.escape) {
|
|
118
|
+
if (texto.length > 0) {
|
|
119
|
+
setTexto("");
|
|
120
|
+
setCursor(0);
|
|
121
|
+
setElegido(0);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// ------------------------------------------------------------- inicio de línea (Ctrl+A o Home)
|
|
126
|
+
if ((tecla.ctrl && entrada === "a") || entrada === "\x1b[H" || entrada === "\x1b[1~") {
|
|
127
|
+
setCursor(0);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// ------------------------------------------------------------- fin de línea (Ctrl+E o End)
|
|
131
|
+
if ((tecla.ctrl && entrada === "e") || entrada === "\x1b[F" || entrada === "\x1b[4~") {
|
|
132
|
+
setCursor(texto.length);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
// ------------------------------------------------------------- borrar hasta inicio de línea (Ctrl+U)
|
|
136
|
+
if (tecla.ctrl && entrada === "u") {
|
|
137
|
+
setTexto(texto.slice(cursor));
|
|
138
|
+
setCursor(0);
|
|
139
|
+
setElegido(0);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
// ------------------------------------------------------------- borrar hasta fin de línea (Ctrl+K)
|
|
143
|
+
if (tecla.ctrl && entrada === "k") {
|
|
144
|
+
setTexto(texto.slice(0, cursor));
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// ------------------------------------------------------------- borrar palabra atrás (Ctrl+W)
|
|
148
|
+
if (tecla.ctrl && entrada === "w") {
|
|
149
|
+
if (cursor === 0)
|
|
150
|
+
return;
|
|
151
|
+
const antes = texto.slice(0, cursor);
|
|
152
|
+
const sinEspaciosFinal = antes.trimEnd();
|
|
153
|
+
const pos = Math.max(sinEspaciosFinal.lastIndexOf(" "), sinEspaciosFinal.lastIndexOf("\t"), sinEspaciosFinal.lastIndexOf("/"), sinEspaciosFinal.lastIndexOf("\\"));
|
|
154
|
+
const nuevoCursor = Math.max(0, pos >= 0 ? pos + 1 : 0);
|
|
155
|
+
setTexto(texto.slice(0, nuevoCursor) + texto.slice(cursor));
|
|
156
|
+
setCursor(nuevoCursor);
|
|
157
|
+
setElegido(0);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// ------------------------------------------------- saltar palabra atrás (Alt+B / Ctrl+Left)
|
|
161
|
+
if ((tecla.meta && entrada === "b") || (tecla.ctrl && tecla.leftArrow) || (tecla.meta && tecla.leftArrow)) {
|
|
162
|
+
if (cursor === 0)
|
|
163
|
+
return;
|
|
164
|
+
const antes = texto.slice(0, cursor).trimEnd();
|
|
165
|
+
const pos = Math.max(antes.lastIndexOf(" "), antes.lastIndexOf("\t"), antes.lastIndexOf("/"), antes.lastIndexOf("\\"));
|
|
166
|
+
setCursor(Math.max(0, pos >= 0 ? pos + 1 : 0));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
// ------------------------------------------------- saltar palabra adelante (Alt+F / Ctrl+Right)
|
|
170
|
+
if ((tecla.meta && entrada === "f") || (tecla.ctrl && tecla.rightArrow) || (tecla.meta && tecla.rightArrow)) {
|
|
171
|
+
if (cursor >= texto.length)
|
|
172
|
+
return;
|
|
173
|
+
const despues = texto.slice(cursor);
|
|
174
|
+
const coincidencia = despues.search(/\s\S|[/\\]\S/);
|
|
175
|
+
setCursor(coincidencia >= 0 ? cursor + coincidencia + 1 : texto.length);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
90
178
|
// ------------------------------------------- cambiar el modo de permisos
|
|
91
179
|
if (tecla.tab && tecla.shift) {
|
|
92
180
|
cycleMode();
|
package/dist/ui/ink/control.d.ts
CHANGED
|
@@ -34,3 +34,5 @@ export declare function alCambiarElTurno(cb: (e: EstadoDelTurno) => void): () =>
|
|
|
34
34
|
* promesa deja el bucle avanzando por su cuenta con una orden que nadie escribió.
|
|
35
35
|
*/
|
|
36
36
|
export declare function pedirOrden(promptSymbol: string, cwd: string): Promise<string>;
|
|
37
|
+
export declare function registrarLimpiador(fn: (() => void) | null): void;
|
|
38
|
+
export declare function solicitarLimpieza(): void;
|
package/dist/ui/ink/control.js
CHANGED
|
@@ -52,3 +52,18 @@ export function pedirOrden(promptSymbol, cwd) {
|
|
|
52
52
|
avisar();
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
+
let limpiador = null;
|
|
56
|
+
export function registrarLimpiador(fn) {
|
|
57
|
+
limpiador = fn;
|
|
58
|
+
}
|
|
59
|
+
export function solicitarLimpieza() {
|
|
60
|
+
if (limpiador) {
|
|
61
|
+
limpiador();
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
try {
|
|
65
|
+
process.stdout.write("\x1b[2J\x1b[3J\x1b[H");
|
|
66
|
+
}
|
|
67
|
+
catch { }
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -14,23 +14,4 @@ export declare function montarArbol(): void;
|
|
|
14
14
|
*/
|
|
15
15
|
export declare function desmontarArbol(): void;
|
|
16
16
|
export declare function hayArbol(): boolean;
|
|
17
|
-
/**
|
|
18
|
-
* Borra la pantalla de verdad. Es lo que hacen /clear, /cd y Ctrl+L.
|
|
19
|
-
*
|
|
20
|
-
* POR QUE NO VALE UN `console.clear()`
|
|
21
|
-
*
|
|
22
|
-
* `console.clear()` escribe la secuencia de borrado directa al terminal, y no
|
|
23
|
-
* pasa por la interceptación de consola: ahí solo van `log`, `error`, `warn` e
|
|
24
|
-
* `info`. Con el árbol montado eso borra filas que Ink cree suyas, y a partir de
|
|
25
|
-
* ahí Ink borra y repinta sobre un sitio que ya no existe. Lo que se ve es
|
|
26
|
-
* basura, o nada.
|
|
27
|
-
*
|
|
28
|
-
* Aquí se hace en el orden que no rompe nada: se borra el marco con la cuenta
|
|
29
|
-
* todavía buena, se suelta el árbol, se limpia la pantalla —y el historial del
|
|
30
|
-
* terminal con `3J`, que es lo que el usuario espera de un /clear— y se vuelve a
|
|
31
|
-
* montar de cero.
|
|
32
|
-
*
|
|
33
|
-
* Y se vacía la transcripción: si no, el <Static> nuevo tendría por delante toda
|
|
34
|
-
* la conversación que se acaba de borrar.
|
|
35
|
-
*/
|
|
36
17
|
export declare function limpiarLaPantalla(): void;
|
package/dist/ui/ink/montarApp.js
CHANGED
|
@@ -109,6 +109,7 @@ export function hayArbol() {
|
|
|
109
109
|
* Y se vacía la transcripción: si no, el <Static> nuevo tendría por delante toda
|
|
110
110
|
* la conversación que se acaba de borrar.
|
|
111
111
|
*/
|
|
112
|
+
import { registrarLimpiador } from "./control.js";
|
|
112
113
|
export function limpiarLaPantalla() {
|
|
113
114
|
const habia = arbol !== null;
|
|
114
115
|
if (habia)
|
|
@@ -122,6 +123,8 @@ export function limpiarLaPantalla() {
|
|
|
122
123
|
if (habia)
|
|
123
124
|
montarArbol();
|
|
124
125
|
}
|
|
126
|
+
// Conectar el limpiador con el prompt para soportar Ctrl+L sin ciclos circulares de módulos
|
|
127
|
+
registrarLimpiador(limpiarLaPantalla);
|
|
125
128
|
// Si el proceso muere sin pasar por la salida ordenada, el árbol tiene que
|
|
126
129
|
// soltarse igual: un árbol vivo en un proceso que se cierra deja el terminal a
|
|
127
130
|
// medio restaurar.
|
|
@@ -67,12 +67,17 @@ async function askToolPermissionDirecto(toolName, args, cwd = process.cwd()) {
|
|
|
67
67
|
process.stdout.write(lines.map((l) => `\r\x1b[2K${l}`).join("\n") + "\n");
|
|
68
68
|
renderedRows = lines.length;
|
|
69
69
|
}
|
|
70
|
-
draw();
|
|
71
70
|
function cleanup() {
|
|
72
71
|
process.stdin.removeListener("keypress", onKeypress);
|
|
72
|
+
process.stdout.removeListener("resize", onResize);
|
|
73
73
|
if (process.stdin.setRawMode)
|
|
74
74
|
process.stdin.setRawMode(wasRaw || false);
|
|
75
75
|
}
|
|
76
|
+
const onResize = () => {
|
|
77
|
+
draw();
|
|
78
|
+
};
|
|
79
|
+
process.stdout.on("resize", onResize);
|
|
80
|
+
draw();
|
|
76
81
|
async function promptForFeedback() {
|
|
77
82
|
cleanup();
|
|
78
83
|
return new Promise((resFeedback) => {
|
|
@@ -329,15 +334,45 @@ function details(toolName, args, cwd, width) {
|
|
|
329
334
|
}
|
|
330
335
|
}
|
|
331
336
|
else if (typeof args.action === "string") {
|
|
332
|
-
// Sobre QUE actua importa tanto como la accion. Un "close_tab" a secas no
|
|
337
|
+
// POR QUE: Sobre QUE actua importa tanto como la accion. Un "close_tab" a secas no
|
|
333
338
|
// decia que pestana moria, asi que aprobarlo era aprobar a ciegas.
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
339
|
+
// Con "sequence" pasaba exactamente lo mismo: ensenar solo la palabra "sequence"
|
|
340
|
+
// hacia que el usuario aprobara N clics y pulsaciones a ciegas sin ver que se iba
|
|
341
|
+
// a ejecutar en su maquina.
|
|
342
|
+
if (args.action === "sequence" && Array.isArray(args.steps) && args.steps.length > 0) {
|
|
343
|
+
const resumirPaso = (s) => {
|
|
344
|
+
if (!s || typeof s !== "object")
|
|
345
|
+
return "?";
|
|
346
|
+
const act = String(s.action || "paso");
|
|
347
|
+
if (typeof s.ref === "number")
|
|
348
|
+
return `${act} [${s.ref}]`;
|
|
349
|
+
if (typeof s.text === "string")
|
|
350
|
+
return `${act} '${s.text}'`;
|
|
351
|
+
if (typeof s.key === "string")
|
|
352
|
+
return `${act} ${s.key}`;
|
|
353
|
+
if (typeof s.keys === "string")
|
|
354
|
+
return `${act} ${s.keys}`;
|
|
355
|
+
if (Array.isArray(s.coordinate) && s.coordinate.length === 2)
|
|
356
|
+
return `${act} (${s.coordinate[0]}, ${s.coordinate[1]})`;
|
|
357
|
+
if (typeof s.x === "number" && typeof s.y === "number")
|
|
358
|
+
return `${act} (${s.x}, ${s.y})`;
|
|
359
|
+
return act;
|
|
360
|
+
};
|
|
361
|
+
const n = args.steps.length;
|
|
362
|
+
const cadenaPasos = args.steps.map(resumirPaso).join(" -> ");
|
|
363
|
+
const plain = `${n} pasos: ${cadenaPasos}`;
|
|
364
|
+
const painted = `${chalk.bold.white(`${n} pasos:`)} ${chalk.gray(cadenaPasos)}`;
|
|
365
|
+
add(plain, painted);
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
const objetivo = args.url || args.appName || args.window || args.text ||
|
|
369
|
+
(typeof args.tabId === "number" ? `pestaña ${args.tabId}` : "") ||
|
|
370
|
+
(typeof args.ref === "number" ? `elemento [${args.ref}]` : "") ||
|
|
371
|
+
"";
|
|
372
|
+
const extra = objetivo || (esNavegador(toolName) ? "en la pestaña de trabajo" : "");
|
|
373
|
+
const plain = extra ? `${args.action} ${String(extra)}` : String(args.action);
|
|
374
|
+
add(plain, extra ? `${chalk.bold.white(args.action)} ${chalk.gray(String(extra))}` : chalk.bold.white(args.action));
|
|
375
|
+
}
|
|
341
376
|
}
|
|
342
377
|
else {
|
|
343
378
|
add(toolName, chalk.bold.white(toolName));
|
package/dist/ui/pieFijo.js
CHANGED
|
@@ -356,6 +356,11 @@ export function reiniciarPie() {
|
|
|
356
356
|
* cursor y el usuario no tiene forma de saber por que. Se devuelve pase lo que
|
|
357
357
|
* pase, tambien si el programa se cae.
|
|
358
358
|
*/
|
|
359
|
+
process.stdout.on("resize", () => {
|
|
360
|
+
if (pieUsable() && filasPintadas > 0) {
|
|
361
|
+
repintar("");
|
|
362
|
+
}
|
|
363
|
+
});
|
|
359
364
|
process.on("exit", () => {
|
|
360
365
|
if (cursorEscondido) {
|
|
361
366
|
try {
|
package/dist/ui/prompt.js
CHANGED
|
@@ -373,6 +373,7 @@ async function promptClasico(promptSymbol = "❯", cwd = process.cwd()) {
|
|
|
373
373
|
pendingSubmit = null;
|
|
374
374
|
}
|
|
375
375
|
process.stdin.removeListener("keypress", onKeypress);
|
|
376
|
+
process.stdout.removeListener("resize", onResize);
|
|
376
377
|
if (process.stdin.setRawMode) {
|
|
377
378
|
process.stdin.setRawMode(wasRaw || false);
|
|
378
379
|
}
|
|
@@ -703,6 +704,11 @@ async function promptClasico(promptSymbol = "❯", cwd = process.cwd()) {
|
|
|
703
704
|
lastCursorRow = 0;
|
|
704
705
|
render();
|
|
705
706
|
};
|
|
707
|
+
const onResize = () => {
|
|
708
|
+
if (!isFinished)
|
|
709
|
+
render();
|
|
710
|
+
};
|
|
711
|
+
process.stdout.on("resize", onResize);
|
|
706
712
|
process.stdin.on("keypress", onKeypress);
|
|
707
713
|
render();
|
|
708
714
|
});
|
package/dist/ui/renderer.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export declare function renderUserPrompt(text: string): void;
|
|
|
21
21
|
export declare function renderToolStart(name: string, summary: string): void;
|
|
22
22
|
export declare function renderToolSuccess(name: string, resultSummary: string): void;
|
|
23
23
|
export declare function renderToolError(name: string, errorSummary: string): void;
|
|
24
|
+
export declare function formatColorDiff(diffText: string): string;
|
|
24
25
|
export declare function renderDiff(filePath: string, diffText: string): void;
|
|
25
26
|
export declare function renderReasoning(reasoningText: string): void;
|
|
26
27
|
export declare function renderAssistantResponse(markdownText: string): void;
|
package/dist/ui/renderer.js
CHANGED
|
@@ -65,7 +65,9 @@ export function renderUserPrompt(text) {
|
|
|
65
65
|
export function renderToolStart(name, summary) {
|
|
66
66
|
const bullet = chalk.hex("#FFA500")("●"); // Amber while starting
|
|
67
67
|
const toolName = chalk.bold.white(formatToolName(name));
|
|
68
|
-
const
|
|
68
|
+
const cols = (process.stdout && process.stdout.columns) || 80;
|
|
69
|
+
const maxSummary = Math.max(60, cols - name.length - 12);
|
|
70
|
+
const argPart = summary ? chalk.gray(`(${summary.length > maxSummary ? summary.slice(0, maxSummary - 3) + '...' : summary})`) : "";
|
|
69
71
|
salida.linea(`\n${bullet} ${toolName}${argPart}`);
|
|
70
72
|
}
|
|
71
73
|
export function renderToolSuccess(name, resultSummary) {
|
|
@@ -85,8 +87,31 @@ export function renderToolSuccess(name, resultSummary) {
|
|
|
85
87
|
export function renderToolError(name, errorSummary) {
|
|
86
88
|
salida.linea(` ${chalk.red("⎿")} ${chalk.red(errorSummary)}`);
|
|
87
89
|
}
|
|
90
|
+
export function formatColorDiff(diffText) {
|
|
91
|
+
return diffText
|
|
92
|
+
.split("\n")
|
|
93
|
+
.map((line) => {
|
|
94
|
+
if (line.startsWith("diff --git") || line.startsWith("index ")) {
|
|
95
|
+
return chalk.bold.white(line);
|
|
96
|
+
}
|
|
97
|
+
if (line.startsWith("---") || line.startsWith("+++")) {
|
|
98
|
+
return chalk.bold.hex("#D97757")(line);
|
|
99
|
+
}
|
|
100
|
+
if (line.startsWith("@@")) {
|
|
101
|
+
return chalk.cyan(line);
|
|
102
|
+
}
|
|
103
|
+
if (line.startsWith("+")) {
|
|
104
|
+
return chalk.green(line);
|
|
105
|
+
}
|
|
106
|
+
if (line.startsWith("-")) {
|
|
107
|
+
return chalk.red(line);
|
|
108
|
+
}
|
|
109
|
+
return chalk.gray(line);
|
|
110
|
+
})
|
|
111
|
+
.join("\n");
|
|
112
|
+
}
|
|
88
113
|
export function renderDiff(filePath, diffText) {
|
|
89
|
-
salida.linea(`\n${diffText}\n`);
|
|
114
|
+
salida.linea(`\n${formatColorDiff(diffText)}\n`);
|
|
90
115
|
}
|
|
91
116
|
export function renderReasoning(reasoningText) {
|
|
92
117
|
if (!reasoningText.trim())
|
package/dist/ui/selector.js
CHANGED
|
@@ -56,6 +56,7 @@ async function elegirDeListaDirecto(titulo, opciones, indiceInicial = 0) {
|
|
|
56
56
|
}
|
|
57
57
|
function terminar(valor) {
|
|
58
58
|
process.stdin.removeListener("keypress", alPulsar);
|
|
59
|
+
process.stdout.removeListener("resize", onResize);
|
|
59
60
|
// Se devuelve el modo que habia, no se fuerza uno: si el prompt tenia el
|
|
60
61
|
// teclado en crudo y aqui se dejara en cocido, la sesion se queda sin
|
|
61
62
|
// poder escribir y no se sabe por que.
|
|
@@ -63,6 +64,10 @@ async function elegirDeListaDirecto(titulo, opciones, indiceInicial = 0) {
|
|
|
63
64
|
process.stdin.setRawMode(eraCrudo || false);
|
|
64
65
|
resolve(valor);
|
|
65
66
|
}
|
|
67
|
+
const onResize = () => {
|
|
68
|
+
pintar();
|
|
69
|
+
};
|
|
70
|
+
process.stdout.on("resize", onResize);
|
|
66
71
|
function alPulsar(_str, key) {
|
|
67
72
|
if (!key)
|
|
68
73
|
return;
|
package/dist/ui/spinner.d.ts
CHANGED
package/dist/ui/spinner.js
CHANGED
|
@@ -60,10 +60,15 @@ export class DynamicSpinner {
|
|
|
60
60
|
this.glyphIdx = 0;
|
|
61
61
|
this.verbIdx = 0;
|
|
62
62
|
this.tick();
|
|
63
|
+
process.stdout.on("resize", this.onResize);
|
|
63
64
|
this.timer = setInterval(() => {
|
|
64
65
|
this.tick();
|
|
65
66
|
}, 120);
|
|
66
67
|
}
|
|
68
|
+
onResize = () => {
|
|
69
|
+
if (this.isRunning)
|
|
70
|
+
this.tick();
|
|
71
|
+
};
|
|
67
72
|
tick() {
|
|
68
73
|
if (!this.isRunning)
|
|
69
74
|
return;
|
|
@@ -132,6 +137,7 @@ export class DynamicSpinner {
|
|
|
132
137
|
if (!this.isRunning)
|
|
133
138
|
return;
|
|
134
139
|
this.isRunning = false;
|
|
140
|
+
process.stdout.off("resize", this.onResize);
|
|
135
141
|
if (this.timer) {
|
|
136
142
|
clearInterval(this.timer);
|
|
137
143
|
this.timer = null;
|
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.6.
|
|
5
|
+
"version": "1.6.14",
|
|
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