chocolatito-code 1.0.0 → 1.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.
Files changed (102) hide show
  1. package/README.md +89 -0
  2. package/dist/agent/compaction.d.ts +65 -0
  3. package/dist/agent/compaction.js +134 -0
  4. package/dist/agent/context.d.ts +3 -0
  5. package/dist/agent/context.js +35 -0
  6. package/dist/agent/loop.d.ts +91 -2
  7. package/dist/agent/loop.js +536 -78
  8. package/dist/agent/loopDetector.d.ts +57 -0
  9. package/dist/agent/loopDetector.js +0 -0
  10. package/dist/agent/mentions.d.ts +13 -0
  11. package/dist/agent/mentions.js +49 -0
  12. package/dist/agent/repoMap.d.ts +117 -0
  13. package/dist/agent/repoMap.js +560 -0
  14. package/dist/agent/result.d.ts +64 -0
  15. package/dist/agent/result.js +48 -0
  16. package/dist/agent/retry.d.ts +35 -0
  17. package/dist/agent/retry.js +123 -4
  18. package/dist/agent/subagent.js +62 -15
  19. package/dist/agent/syntaxValidator.js +288 -52
  20. package/dist/agent/toolGate.d.ts +58 -0
  21. package/dist/agent/toolGate.js +111 -0
  22. package/dist/agent/tracker.js +4 -7
  23. package/dist/agent/undoManager.d.ts +44 -11
  24. package/dist/agent/undoManager.js +95 -24
  25. package/dist/agent/usageMeter.d.ts +56 -0
  26. package/dist/agent/usageMeter.js +51 -0
  27. package/dist/agent/verifier.d.ts +49 -0
  28. package/dist/agent/verifier.js +158 -0
  29. package/dist/config/constants.js +14 -0
  30. package/dist/config/engine.d.ts +19 -0
  31. package/dist/config/engine.js +35 -3
  32. package/dist/config/license.d.ts +5 -0
  33. package/dist/config/license.js +107 -9
  34. package/dist/config/limits.d.ts +28 -0
  35. package/dist/config/limits.js +51 -0
  36. package/dist/config/permissions.d.ts +76 -1
  37. package/dist/config/permissions.js +379 -23
  38. package/dist/config/quota.js +24 -1
  39. package/dist/config/updater.d.ts +68 -0
  40. package/dist/config/updater.js +215 -0
  41. package/dist/hooks/manager.js +159 -14
  42. package/dist/index.js +222 -34
  43. package/dist/mcp/client.d.ts +22 -0
  44. package/dist/mcp/client.js +93 -11
  45. package/dist/prompts/systemPrompt.js +12 -1
  46. package/dist/sessions/manager.d.ts +12 -0
  47. package/dist/sessions/manager.js +33 -5
  48. package/dist/sessions/resume.d.ts +36 -0
  49. package/dist/sessions/resume.js +43 -0
  50. package/dist/skills/manager.d.ts +1 -0
  51. package/dist/skills/manager.js +9 -0
  52. package/dist/tools/binary.d.ts +46 -0
  53. package/dist/tools/binary.js +100 -0
  54. package/dist/tools/browserCdp.js +13 -1
  55. package/dist/tools/browserExtension.d.ts +5 -0
  56. package/dist/tools/browserExtension.js +202 -18
  57. package/dist/tools/browserSession.d.ts +23 -0
  58. package/dist/tools/browserSession.js +28 -0
  59. package/dist/tools/computerUse.js +33 -1
  60. package/dist/tools/createImage.d.ts +11 -0
  61. package/dist/tools/createImage.js +13 -1
  62. package/dist/tools/definitions.js +9 -3
  63. package/dist/tools/editDiagnosis.d.ts +54 -0
  64. package/dist/tools/editDiagnosis.js +142 -0
  65. package/dist/tools/editFile.d.ts +1 -0
  66. package/dist/tools/editFile.js +118 -62
  67. package/dist/tools/findFiles.d.ts +21 -0
  68. package/dist/tools/findFiles.js +75 -6
  69. package/dist/tools/getSystemInfo.js +15 -7
  70. package/dist/tools/gitTools.d.ts +24 -0
  71. package/dist/tools/gitTools.js +87 -26
  72. package/dist/tools/moveCopyFile.d.ts +18 -1
  73. package/dist/tools/moveCopyFile.js +74 -4
  74. package/dist/tools/patchCascade.d.ts +57 -0
  75. package/dist/tools/patchCascade.js +338 -0
  76. package/dist/tools/runCommand.js +213 -25
  77. package/dist/tools/runner.js +57 -4
  78. package/dist/tools/toolDefsComputer.js +12 -2
  79. package/dist/tools/truncator.d.ts +27 -1
  80. package/dist/tools/truncator.js +117 -11
  81. package/dist/tools/viewFile.js +15 -11
  82. package/dist/tools/visionBridge.js +7 -0
  83. package/dist/tools/webSearch.d.ts +21 -0
  84. package/dist/tools/webSearch.js +125 -14
  85. package/dist/tools/writeFile.js +18 -1
  86. package/dist/ui/interrupt.d.ts +4 -1
  87. package/dist/ui/interrupt.js +56 -5
  88. package/dist/ui/keyboardGuard.d.ts +55 -0
  89. package/dist/ui/keyboardGuard.js +65 -0
  90. package/dist/ui/loopPrompt.d.ts +17 -0
  91. package/dist/ui/loopPrompt.js +59 -0
  92. package/dist/ui/permissionPrompt.js +84 -2
  93. package/dist/ui/prompt.d.ts +35 -0
  94. package/dist/ui/prompt.js +345 -125
  95. package/dist/ui/reasoningStream.d.ts +8 -0
  96. package/dist/ui/reasoningStream.js +99 -7
  97. package/extension/README.md +95 -74
  98. package/extension/background.js +598 -178
  99. package/extension/content.js +92 -9
  100. package/extension/manifest.json +2 -1
  101. package/extension/popup.js +28 -12
  102. package/package.json +1 -1
