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
package/README.md ADDED
@@ -0,0 +1,186 @@
1
+ # 🦊 Chocolatito Code (v1.0.0)
2
+
3
+ > **Agente Autónomo de Programación para la Terminal**, desarrollado por **Chocolatito** con la arquitectura del **Motor Espectro**.
4
+
5
+ ---
6
+
7
+ ## ⚡ Niveles de Potencia y Esfuerzo (/effort)
8
+
9
+ Chocolatito Code te permite regular dinámicamente la profundidad y potencia del motor según la complejidad de la tarea:
10
+
11
+ | Nivel | Nombre | Nivel de Esfuerzo | Uso Recomendado |
12
+ | :--- | :--- | :---: | :--- |
13
+ | Nivel | Modelo real | Uso recomendado |
14
+ | :--- | :--- | :--- |
15
+ | **`1.0`** Ágil | `deepseek-v4-flash` | Tareas cotidianas, funciones y scripts directos. |
16
+ | **`1.5`** Avanzado | `deepseek-v4-flash` | Refactorizaciones, con más margen creativo. |
17
+ | **`2.0`** Razonamiento Pro | `deepseek-v4-pro` | Bugs difíciles, algoritmos y arquitectura. |
18
+ | **`2.5`** MAX | `deepseek-v4-pro` | Proyectos completos y exploración amplia. |
19
+
20
+ Ventana de contexto: **1.000.000 de tokens** en los cuatro niveles.
21
+
22
+ Para cambiar de nivel dentro de la sesión, escribe:
23
+ ```bash
24
+ /effort 2.0
25
+ ```
26
+
27
+ ---
28
+
29
+ ## 🛠️ Herramientas Nativas Autónomas
30
+
31
+ - 👁️ `view_file`: Lectura precisa con numeración de líneas.
32
+ - ✏️ `edit_file`: Modificación de código con diffs visuales tipo Git (verde/rojo).
33
+ - 📄 `write_file`: Creación y sobreescritura de archivos y directorios.
34
+ - 💻 `run_command`: Ejecución de comandos en PowerShell/Bash con captura de logs.
35
+ - 📂 `list_dir`: Exploración de proyectos respetando `.gitignore`.
36
+ - 🔍 `grep_search`: Búsqueda instantánea de texto y regex.
37
+ - 🌐 `chrome`: Controla **tu** Chrome desde dentro, con tus sesiones iniciadas y en segundo
38
+ plano real (requiere la extensión: ver `extension/README.md`).
39
+ - 🖥️ `computer_use`: Aplicaciones de escritorio por árbol de accesibilidad, sin adivinar píxeles.
40
+ - 🧭 `browser`: Navegador propio por CDP, para webs públicas y `localhost`.
41
+
42
+ Las lecturas independientes lanzadas en el mismo turno se ejecutan **en paralelo**.
43
+
44
+ ## 🔌 MCP (Model Context Protocol)
45
+
46
+ Conecta cualquier servidor MCP y sus herramientas quedan disponibles para el agente.
47
+ Configuración compatible con Claude Code en `.mcp.json` (ver `.mcp.json.ejemplo`):
48
+
49
+ ```json
50
+ { "mcpServers": { "github": {
51
+ "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"],
52
+ "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" } } } }
53
+ ```
54
+
55
+ Las herramientas aparecen como `mcp__<servidor>__<herramienta>`. Usa `/mcp` para ver el estado.
56
+
57
+ ## 🪝 Hooks
58
+
59
+ Reglas propias que el agente no puede saltarse, en `.chocolatito/settings.json`:
60
+
61
+ ```json
62
+ { "hooks": { "PreToolUse": [ { "matcher": "run_command",
63
+ "hooks": [{ "type": "command", "command": "node .chocolatito/hooks/guardia.mjs" }] } ] } }
64
+ ```
65
+
66
+ El hook recibe el evento por stdin como JSON y puede **denegar**, **pedir confirmación** o
67
+ **reescribir los argumentos** antes de que la herramienta se ejecute. Salir con código 2
68
+ bloquea directamente.
69
+
70
+
71
+ ## 🔐 Permisos
72
+
73
+ Una sola regla: **mirar es gratis, actuar se pregunta.**
74
+
75
+ | Acción | Se pregunta |
76
+ | :--- | :--- |
77
+ | `ui_snapshot`, `list_windows`, `snapshot`, `screenshot`, `get_text`, `tabs` | No. Es el paso previo obligatorio de todo. |
78
+ | Clic, escritura, navegación o JavaScript sobre tu ordenador o tu Chrome | **Siempre**, también en `acceptEdits`. |
79
+ | `run_command`, escritura y borrado de archivos | Sí, salvo patrón autorizado. |
80
+
81
+ ### Cambiar de modo con `shift+tab`
82
+
83
+ Funciona **en cualquier momento**: en el prompt, a mitad de una generación y dentro del
84
+ propio diálogo de permiso (ahí además aprueba la acción pendiente).
85
+
86
+ ```
87
+ normal → acepta ediciones → automático → normal
88
+ ```
89
+
90
+ - **normal** — pregunta antes de cada acción con consecuencias.
91
+ - **acepta ediciones** — escribe archivos sin preguntar; sigue preguntando por comandos y
92
+ por el control del ordenador.
93
+ - **automático** — no pregunta nada.
94
+
95
+ El **modo plan** se activa aparte, con `/plan`, para no dejarlo a un golpe de tecla. Es
96
+ solo lectura de verdad: ni comandos, ni clics, ni escrituras.
97
+
98
+ `--yes` aprueba todo sin preguntar: es para CI, no para el día a día.
99
+
100
+ ## ⌨️ Escribir mientras trabaja
101
+
102
+ No hace falta esperar a que termine. Lo que escribas durante una generación aparece bajo
103
+ el spinner y, al pulsar Enter, queda en cola: el agente acaba su turno y lo toma como
104
+ siguiente orden, sin que tengas que volver a teclearlo.
105
+
106
+ `Esc` pausa el turno en curso. `Ctrl+C` una vez interrumpe; dos veces cierra la sesión.
107
+
108
+
109
+ ---
110
+
111
+ ## 🔑 Licencia
112
+
113
+ Al abrirlo por primera vez pide la clave que recibiste por correo al comprar:
114
+
115
+ ```
116
+ 🔑 ACTIVACIÓN — CHOCOLATITO CODE
117
+ Licencia ❯ 38b1460a-5104-4067-a91d-77b872934d51
118
+ ✔ Licencia activada para tu@correo.com
119
+ ```
120
+
121
+ Se guarda en `~/.chocolatitorc` y no vuelve a pedirla. Una clave sirve para **3 equipos**.
122
+
123
+ ```bash
124
+ /licencia # ver la licencia activa y en qué equipo estás
125
+ /licencia liberar # soltar este equipo para usar la clave en otro
126
+ ```
127
+
128
+ Si cambias de ordenador o formateas, libera el equipo antes. Si ya no puedes,
129
+ escribe al soporte y se libera desde el panel.
130
+
131
+ Se comprueba una vez al día. Si algún día no hay conexión, **sigues trabajando**:
132
+ hay 7 días de margen antes de pedirte que te conectes.
133
+
134
+ ---
135
+
136
+ ## 📦 Instalación
137
+
138
+ ```bash
139
+ npm install -g chocolatito-code
140
+ chocolatito --version
141
+ ```
142
+
143
+ Requiere **Node.js 20 o superior**. La primera vez pide la API key y la guarda en
144
+ `~/.chocolatitorc`; también se puede pasar por `CHOCOLATITO_API_KEY` o por un `.env` del
145
+ proyecto.
146
+
147
+ Para desarrollar sobre el propio proyecto:
148
+
149
+ ```bash
150
+ npm install && npm run build && npm link
151
+ ```
152
+
153
+ ---
154
+
155
+ ## 🚀 Uso Rápido
156
+
157
+ ```bash
158
+ # Iniciar sesión interactiva
159
+ chocolatito
160
+
161
+ # O ejecutar una orden directa
162
+ chocolatito "crea una API REST con Node.js y Express"
163
+
164
+ # Modo no interactivo: aprueba las acciones sin preguntar
165
+ chocolatito --yes "ejecuta los tests y arregla lo que falle"
166
+
167
+ # Ayuda y versión, sin gastar tokens
168
+ chocolatito --help
169
+ chocolatito --version
170
+ ```
171
+
172
+ ## 🧪 Pruebas
173
+
174
+ ```bash
175
+ npm run build && npm test
176
+ ```
177
+
178
+ ## 📚 Documentación
179
+
180
+ - `MEJORAS.md` — auditoría del núcleo y de permisos: qué estaba roto, qué se arregló y cómo se comprobó.
181
+ - `COMPUTER-USE.md` — diseño del control de ordenador y navegador.
182
+ - `extension/README.md` — instalación de la extensión de Chrome.
183
+
184
+ ---
185
+
186
+ Desarrollado con pasión por **Chocolatito**. 🦊⚡
@@ -0,0 +1,9 @@
1
+ export interface ProjectContext {
2
+ cwd: string;
3
+ os: string;
4
+ rulesContent: string | null;
5
+ gitBranch: string | null;
6
+ projectType: string;
7
+ availableScripts: string[];
8
+ }
9
+ export declare function getProjectContext(cwd?: string): Promise<ProjectContext>;
@@ -0,0 +1,123 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { execa } from "execa";
4
+ import { RULES_FILE_NAME } from "../config/constants.js";
5
+ export async function getProjectContext(cwd = process.cwd()) {
6
+ let rulesContent = null;
7
+ // 1. Look for CHOCOLATITO.md or CLAUDE.md
8
+ const rulesPath = path.join(cwd, RULES_FILE_NAME);
9
+ const fallbackClaudePath = path.join(cwd, "CLAUDE.md");
10
+ if (fs.existsSync(rulesPath)) {
11
+ try {
12
+ rulesContent = fs.readFileSync(rulesPath, "utf-8");
13
+ }
14
+ catch { }
15
+ }
16
+ else if (fs.existsSync(fallbackClaudePath)) {
17
+ try {
18
+ rulesContent = fs.readFileSync(fallbackClaudePath, "utf-8");
19
+ }
20
+ catch { }
21
+ }
22
+ // 2. Git branch & status detection
23
+ let gitBranch = null;
24
+ try {
25
+ const { stdout: branchOut } = await execa("git", ["branch", "--show-current"], { cwd });
26
+ if (branchOut && branchOut.trim()) {
27
+ const branchName = branchOut.trim();
28
+ const { stdout: statusOut } = await execa("git", ["status", "--porcelain"], { cwd });
29
+ const changedFiles = statusOut ? statusOut.trim().split("\n").filter(Boolean).length : 0;
30
+ gitBranch = changedFiles > 0 ? `${branchName} (${changedFiles} archivos modificados)` : `${branchName} (limpio)`;
31
+ }
32
+ }
33
+ catch { }
34
+ // 3. Comprehensive project type & available scripts detection
35
+ let projectType = "Desconocido / Genérico";
36
+ const availableScripts = [];
37
+ const pkgJsonPath = path.join(cwd, "package.json");
38
+ const pyProjectPath = path.join(cwd, "pyproject.toml");
39
+ const reqTxtPath = path.join(cwd, "requirements.txt");
40
+ const cargoPath = path.join(cwd, "Cargo.toml");
41
+ const goModPath = path.join(cwd, "go.mod");
42
+ const pubspecPath = path.join(cwd, "pubspec.yaml");
43
+ const gradlePath = path.join(cwd, "build.gradle");
44
+ const pomPath = path.join(cwd, "pom.xml");
45
+ const cmakePath = path.join(cwd, "CMakeLists.txt");
46
+ if (fs.existsSync(pkgJsonPath)) {
47
+ try {
48
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
49
+ const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
50
+ const tech = [];
51
+ if (deps.react)
52
+ tech.push("React");
53
+ if (deps.next)
54
+ tech.push("Next.js");
55
+ if (deps.remotion)
56
+ tech.push("Remotion");
57
+ if (deps.vue)
58
+ tech.push("Vue");
59
+ if (deps.svelte)
60
+ tech.push("Svelte");
61
+ if (deps.express)
62
+ tech.push("Express");
63
+ if (deps.fastify)
64
+ tech.push("Fastify");
65
+ if (deps.nest || deps["@nestjs/core"])
66
+ tech.push("NestJS");
67
+ if (deps.typescript)
68
+ tech.push("TypeScript");
69
+ if (deps.tailwindcss)
70
+ tech.push("Tailwind CSS");
71
+ projectType = `Node.js / JavaScript${tech.length > 0 ? ` (${tech.join(", ")})` : ""}`;
72
+ if (pkg.scripts) {
73
+ Object.keys(pkg.scripts).forEach((k) => availableScripts.push(`npm run ${k}`));
74
+ }
75
+ }
76
+ catch { }
77
+ }
78
+ else if (fs.existsSync(pyProjectPath) || fs.existsSync(reqTxtPath)) {
79
+ let framework = "";
80
+ try {
81
+ const content = (fs.existsSync(reqTxtPath) ? fs.readFileSync(reqTxtPath, "utf-8") : "") +
82
+ (fs.existsSync(pyProjectPath) ? fs.readFileSync(pyProjectPath, "utf-8") : "");
83
+ if (content.includes("fastapi"))
84
+ framework = " (FastAPI)";
85
+ else if (content.includes("django"))
86
+ framework = " (Django)";
87
+ else if (content.includes("flask"))
88
+ framework = " (Flask)";
89
+ else if (content.includes("torch"))
90
+ framework = " (PyTorch)";
91
+ }
92
+ catch { }
93
+ projectType = `Python${framework}`;
94
+ availableScripts.push("python main.py", "pytest");
95
+ }
96
+ else if (fs.existsSync(cargoPath)) {
97
+ projectType = "Rust (Cargo)";
98
+ availableScripts.push("cargo build", "cargo test", "cargo run");
99
+ }
100
+ else if (fs.existsSync(goModPath)) {
101
+ projectType = "Go (Golang)";
102
+ availableScripts.push("go build", "go test", "go run .");
103
+ }
104
+ else if (fs.existsSync(pubspecPath)) {
105
+ projectType = "Flutter / Dart";
106
+ availableScripts.push("flutter run", "flutter test");
107
+ }
108
+ else if (fs.existsSync(gradlePath) || fs.existsSync(pomPath)) {
109
+ projectType = "Java / Kotlin (JVM)";
110
+ }
111
+ else if (fs.existsSync(cmakePath)) {
112
+ projectType = "C / C++ (CMake)";
113
+ }
114
+ const osName = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
115
+ return {
116
+ cwd,
117
+ os: osName,
118
+ rulesContent,
119
+ gitBranch,
120
+ projectType,
121
+ availableScripts,
122
+ };
123
+ }
@@ -0,0 +1,16 @@
1
+ declare class FileTracker {
2
+ private seen;
3
+ private key;
4
+ /** Se llama tras leer un archivo con exito. */
5
+ markRead(filePath: string, cwd: string): void;
6
+ /** Se llama tras escribir, para que la siguiente edicion no se queje. */
7
+ markWritten(filePath: string, cwd: string): void;
8
+ forget(filePath: string, cwd: string): void;
9
+ /**
10
+ * Devuelve un aviso si editar este archivo ahora seria arriesgado, o null si
11
+ * todo esta en orden.
12
+ */
13
+ checkBeforeEdit(filePath: string, cwd: string): string | null;
14
+ }
15
+ export declare const fileTracker: FileTracker;
16
+ export {};
@@ -0,0 +1,53 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ class FileTracker {
4
+ seen = new Map();
5
+ key(filePath, cwd) {
6
+ const abs = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
7
+ return path.normalize(abs).toLowerCase();
8
+ }
9
+ /** Se llama tras leer un archivo con exito. */
10
+ markRead(filePath, cwd) {
11
+ try {
12
+ const abs = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
13
+ const st = fs.statSync(abs);
14
+ this.seen.set(this.key(filePath, cwd), { mtimeMs: st.mtimeMs, size: st.size });
15
+ }
16
+ catch {
17
+ // Si no se puede medir, no se registra: mejor pedir lectura de nuevo.
18
+ }
19
+ }
20
+ /** Se llama tras escribir, para que la siguiente edicion no se queje. */
21
+ markWritten(filePath, cwd) {
22
+ this.markRead(filePath, cwd);
23
+ }
24
+ forget(filePath, cwd) {
25
+ this.seen.delete(this.key(filePath, cwd));
26
+ }
27
+ /**
28
+ * Devuelve un aviso si editar este archivo ahora seria arriesgado, o null si
29
+ * todo esta en orden.
30
+ */
31
+ checkBeforeEdit(filePath, cwd) {
32
+ const abs = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
33
+ if (!fs.existsSync(abs))
34
+ return null;
35
+ const record = this.seen.get(this.key(filePath, cwd));
36
+ if (!record) {
37
+ return (`No has leido "${filePath}" en esta sesion. Usa view_file antes de editarlo: ` +
38
+ `editar un contenido que no has visto es como se sobrescribe la parte equivocada.`);
39
+ }
40
+ try {
41
+ const st = fs.statSync(abs);
42
+ if (st.mtimeMs > record.mtimeMs + 1 || st.size !== record.size) {
43
+ return (`"${filePath}" cambio despues de que lo leyeras (otro proceso, el usuario o un formateador). ` +
44
+ `Vuelve a leerlo con view_file antes de editar, o perderas esos cambios.`);
45
+ }
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ return null;
51
+ }
52
+ }
53
+ export const fileTracker = new FileTracker();
@@ -0,0 +1,25 @@
1
+ import OpenAI from "openai";
2
+ import { TokenTracker } from "./tracker.js";
3
+ import { EspectroModel } from "../config/constants.js";
4
+ import { PermissionManager } from "../config/permissions.js";
5
+ import { HookManager } from "../hooks/manager.js";
6
+ export declare class AgentLoop {
7
+ private client;
8
+ private currentEspectro;
9
+ messages: OpenAI.Chat.ChatCompletionMessageParam[];
10
+ tracker: TokenTracker;
11
+ currentCwd: string;
12
+ permissions: PermissionManager;
13
+ hooks: HookManager;
14
+ private apiKey;
15
+ private baseURL;
16
+ private maxIterations;
17
+ constructor(apiKey: string, baseURL: string, initialModel: EspectroModel, systemPrompt: string);
18
+ setEspectroModel(model: EspectroModel, updatedSystemPrompt?: string): void;
19
+ getEspectroModel(): EspectroModel;
20
+ clearHistory(systemPrompt: string): void;
21
+ compactHistory(systemPrompt: string): Promise<string>;
22
+ lastTurnTokens: number;
23
+ autoCompactIfNeeded(): Promise<boolean>;
24
+ runTask(userPrompt: string): Promise<void>;
25
+ }