chocolatito-code 1.6.13 → 1.6.15

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.
Files changed (49) hide show
  1. package/COMPUTER-USE.md +37 -0
  2. package/README.md +29 -3
  3. package/dist/agent/historialDeCambios.d.ts +77 -0
  4. package/dist/agent/historialDeCambios.js +220 -0
  5. package/dist/agent/salidaDelAgente.d.ts +9 -0
  6. package/dist/agent/salidaDelAgente.js +19 -0
  7. package/dist/agent/undoManager.d.ts +21 -0
  8. package/dist/agent/undoManager.js +85 -5
  9. package/dist/config/permissions.js +4 -0
  10. package/dist/index.js +216 -27
  11. package/dist/prompts/systemPrompt.js +15 -11
  12. package/dist/servidor/archivos.d.ts +69 -0
  13. package/dist/servidor/archivos.js +156 -0
  14. package/dist/servidor/captura.d.ts +9 -0
  15. package/dist/servidor/captura.js +48 -0
  16. package/dist/servidor/fondo.d.ts +85 -0
  17. package/dist/servidor/fondo.js +134 -0
  18. package/dist/servidor/marca.d.ts +14 -0
  19. package/dist/servidor/marca.js +14 -0
  20. package/dist/servidor/pagina.d.ts +0 -26
  21. package/dist/servidor/pagina.js +337 -10
  22. package/dist/servidor/puente.d.ts +13 -0
  23. package/dist/servidor/puente.js +11 -0
  24. package/dist/servidor/servidor.d.ts +76 -2
  25. package/dist/servidor/servidor.js +245 -13
  26. package/dist/tools/computerUse.d.ts +11 -1
  27. package/dist/tools/computerUse.js +376 -34
  28. package/dist/tools/toolDefsComputer.js +39 -14
  29. package/dist/tools/visionBridge.d.ts +4 -2
  30. package/dist/tools/visionBridge.js +40 -15
  31. package/dist/tools/win/hostScript.js +300 -29
  32. package/dist/ui/comandos.js +1 -0
  33. package/dist/ui/ink/App.js +23 -3
  34. package/dist/ui/ink/Prompt.d.ts +5 -1
  35. package/dist/ui/ink/Prompt.js +92 -4
  36. package/dist/ui/ink/control.d.ts +2 -0
  37. package/dist/ui/ink/control.js +15 -0
  38. package/dist/ui/ink/montarApp.d.ts +0 -19
  39. package/dist/ui/ink/montarApp.js +3 -0
  40. package/dist/ui/permissionPrompt.js +44 -9
  41. package/dist/ui/pieFijo.js +5 -0
  42. package/dist/ui/prompt.js +6 -0
  43. package/dist/ui/renderer.d.ts +1 -0
  44. package/dist/ui/renderer.js +27 -2
  45. package/dist/ui/selector.js +5 -0
  46. package/dist/ui/spinner.d.ts +1 -0
  47. package/dist/ui/spinner.js +6 -0
  48. package/extension/manifest.json +1 -1
  49. package/package.json +1 -1
@@ -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 = Math.max(20, stdout?.columns || 80);
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 ?? stdout?.rows ?? 24);
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();
@@ -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;
@@ -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;
@@ -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
- const objetivo = args.url || args.appName || args.window || args.text ||
335
- (typeof args.tabId === "number" ? `pestaña ${args.tabId}` : "") ||
336
- (typeof args.ref === "number" ? `elemento [${args.ref}]` : "") ||
337
- "";
338
- const extra = objetivo || (esNavegador(toolName) ? "en la pestaña de trabajo" : "");
339
- const plain = extra ? `${args.action} ${String(extra)}` : String(args.action);
340
- add(plain, extra ? `${chalk.bold.white(args.action)} ${chalk.gray(String(extra))}` : chalk.bold.white(args.action));
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));
@@ -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
  });
@@ -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;
@@ -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 argPart = summary ? chalk.gray(`(${summary.length > 60 ? summary.slice(0, 57) + '...' : summary})`) : "";
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())
@@ -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;
@@ -14,6 +14,7 @@ export declare class DynamicSpinner {
14
14
  */
15
15
  setPrefijo(prefijo: string): void;
16
16
  start(initialPrefix?: string): void;
17
+ private onResize;
17
18
  private tick;
18
19
  /**
19
20
  * `✳ Compactando historial… (3s · ↓ 1.2k tokens · esc para pausar) ⇥ modo`
@@ -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;
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "minimum_chrome_version": "102",
4
4
  "name": "Chocolatito Code",
5
- "version": "1.6.13",
5
+ "version": "1.6.15",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chocolatito-code",
3
- "version": "1.6.13",
3
+ "version": "1.6.15",
4
4
  "description": "Agente autónomo de programación para la terminal, con control real del ordenador y del navegador. Desarrollado por Chocolatito.",
5
5
  "type": "module",
6
6
  "bin": {