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
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Detector de bucles: el agente repitiendo la misma accion sin avanzar.
3
+ *
4
+ * Hasta ahora la unica defensa era el tope de 30 iteraciones del turno. Un
5
+ * agente atascado —reintentando el mismo edit_file que falla, releyendo el
6
+ * mismo archivo, relanzando el mismo comando roto— se gastaba las 30 enteras,
7
+ * con su coste real en la cuota del usuario, antes de que nadie lo parara. Y
8
+ * como el error que recibia era siempre el mismo texto, nada le empujaba a
9
+ * cambiar de estrategia.
10
+ *
11
+ * Dos decisiones copiadas de opencode y Crush, y las dos importan:
12
+ *
13
+ * 1. **Estar atascado no es un error, es una pregunta.** No se aborta el
14
+ * turno: se le pregunta al usuario, que es quien sabe si el agente esta
15
+ * dando vueltas o esperando algo legitimamente.
16
+ *
17
+ * 2. **La firma incluye el RESULTADO, no solo la llamada.** Es lo que separa
18
+ * un bucle de un sondeo: leer el mismo log cinco veces mientras cambia es
19
+ * trabajo normal; leerlo cinco veces con la misma respuesta byte a byte es
20
+ * dar vueltas. Con la firma solo sobre los argumentos, toda paginacion y
21
+ * todo polling darian falso positivo.
22
+ */
23
+ /** Repeticiones identicas seguidas antes de preguntar. */
24
+ export declare const UMBRAL_BUCLE = 3;
25
+ export interface AvisoDeBucle {
26
+ herramienta: string;
27
+ repeticiones: number;
28
+ }
29
+ export declare class DetectorDeBucle {
30
+ private firmas;
31
+ /** Herramientas para las que el usuario ya dijo "dejalo seguir". */
32
+ private perdonadas;
33
+ /**
34
+ * Apunta una llamada ya ejecutada. Devuelve el aviso si las ultimas
35
+ * UMBRAL_BUCLE llamadas son identicas entre si.
36
+ */
37
+ registrar(herramienta: string, argumentos: string, resultado: string): AvisoDeBucle | null;
38
+ /**
39
+ * El usuario dejo seguir. No se vuelve a preguntar por esa herramienta en el
40
+ * turno: preguntar dos veces por lo mismo es peor que no preguntar.
41
+ */
42
+ perdonar(herramienta: string): void;
43
+ /**
44
+ * Se corto el bucle. Se olvidan las firmas para que el siguiente aviso exija
45
+ * tres repeticiones nuevas: si no, cada llamada posterior volveria a
46
+ * preguntar y el remedio seria peor que el bucle.
47
+ */
48
+ olvidar(): void;
49
+ /** Se llama al empezar cada turno: el usuario ha dicho algo nuevo. */
50
+ reiniciar(): void;
51
+ }
52
+ /**
53
+ * Texto que se le devuelve al modelo cuando el usuario corta el bucle. Decirle
54
+ * "cancelado" a secas le deja sin saber que hacer distinto; esto le nombra el
55
+ * problema y le da salidas concretas.
56
+ */
57
+ export declare function mensajeDeBucle(aviso: AvisoDeBucle, indicacion?: string): string;
Binary file
@@ -9,3 +9,16 @@ export declare function parseFileMentions(userInput: string, cwd?: string): {
9
9
  attachedFiles: MentionedFile[];
10
10
  };
11
11
  export declare function buildPromptWithMentions(userInput: string, attachedFiles: MentionedFile[]): string;
