chocolatito-code 1.0.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.
Files changed (140) hide show
  1. package/.mcp.json.ejemplo +19 -0
  2. package/COMPUTER-USE.md +484 -0
  3. package/LICENSE +21 -0
  4. package/README.md +186 -0
  5. package/dist/agent/context.d.ts +9 -0
  6. package/dist/agent/context.js +123 -0
  7. package/dist/agent/fileTracker.d.ts +16 -0
  8. package/dist/agent/fileTracker.js +53 -0
  9. package/dist/agent/loop.d.ts +25 -0
  10. package/dist/agent/loop.js +524 -0
  11. package/dist/agent/mentions.d.ts +11 -0
  12. package/dist/agent/mentions.js +43 -0
  13. package/dist/agent/retry.d.ts +17 -0
  14. package/dist/agent/retry.js +57 -0
  15. package/dist/agent/subagent.d.ts +2 -0
  16. package/dist/agent/subagent.js +116 -0
  17. package/dist/agent/syntaxValidator.d.ts +5 -0
  18. package/dist/agent/syntaxValidator.js +71 -0
  19. package/dist/agent/tracker.d.ts +19 -0
  20. package/dist/agent/tracker.js +38 -0
  21. package/dist/agent/undoManager.d.ts +37 -0
  22. package/dist/agent/undoManager.js +95 -0
  23. package/dist/config/constants.d.ts +77 -0
  24. package/dist/config/constants.js +146 -0
  25. package/dist/config/engine.d.ts +49 -0
  26. package/dist/config/engine.js +86 -0
  27. package/dist/config/env.d.ts +13 -0
  28. package/dist/config/env.js +103 -0
  29. package/dist/config/license.d.ts +39 -0
  30. package/dist/config/license.js +306 -0
  31. package/dist/config/permissions.d.ts +38 -0
  32. package/dist/config/permissions.js +239 -0
  33. package/dist/config/quota.d.ts +58 -0
  34. package/dist/config/quota.js +156 -0
  35. package/dist/hooks/manager.d.ts +60 -0
  36. package/dist/hooks/manager.js +193 -0
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.js +470 -0
  39. package/dist/mcp/client.d.ts +55 -0
  40. package/dist/mcp/client.js +282 -0
  41. package/dist/mcp/manager.d.ts +26 -0
  42. package/dist/mcp/manager.js +167 -0
  43. package/dist/memory/manager.d.ts +9 -0
  44. package/dist/memory/manager.js +59 -0
  45. package/dist/prompts/systemPrompt.d.ts +5 -0
  46. package/dist/prompts/systemPrompt.js +177 -0
  47. package/dist/sessions/manager.d.ts +21 -0
  48. package/dist/sessions/manager.js +54 -0
  49. package/dist/skills/manager.d.ts +14 -0
  50. package/dist/skills/manager.js +86 -0
  51. package/dist/tools/browserCdp.d.ts +26 -0
  52. package/dist/tools/browserCdp.js +610 -0
  53. package/dist/tools/browserExtension.d.ts +58 -0
  54. package/dist/tools/browserExtension.js +479 -0
  55. package/dist/tools/browserLive.d.ts +12 -0
  56. package/dist/tools/browserLive.js +265 -0
  57. package/dist/tools/changeDir.d.ts +5 -0
  58. package/dist/tools/changeDir.js +63 -0
  59. package/dist/tools/computerUse.d.ts +58 -0
  60. package/dist/tools/computerUse.js +567 -0
  61. package/dist/tools/createImage.d.ts +1 -0
  62. package/dist/tools/createImage.js +34 -0
  63. package/dist/tools/definitions.d.ts +8 -0
  64. package/dist/tools/definitions.js +401 -0
  65. package/dist/tools/deleteFile.d.ts +1 -0
  66. package/dist/tools/deleteFile.js +17 -0
  67. package/dist/tools/editFile.d.ts +5 -0
  68. package/dist/tools/editFile.js +88 -0
  69. package/dist/tools/findFiles.d.ts +1 -0
  70. package/dist/tools/findFiles.js +33 -0
  71. package/dist/tools/getSystemInfo.d.ts +1 -0
  72. package/dist/tools/getSystemInfo.js +23 -0
  73. package/dist/tools/gitTools.d.ts +3 -0
  74. package/dist/tools/gitTools.js +47 -0
  75. package/dist/tools/grepSearch.d.ts +1 -0
  76. package/dist/tools/grepSearch.js +37 -0
  77. package/dist/tools/listDir.d.ts +1 -0
  78. package/dist/tools/listDir.js +33 -0
  79. package/dist/tools/moveCopyFile.d.ts +1 -0
  80. package/dist/tools/moveCopyFile.js +21 -0
  81. package/dist/tools/runCommand.d.ts +1 -0
  82. package/dist/tools/runCommand.js +61 -0
  83. package/dist/tools/runner.d.ts +5 -0
  84. package/dist/tools/runner.js +177 -0
  85. package/dist/tools/safety.d.ts +17 -0
  86. package/dist/tools/safety.js +33 -0
  87. package/dist/tools/todoTool.d.ts +8 -0
  88. package/dist/tools/todoTool.js +27 -0
  89. package/dist/tools/toolDefsComputer.d.ts +13 -0
  90. package/dist/tools/toolDefsComputer.js +205 -0
  91. package/dist/tools/truncator.d.ts +11 -0
  92. package/dist/tools/truncator.js +24 -0
  93. package/dist/tools/viewFile.d.ts +1 -0
  94. package/dist/tools/viewFile.js +45 -0
  95. package/dist/tools/visionBridge.d.ts +37 -0
  96. package/dist/tools/visionBridge.js +107 -0
  97. package/dist/tools/webFetch.d.ts +1 -0
  98. package/dist/tools/webFetch.js +25 -0
  99. package/dist/tools/webSearch.d.ts +1 -0
  100. package/dist/tools/webSearch.js +35 -0
  101. package/dist/tools/win/hostClient.d.ts +31 -0
  102. package/dist/tools/win/hostClient.js +158 -0
  103. package/dist/tools/win/hostScript.d.ts +1 -0
  104. package/dist/tools/win/hostScript.js +925 -0
  105. package/dist/tools/writeFile.d.ts +1 -0
  106. package/dist/tools/writeFile.js +13 -0
  107. package/dist/ui/banner.d.ts +10 -0
  108. package/dist/ui/banner.js +165 -0
  109. package/dist/ui/diffViewer.d.ts +1 -0
  110. package/dist/ui/diffViewer.js +60 -0
  111. package/dist/ui/interrupt.d.ts +17 -0
  112. package/dist/ui/interrupt.js +156 -0
  113. package/dist/ui/markdownStream.d.ts +23 -0
  114. package/dist/ui/markdownStream.js +0 -0
  115. package/dist/ui/modes.d.ts +28 -0
  116. package/dist/ui/modes.js +57 -0
  117. package/dist/ui/permissionPrompt.d.ts +35 -0
  118. package/dist/ui/permissionPrompt.js +271 -0
  119. package/dist/ui/prompt.d.ts +7 -0
  120. package/dist/ui/prompt.js +466 -0
  121. package/dist/ui/reasoningStream.d.ts +6 -0
  122. package/dist/ui/reasoningStream.js +38 -0
  123. package/dist/ui/renderer.d.ts +10 -0
  124. package/dist/ui/renderer.js +142 -0
  125. package/dist/ui/spinner.d.ts +24 -0
  126. package/dist/ui/spinner.js +111 -0
  127. package/dist/ui/theme.d.ts +36 -0
  128. package/dist/ui/theme.js +37 -0
  129. package/dist/ui/typeAhead.d.ts +31 -0
  130. package/dist/ui/typeAhead.js +87 -0
  131. package/extension/README.md +74 -0
  132. package/extension/background.js +575 -0
  133. package/extension/content.js +446 -0
  134. package/extension/manifest.json +36 -0
  135. package/extension/popup.html +22 -0
  136. package/extension/popup.js +12 -0
  137. package/package.json +66 -0
  138. package/skills/complex-refactor/SKILL.md +13 -0
  139. package/skills/deep-debugger/SKILL.md +14 -0
  140. package/skills/software-architect/SKILL.md +20 -0