@@ -155,12 +155,43 @@
155
155
  function norm(s) {
156
156
  return (s || "")
157
157
  .normalize("NFD")
158
+ // Rango de diacriticos combinantes. Escrito con escapes y no con los
159
+ // caracteres literales: en el fuente eran invisibles y cualquier editor
160
+ // que "normalizara" el archivo se los llevaba por delante sin que nadie
161
+ // lo notara hasta que el filtro dejaba de casar acentos.
158
162
  .replace(/[̀-ͯ]/g, "")
159
163
  .toLowerCase();
160
164
  }
161
165
 
162
- function buildSnapshot(startIndex, filter) {
163
- if (startIndex === 0) refIdentity.clear();
166
+ /**
167
+ * Quita las marcas del snapshot anterior.
168
+ *
169
+ * data-choco-ref se escribia en los elementos de la pagina del usuario y no
170
+ * lo borraba nadie: los atributos se acumulaban snapshot tras snapshot, y un
171
+ * ref viejo podia seguir resolviendo a un elemento que ya no estaba en la
172
+ * lista actual.
173
+ */
174
+ function limpiarMarcas() {
175
+ for (const root of allRoots()) {
176
+ let marcados;
177
+ try {
178
+ marcados = root.querySelectorAll("[data-choco-ref]");
179
+ } catch (_) {
180
+ continue;
181
+ }
182
+ for (const el of marcados) el.removeAttribute("data-choco-ref");
183
+ }
184
+ }
185
+
186
+ function buildSnapshot(startIndex, filter, nuevo) {
187
+ // Antes esto era `startIndex === 0`, que solo es cierto en el PRIMER frame.
188
+ // Cada frame tiene su propio content script con su propia tabla, asi que
189
+ // los subframes no la limpiaban nunca: acumulaban identidades de snapshots
190
+ // viejos y un ref podia resolver a un boton que ya no era ese.
191
+ if (nuevo || startIndex === 0) {
192
+ refIdentity.clear();
193
+ limpiarMarcas();
194
+ }
164
195
  const out = [];
165
196
  let idx = startIndex;
166
197
  const f = norm(filter);
@@ -324,13 +355,52 @@
324
355
  return true;
325
356
  }
326
357
 
358
+ /**
359
+ * Codigos de tecla.
360
+ *
361
+ * La tabla tenia siete entradas y todo lo demas salia con keyCode 0, que para
362
+ * un manejador que mira `e.keyCode` o `e.which` -que son casi todos los que
363
+ * existen desde antes de 2018- equivale a "no se ha pulsado nada". Escribir
364
+ * una letra suelta o un Espacio con press no hacia absolutamente nada.
365
+ */
366
+ const CODIGOS = {
367
+ Enter: 13, Escape: 27, Esc: 27, Tab: 9, Backspace: 8, Delete: 46,
368
+ ArrowUp: 38, ArrowDown: 40, ArrowLeft: 37, ArrowRight: 39,
369
+ Home: 36, End: 35, PageUp: 33, PageDown: 34, Insert: 45,
370
+ " ": 32, Space: 32, Shift: 16, Control: 17, Alt: 18,
371
+ F1: 112, F2: 113, F3: 114, F4: 115, F5: 116, F6: 117,
372
+ F7: 118, F8: 119, F9: 120, F10: 121, F11: 122, F12: 123,
373
+ };
374
+
375
+ /** Nombre DOM del codigo fisico ("KeyA", "Digit1", "Space"...). */
376
+ function codigoFisico(key) {
377
+ if (key === " " || key === "Space") return "Space";
378
+ if (/^[a-zA-Z]$/.test(key)) return "Key" + key.toUpperCase();
379
+ if (/^[0-9]$/.test(key)) return "Digit" + key;
380
+ return key;
381
+ }
382
+
327
383
  function pressKey(el, key) {
328
384
  const target = el || document.activeElement || document.body;
329
- const map = { Enter: 13, Escape: 27, Tab: 9, Backspace: 8, Delete: 46, ArrowUp: 38, ArrowDown: 40 };
330
- const code = map[key] || 0;
331
- const init = { key, code: key, keyCode: code, which: code, bubbles: true, cancelable: true, composed: true };
385
+ const nombre = key === "Space" ? " " : key;
386
+ const code = CODIGOS[key] !== undefined
387
+ ? CODIGOS[key]
388
+ : nombre.length === 1
389
+ ? nombre.toUpperCase().charCodeAt(0)
390
+ : 0;
391
+ const init = {
392
+ key: nombre,
393
+ code: codigoFisico(key),
394
+ keyCode: code,
395
+ which: code,
396
+ bubbles: true,
397
+ cancelable: true,
398
+ composed: true,
399
+ };
332
400
  target.dispatchEvent(new KeyboardEvent("keydown", init));
333
- target.dispatchEvent(new KeyboardEvent("keypress", init));
401
+ // keypress solo existe para las teclas que producen caracter. Emitirlo para
402
+ // Escape o las flechas es inventarse un evento que el navegador nunca manda.
403
+ if (nombre.length === 1) target.dispatchEvent(new KeyboardEvent("keypress", init));
334
404
  target.dispatchEvent(new KeyboardEvent("keyup", init));
335
405
  // Si es un formulario y la tecla es Enter, se intenta enviar de verdad.
336
406
  if (key === "Enter" && target.form && typeof target.form.requestSubmit === "function") {
@@ -355,7 +425,7 @@
355
425
  break;
356
426
 
357
427
  case "snapshot": {
358
- const items = buildSnapshot(msg.startIndex || 0, msg.filter || "");
428
+ const items = buildSnapshot(msg.startIndex || 0, msg.filter || "", msg.nuevo === true);
359
429
  sendResponse({ ok: true, items, url: location.href, title: document.title, top: IS_TOP });
360
430
  break;
361
431
  }
@@ -425,13 +495,26 @@
425
495
  break;
426
496
 
427
497
  case "eval": {
498
+ // Un objeto salia como "[object Object]", que no dice nada: quien
499
+ // pedia document.querySelectorAll('a').length lo tenia bien, pero
500
+ // quien pedia el objeto entero recibia ruido y volvia a intentarlo.
428
501
  let out;
429
502
  try {
430
- out = String(eval(msg.script));
503
+ const valor = eval(msg.script);
504
+ if (valor === undefined) out = "undefined";
505
+ else if (valor === null) out = "null";
506
+ else if (typeof valor === "object") {
507
+ try {
508
+ out = JSON.stringify(valor, null, 2);
509
+ if (out === undefined) out = String(valor); // referencias circulares
510
+ } catch (_) {
511
+ out = String(valor);
512
+ }
513
+ } else out = String(valor);
431
514
  } catch (e) {
432
515
  out = "Error JS: " + (e && e.message ? e.message : e);
433
516
  }
434
- sendResponse({ ok: true, result: out });
517
+ sendResponse({ ok: true, result: String(out).slice(0, 20000) });
435
518
  break;
436
519
  }
437
520
 
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "manifest_version": 3,
3
+ "minimum_chrome_version": "102",
3
4
  "name": "Chocolatito Code",
4
- "version": "1.0.0",
5
+ "version": "1.2.0",
5
6
  "description": "Deja que Chocolatito Code trabaje dentro de tu Chrome, en segundo plano y con tus sesiones ya iniciadas.",
6
7
  "permissions": [
7
8
  "tabs",
@@ -1,12 +1,28 @@
1
- // Estado de la conexion con la CLI. El badge lo pone el service worker; aqui
2
- // solo se traduce a algo legible para el usuario.
3
- chrome.action.getBadgeText({}, (text) => {
4
- const on = text === "on";
5
- document.getElementById("dot").className = "dot" + (on ? " on" : "");
6
- document.getElementById("state").textContent = on
7
- ? "Conectado a la CLI"
8
- : "Sin conexion con la CLI";
9
- document.getElementById("hint").innerHTML = on
10
- ? "El agente puede trabajar en tus pestanas en segundo plano."
11
- : 'Arranca <code>chocolatito</code> en la terminal y esta pestana se conectara sola.';
12
- });
1
+ /**
2
+ * Estado de la conexion con la CLI. El badge lo pone el service worker; aqui
3
+ * solo se traduce a algo legible.
4
+ *
5
+ * Aqui se comparaba el badge con la cadena "on", y el service worker nunca
6
+ * escribe eso: escribe el NUMERO de sesiones conectadas ("1", "2") o vacio. La
7
+ * comparacion no se cumplia jamas, asi que el popup decia "Sin conexion con la
8
+ * CLI" incluso con el agente trabajando delante. Es el unico sitio donde el
9
+ * usuario puede comprobar si la extension funciona, y siempre mentia.
10
+ */
11
+ chrome.action.getBadgeText({}, (text) => {
12
+ const sesiones = Number(text);
13
+ const conectadas = Number.isFinite(sesiones) && sesiones > 0 ? sesiones : 0;
14
+
15
+ document.getElementById("dot").className = "dot" + (conectadas > 0 ? " on" : "");
16
+
17
+ document.getElementById("state").textContent =
18
+ conectadas === 0
19
+ ? "Sin conexion con la CLI"
20
+ : conectadas === 1
21
+ ? "Conectado a la CLI"
22
+ : `Conectado a ${conectadas} sesiones`;
23
+
24
+ document.getElementById("hint").innerHTML =
25
+ conectadas > 0
26
+ ? "El agente puede trabajar en tus pestanas en segundo plano."
27
+ : 'Arranca <code>chocolatito</code> en la terminal y esta pestana se conectara sola.';
28
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chocolatito-code",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
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": {