12
+ /**
13
+ * Archivos que el usuario esta nombrando SIN escribir la @.
14
+ *
15
+ * La gente no escribe "@src/agent/loop.ts": escribe "el bucle de loop.ts" o
16
+ * "arregla el fileTracker". Antes eso no lo veia nadie, y el agente empezaba
17
+ * cada peticion buscando a ciegas un archivo cuyo nombre el usuario acababa de
18
+ * decir.
19
+ *
20
+ * A diferencia de la mencion con @, aqui NO se adjunta el contenido: se dan las
21
+ * rutas y ya. Pegar tres archivos enteros por si acaso cuesta mas contexto que
22
+ * la busqueda que ahorra, y el agente sabe leer.
23
+ */
24
+ export declare function notaDeMencionesImplicitas(userInput: string, cwd?: string, yaAdjuntos?: string[]): string;
@@ -1,6 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import chalk from "chalk";
4
+ import { extraerMenciones, listarArchivosCacheado, indiceDeDefiniciones } from "./repoMap.js";
4
5
  export function parseFileMentions(userInput, cwd = process.cwd()) {
5
6
  const mentionRegex = /@([a-zA-Z0-9_\-\.\/\\]+)/g;
6
7
  const attachedFiles = [];
@@ -41,3 +42,51 @@ export function buildPromptWithMentions(userInput, attachedFiles) {
41
42
  .join("\n");
42
43
  return `${userInput}\n${fileBlocks}`;
43
44
  }
45
+ /** Archivos que quedan fuera de la nota por no aportar nada al modelo. */
46
+ const MAX_IMPLICITAS = 8;
47
+ /**
48
+ * Archivos que el usuario esta nombrando SIN escribir la @.
49
+ *
50
+ * La gente no escribe "@src/agent/loop.ts": escribe "el bucle de loop.ts" o
51
+ * "arregla el fileTracker". Antes eso no lo veia nadie, y el agente empezaba
52
+ * cada peticion buscando a ciegas un archivo cuyo nombre el usuario acababa de
53
+ * decir.
54
+ *
55
+ * A diferencia de la mencion con @, aqui NO se adjunta el contenido: se dan las
56
+ * rutas y ya. Pegar tres archivos enteros por si acaso cuesta mas contexto que
57
+ * la busqueda que ahorra, y el agente sabe leer.
58
+ */
59
+ export function notaDeMencionesImplicitas(userInput, cwd = process.cwd(), yaAdjuntos = []) {
60
+ let candidatos;
61
+ try {
62
+ candidatos = listarArchivosCacheado(cwd);
63
+ }
64
+ catch {
65
+ return "";
66
+ }
67
+ if (candidatos.length === 0)
68
+ return "";
69
+ const { archivos, identificadores } = extraerMenciones(userInput, candidatos);
70
+ // Nombrar un simbolo tambien cuenta. Es como habla la gente: "arregla
71
+ // calcularImpuesto", no "arregla src/facturacion.ts". Un nombre definido en
72
+ // mas de tres sitios no senala nada, asi que no se ofrece.
73
+ try {
74
+ const indice = indiceDeDefiniciones(cwd);
75
+ for (const ident of identificadores) {
76
+ if (ident.length < 4)
77
+ continue;
78
+ const definidores = indice.get(ident);
79
+ if (definidores && definidores.length <= 3) {
80
+ for (const a of definidores)
81
+ archivos.add(a);
82
+ }
83
+ }
84
+ }
85
+ catch { }
86
+ const adjuntos = new Set(yaAdjuntos.map((a) => a.replace(/\\/g, "/")));
87
+ const rutas = [...archivos].filter((a) => !adjuntos.has(a.replace(/\\/g, "/"))).slice(0, MAX_IMPLICITAS);
88
+ if (rutas.length === 0)
89
+ return "";
90
+ return (`\n\n[Archivos del proyecto que parece que estas nombrando: ${rutas.join(", ")}. ` +
91
+ `Son rutas, no contenido: leelas con view_file si te hacen falta.]`);
92
+ }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Mapa del repositorio: que hay en el proyecto y que importa de ello.
3
+ *
4
+ * Hasta ahora el agente empezaba cada sesion a ciegas. Sabia el tipo de
5
+ * proyecto y la rama de git (context.ts), y nada mas: para enterarse de que
6
+ * existe una funcion tenia que buscarla, y para buscarla tenia que sospechar
7
+ * que existe. El resultado son turnos enteros gastados en grep_search y
8
+ * list_dir antes de tocar una linea.
9
+ *
10
+ * Esto es la version sin tree-sitter del repo map de Aider. Se pierde
11
+ * precision en la extraccion de simbolos —donde ellos parsean, aqui hay
12
+ * expresiones regulares por lenguaje— pero las tres piezas que hacen que el
13
+ * mapa sirva de algo se conservan enteras:
14
+ *
15
+ * 1. **Un grafo, no una lista.** Los archivos se puntuan por quien los usa,
16
+ * con PageRank. Un fichero de utilidades que importan veinte modulos sale
17
+ * antes que uno enorme que no usa nadie.
18
+ * 2. **El rango del archivo se reparte entre sus simbolos.** Lo que se ensena
19
+ * no son ficheros, son definiciones, ordenadas por el "voto" que les mandan
20
+ * quienes las llaman.
21
+ * 3. **Presupuesto de tokens con biseccion.** El mapa se corta al numero de
22
+ * simbolos que quepa en el presupuesto, no a un numero fijo de lineas.
23
+ *
24
+ * Y lo que sesga todo: lo que el usuario acaba de escribir (ver
25
+ * extraerMenciones).
26
+ */
27
+ export interface Simbolo {
28
+ archivo: string;
29
+ linea: number;
30
+ nombre: string;
31
+ clase: "def" | "ref";
32
+ }
33
+ /**
34
+ * Patrones de definicion por lenguaje.
35
+ *
36
+ * Se prefiere perder alguna definicion a inventarsela: un simbolo fantasma en
37
+ * el mapa manda al agente a buscar algo que no existe, que es peor que no
38
+ * mencionarlo.
39
+ */
40
+ declare const DEFINICIONES: Record<string, RegExp[]>;
41
+ export declare function lenguajeDe(ruta: string): keyof typeof DEFINICIONES | null;
42
+ /**
43
+ * Definiciones y referencias de un archivo.
44
+ *
45
+ * Las referencias son "todo lo que parezca un identificador" menos las
46
+ * reservadas. Es tosco, pero es exactamente lo que hace Aider cuando la
47
+ * gramatica de un lenguaje no le da referencias: lo que importa aqui no es
48
+ * clasificar bien cada token, es saber quien nombra a quien.
49
+ */
50
+ export interface SimbolosDeArchivo {
51
+ definiciones: Simbolo[];
52
+ /**
53
+ * Cuantas veces se nombra cada identificador. El numero importa: el peso de
54
+ * la arista lleva una raiz cuadrada encima justo para que un identificador
55
+ * citado doscientas veces pese mas que uno citado dos, pero no cien veces
56
+ * mas. Contando solo "aparece o no aparece" esa senal se pierde entera.
57
+ */
58
+ referencias: Map<string, number>;
59
+ }
60
+ export declare function extraerSimbolos(ruta: string, contenido: string): SimbolosDeArchivo;
61
+ /**
62
+ * Un archivo de pruebas es parte del repositorio, pero no es por donde se
63
+ * empieza a entender un proyecto: nombra a todo el mundo (por eso puntua alto
64
+ * en el grafo) y no lo llama nadie. Se deja en el mapa, pero al final.
65
+ */
66
+ export declare function esArchivoDePruebas(ruta: string): boolean;
67
+ export interface Menciones {
68
+ archivos: Set<string>;
69
+ identificadores: Set<string>;
70
+ }
71
+ /**
72
+ * Que archivos e identificadores esta nombrando el usuario.
73
+ *
74
+ * Las tres reglas son de Aider y las tres importan:
75
+ * - la ruta completa cuenta siempre, normalizando "\" a "/" (en Windows es la
76
+ * diferencia entre funcionar y no funcionar);
77
+ * - el nombre suelto ("loop.ts") solo cuenta si lleva un separador o un punto
78
+ * y si es UNICO en el proyecto, para no confundir "run" o "make";
79
+ * - un identificador de 5 letras o mas que coincide con el nombre de un
80
+ * archivo lo trae al mapa: escribir "arregla el fileTracker" deberia sacar
81
+ * src/agent/fileTracker.ts sin que nadie escriba la ruta.
82
+ */
83
+ export declare function extraerMenciones(texto: string, archivos: string[]): Menciones;
84
+ /**
85
+ * PageRank por iteracion de potencia. No hace falta una libreria de grafos:
86
+ * son veinte lineas y evita una dependencia nativa mas.
87
+ */
88
+ export declare function pageRank(nodos: string[], aristas: Map<string, {
89
+ destino: string;
90
+ peso: number;
91
+ }[]>, personalizacion: Map<string, number>, amortiguacion?: number, vueltas?: number): Map<string, number>;
92
+ export interface OpcionesMapa {
93
+ cwd: string;
94
+ /** Texto del usuario, para sesgar el ranking hacia lo que acaba de pedir. */
95
+ peticion?: string;
96
+ /** Archivos ya "abiertos" (leidos o editados) en la sesion. */
97
+ abiertos?: string[];
98
+ /** Tokens que puede ocupar el mapa. */
99
+ presupuesto?: number;
100
+ maxArchivos?: number;
101
+ }
102
+ export declare function listarArchivosCacheado(cwd: string, maxArchivos?: number): string[];
103
+ export declare function indiceDeDefiniciones(cwd: string): Map<string, string[]>;
104
+ export declare function listarArchivos(cwd: string, maxArchivos?: number): string[];
105
+ /**
106
+ * Construye el mapa. Devuelve el texto listo para inyectar, o "" si no hay
107
+ * nada que ensenar (proyecto sin codigo reconocible, o presupuesto cero).
108
+ */
109
+ export declare function construirMapa(opciones: OpcionesMapa): string;
110
+ /**
111
+ * El bloque tal y como se le entrega al modelo.
112
+ *
113
+ * El encabezado no es decorativo: sin el, el modelo trata el mapa como codigo
114
+ * que acaba de leer y se pone a editar simbolos que solo ha visto de nombre.
115
+ */
116
+ export declare function bloqueDeMapa(mapa: string): string;
117
+ export {};