@@ -0,0 +1,271 @@
1
+ import readline from "node:readline";
2
+ import process from "node:process";
3
+ import chalk from "chalk";
4
+ import { cycleMode, describeMode, getMode, modeAnnouncement } from "./modes.js";
5
+ /**
6
+ * Aprobacion automatica: se activa con --yes / -y o con la variable de entorno
7
+ * CHOCOLATITO_AUTO_APPROVE. Pensada para modo no interactivo y CI.
8
+ */
9
+ let autoApprove = process.env.CHOCOLATITO_AUTO_APPROVE === "1";
10
+ export function setAutoApprove(value) {
11
+ autoApprove = value;
12
+ }
13
+ /**
14
+ * DIALOGO DE PERMISO
15
+ *
16
+ * La version anterior tenia dos fallos visibles en cuanto se usaba:
17
+ *
18
+ * 1. Al mover la seleccion subia el cursor 12 lineas fijas, pero la caja mide
19
+ * entre 10 y 14 segun cuantos detalles tenga. Cada flecha dejaba media caja
20
+ * huerfana en pantalla, y por eso salian marcos vacios apilados.
21
+ *
22
+ * 2. El titulo llevaba un simbolo de anchura ambigua. El terminal lo pinta
23
+ * ocupando dos columnas y el calculo del ancho contaba una, asi que el borde
24
+ * derecho quedaba descuadrado justo en esa linea.
25
+ *
26
+ * Aqui se dibuja la caja a mano, con anchura conocida, y se repinta subiendo
27
+ * exactamente las lineas que se escribieron.
28
+ */
29
+ export async function askToolPermission(toolName, args, cwd = process.cwd()) {
30
+ if (autoApprove) {
31
+ return { approved: true };
32
+ }
33
+ // Sin terminal interactiva no hay nadie que pueda contestar. Antes el agente
34
+ // se quedaba colgado para siempre esperando una tecla que nunca llegaba, y en
35
+ // modo `chocolatito "tarea"` o en CI eso es un bloqueo silencioso. Ante la
36
+ // duda se deniega, que es lo seguro, y se explica como autorizar.
37
+ if (!process.stdin.isTTY) {
38
+ return {
39
+ approved: false,
40
+ userFeedback: `No hay terminal interactiva para pedir permiso de "${toolName}". ` +
41
+ `Vuelve a lanzarlo con --yes (o CHOCOLATITO_AUTO_APPROVE=1) si quieres aprobar automaticamente, ` +
42
+ `o ejecuta el comando tu mismo.`,
43
+ };
44
+ }
45
+ return new Promise((resolve) => {
46
+ let selectedIndex = 0;
47
+ const options = PERMISSION_OPTIONS;
48
+ const kind = classify(toolName, args);
49
+ const width = boxWidth();
50
+ const wasRaw = process.stdin.isRaw;
51
+ if (process.stdin.setRawMode)
52
+ process.stdin.setRawMode(true);
53
+ process.stdin.resume();
54
+ /** Lineas que ocupa el ultimo dibujo, para poder repintarlo sin dejar restos. */
55
+ let renderedRows = 0;
56
+ function draw() {
57
+ if (renderedRows > 0) {
58
+ // Se sube justo lo que se escribio: ni una linea mas, ni una menos.
59
+ process.stdout.write(`\x1b[${renderedRows}A`);
60
+ }
61
+ const lines = buildPermissionBox(toolName, args, cwd, selectedIndex, width);
62
+ // Cada linea se limpia antes de escribirse: si el dibujo anterior era mas
63
+ // ancho, no queda cola a la derecha.
64
+ process.stdout.write(lines.map((l) => `\r\x1b[2K${l}`).join("\n") + "\n");
65
+ renderedRows = lines.length;
66
+ }
67
+ draw();
68
+ function cleanup() {
69
+ process.stdin.removeListener("keypress", onKeypress);
70
+ if (process.stdin.setRawMode)
71
+ process.stdin.setRawMode(wasRaw || false);
72
+ }
73
+ async function promptForFeedback() {
74
+ cleanup();
75
+ return new Promise((resFeedback) => {
76
+ const rl = readline.createInterface({
77
+ input: process.stdin,
78
+ output: process.stdout,
79
+ });
80
+ rl.question(chalk.hex("#A855F7")("\n¿Qué prefieres que haga? ❯ "), (answer) => {
81
+ rl.close();
82
+ resFeedback(answer.trim() || "El usuario canceló la acción sin dar detalles adicionales.");
83
+ });
84
+ });
85
+ }
86
+ async function onKeypress(str, key) {
87
+ // Shift+Tab desde el propio dialogo: cambia de modo instantáneamente
88
+ const isShiftTab = Boolean(key && key.name === "tab" && key.shift) ||
89
+ str === "\x1b[Z" ||
90
+ Boolean(key && key.sequence === "\x1b[Z");
91
+ if (isShiftTab) {
92
+ const nuevo = cycleMode();
93
+ if (nuevo === "bypass") {
94
+ cleanup();
95
+ process.stdout.write(`\r\x1b[2K${modeAnnouncement(nuevo)}\n`);
96
+ resolve({ approved: true });
97
+ return;
98
+ }
99
+ process.stdout.write(`\r\x1b[2K${modeAnnouncement(nuevo)}\n`);
100
+ renderedRows = 0;
101
+ draw();
102
+ return;
103
+ }
104
+ if (key && (key.name === "return" || key.name === "enter")) {
105
+ if (selectedIndex === 0) {
106
+ cleanup();
107
+ resolve({ approved: true });
108
+ }
109
+ else if (selectedIndex === 1) {
110
+ cleanup();
111
+ resolve({ approved: true, rememberPattern: true });
112
+ }
113
+ else {
114
+ const feedback = await promptForFeedback();
115
+ resolve({ approved: false, userFeedback: feedback });
116
+ }
117
+ return;
118
+ }
119
+ if (key && key.name === "escape") {
120
+ cleanup();
121
+ resolve({ approved: false, userFeedback: "Cancelado por el usuario con la tecla Esc." });
122
+ return;
123
+ }
124
+ if (str === "1") {
125
+ cleanup();
126
+ resolve({ approved: true });
127
+ return;
128
+ }
129
+ if (str === "2") {
130
+ cleanup();
131
+ resolve({ approved: true, rememberPattern: true });
132
+ return;
133
+ }
134
+ if (str === "3") {
135
+ const feedback = await promptForFeedback();
136
+ resolve({ approved: false, userFeedback: feedback });
137
+ return;
138
+ }
139
+ if (key && (key.name === "up" || key.name === "down")) {
140
+ const delta = key.name === "up" ? -1 : 1;
141
+ selectedIndex = (selectedIndex + delta + options.length) % options.length;
142
+ draw();
143
+ return;
144
+ }
145
+ if (key && key.ctrl && key.name === "c") {
146
+ cleanup();
147
+ process.stdout.write("\n");
148
+ process.exit(0);
149
+ }
150
+ }
151
+ process.stdin.on("keypress", onKeypress);
152
+ });
153
+ }
154
+ // ---------------------------------------------------------------------------
155
+ // Dibujo de la caja.
156
+ //
157
+ // Se hace a mano en vez de con una libreria porque hay que saber con exactitud
158
+ // cuantas lineas ocupa y cuanto mide el texto sin los codigos de color. Los
159
+ // simbolos usados son de anchura fija: nada de emoji, que es lo que descuadraba
160
+ // el borde derecho.
161
+ const H = "─";
162
+ export const PERMISSION_OPTIONS = [
163
+ { label: "Sí, adelante", hint: "solo esta vez" },
164
+ { label: "Sí, y no preguntar más por esto", hint: "lo recuerda en este proyecto" },
165
+ { label: "No, prefiero decirte otra cosa", hint: "cancela y te lo explico" },
166
+ ];
167
+ /**
168
+ * Construye el dialogo entero como lista de lineas.
169
+ *
170
+ * Es una funcion pura a proposito: asi se puede comprobar en una prueba que
171
+ * todas las lineas del marco miden exactamente lo mismo. El descuadre del borde
172
+ * derecho no se ve leyendo el codigo, solo ejecutandolo.
173
+ */
174
+ export function buildPermissionBox(toolName, args, cwd, selectedIndex, width = boxWidth()) {
175
+ const kind = classify(toolName, args);
176
+ const lines = [];
177
+ lines.push(top(width, kind.color));
178
+ lines.push(row(chalk.bold.hex(kind.color)(kind.title), width, kind.color, kind.title.length));
179
+ for (const d of details(toolName, args, cwd, width)) {
180
+ lines.push(row(d.text, width, kind.color, d.length));
181
+ }
182
+ PERMISSION_OPTIONS.forEach((opt, idx) => {
183
+ const sel = idx === selectedIndex;
184
+ const marker = sel ? "❯" : " ";
185
+ const num = `${idx + 1}.`;
186
+ const cabeza = ` ${marker} ${num} ${opt.label}`;
187
+ // La pista es lo primero que se cae si no cabe: perder el marco por una
188
+ // aclaración opcional es peor que quedarse sin la aclaración.
189
+ const conPista = `${cabeza} ${opt.hint}`;
190
+ const cabe = conPista.length <= width - 3;
191
+ const plain = cabe ? conPista : cabeza;
192
+ const etiqueta = sel ? chalk.bold.white(opt.label) : chalk.gray(opt.label);
193
+ const flecha = sel ? chalk.hex(kind.color)(marker) : marker;
194
+ const painted = ` ${flecha} ${chalk.gray(num)} ${etiqueta}${cabe ? ` ${chalk.gray(opt.hint)}` : ""}`;
195
+ lines.push(row(painted, width, kind.color, plain.length));
196
+ });
197
+ lines.push(bottom(width, kind.color));
198
+ const modo = describeMode(getMode());
199
+ lines.push(chalk.gray(" ↑↓ o 1-3 · enter confirma · esc cancela · ") +
200
+ chalk.hex(modo.color)("shift+tab") +
201
+ chalk.gray(" cambia a modo automático"));
202
+ return lines;
203
+ }
204
+ function boxWidth() {
205
+ const cols = process.stdout.columns || 80;
206
+ return Math.max(48, Math.min(96, cols - 4));
207
+ }
208
+ function top(width, color) {
209
+ return chalk.hex(color)(`╭${H.repeat(width - 2)}╮`);
210
+ }
211
+ function bottom(width, color) {
212
+ return chalk.hex(color)(`╰${H.repeat(width - 2)}╯`);
213
+ }
214
+ /** Una fila del marco. `plainLength` es el ancho real del texto ya pintado. */
215
+ function row(painted, width, color, plainLength) {
216
+ const inner = width - 2;
217
+ const relleno = Math.max(0, inner - plainLength);
218
+ const bar = chalk.hex(color)("│");
219
+ return `${bar}${painted}${" ".repeat(relleno)}${bar}`;
220
+ }
221
+ function classify(toolName, args) {
222
+ if (toolName === "delete_file")
223
+ return { title: " Borrar un archivo", color: "#EF4444" };
224
+ if (toolName === "run_command")
225
+ return { title: " Ejecutar un comando", color: "#F59E0B" };
226
+ if (toolName === "edit_file" || toolName === "write_file") {
227
+ return { title: " Escribir en un archivo", color: "#D97757" };
228
+ }
229
+ if (toolName === "move_copy_file")
230
+ return { title: " Mover o copiar un archivo", color: "#D97757" };
231
+ if (toolName === "chrome" || toolName === "browser" || toolName === "browser_live") {
232
+ return { title: " Controlar tu navegador", color: "#A855F7" };
233
+ }
234
+ if (toolName === "computer_use")
235
+ return { title: " Controlar tu ordenador", color: "#A855F7" };
236
+ return { title: " Permiso de ejecución", color: "#D97757" };
237
+ }
238
+ /** Las lineas de detalle, ya recortadas para que quepan dentro del marco. */
239
+ function details(toolName, args, cwd, width) {
240
+ const max = width - 8;
241
+ const out = [];
242
+ const add = (plain, painted) => {
243
+ const corto = plain.length > max ? `${plain.slice(0, max - 1)}…` : plain;
244
+ const texto = painted && plain.length <= max ? painted : chalk.white(corto);
245
+ out.push({ text: ` ${texto}`, length: corto.length + 2 });
246
+ };
247
+ out.push({ text: "", length: 0 });
248
+ if (typeof args.command === "string") {
249
+ add(args.command, chalk.bold.white(args.command));
250
+ add(`en ${cwd}`, chalk.gray(`en ${cwd}`));
251
+ }
252
+ else if (typeof args.path === "string") {
253
+ add(args.path, chalk.bold.white(args.path));
254
+ if (typeof args.oldText === "string" && typeof args.newText === "string") {
255
+ const mas = args.newText.split("\n").length;
256
+ const menos = args.oldText.split("\n").length;
257
+ const plain = `+${mas} líneas -${menos} líneas`;
258
+ add(plain, `${chalk.green(`+${mas} líneas`)} ${chalk.red(`-${menos} líneas`)}`);
259
+ }
260
+ }
261
+ else if (typeof args.action === "string") {
262
+ const extra = args.url || args.appName || args.window || args.text || "";
263
+ const plain = extra ? `${args.action} ${String(extra)}` : String(args.action);
264
+ add(plain, extra ? `${chalk.bold.white(args.action)} ${chalk.gray(String(extra))}` : chalk.bold.white(args.action));
265
+ }
266
+ else {
267
+ add(toolName, chalk.bold.white(toolName));
268
+ }
269
+ out.push({ text: "", length: 0 });
270
+ return out;
271
+ }
@@ -0,0 +1,7 @@
1
+ export interface SlashCommandItem {
2
+ name: string;
3
+ description: string;
4
+ args?: string;
5
+ }
6
+ export declare const SLASH_COMMANDS: SlashCommandItem[];
7
+ export declare function askInteractivePrompt(promptSymbol?: string, cwd?: string): Promise<string>;