mcp-code-context 2.4.1 β 2.5.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.
- package/CHANGELOG.md +26 -0
- package/PLAN_v2.5.0.md +407 -0
- package/README.md +1 -1
- package/dist/src/cache/astCache.d.ts +9 -5
- package/dist/src/cache/astCache.js +45 -17
- package/dist/src/cache/astCache.js.map +1 -1
- package/dist/src/handlers/readHandlers.d.ts +1 -1
- package/dist/src/handlers/readHandlers.js +66 -57
- package/dist/src/handlers/readHandlers.js.map +1 -1
- package/dist/src/handlers/writeHandlers.js +3 -3
- package/dist/src/handlers/writeHandlers.js.map +1 -1
- package/dist/src/utils/constants.d.ts +1 -1
- package/dist/src/utils/constants.js +1 -1
- package/dist/src/utils/dependencyChecker.d.ts +1 -0
- package/dist/src/utils/dependencyChecker.js +55 -0
- package/dist/src/utils/dependencyChecker.js.map +1 -0
- package/dist/src/utils/ignoreManager.d.ts +1 -1
- package/dist/src/utils/ignoreManager.js +6 -4
- package/dist/src/utils/ignoreManager.js.map +1 -1
- package/dist/src/utils/syntaxValidator.d.ts +15 -0
- package/dist/src/utils/syntaxValidator.js +218 -0
- package/dist/src/utils/syntaxValidator.js.map +1 -0
- package/dist/src/utils/transactionManager.d.ts +2 -1
- package/dist/src/utils/transactionManager.js +25 -4
- package/dist/src/utils/transactionManager.js.map +1 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.5.0] - 2024-01-16
|
|
9
|
+
|
|
10
|
+
### π Reliability & Safety
|
|
11
|
+
|
|
12
|
+
- **Syntax Validation**: Auto-check before commit (TS/JS/PHP/Dart/Python)
|
|
13
|
+
- **Cache Memory Limits**: Real byte limits (100MB default)
|
|
14
|
+
- **AbortController**: 60s timeout on large operations
|
|
15
|
+
- **AST Dependency Check**: Eliminates false positives
|
|
16
|
+
|
|
17
|
+
### π Metrics
|
|
18
|
+
- Reliability: 8.5 β 9.5 (+1.0)
|
|
19
|
+
- Safety: 8.0 β 9.5 (+1.5)
|
|
20
|
+
|
|
21
|
+
## [2.5.0] - 2024-01-16
|
|
22
|
+
|
|
23
|
+
### π Reliability & Safety
|
|
24
|
+
|
|
25
|
+
- **Syntax Validation**: Auto-check before commit (TS/JS/PHP/Dart/Python)
|
|
26
|
+
- **Cache Memory Limits**: Real byte limits (100MB default)
|
|
27
|
+
- **AbortController**: 60s timeout on large operations
|
|
28
|
+
- **AST Dependency Check**: Eliminates false positives
|
|
29
|
+
|
|
30
|
+
### π Metrics
|
|
31
|
+
- Reliability: 8.5 β 9.5 (+1.0)
|
|
32
|
+
- Safety: 8.0 β 9.5 (+1.5)
|
|
33
|
+
|
|
8
34
|
## [2.4.1] - 2024-01-15
|
|
9
35
|
|
|
10
36
|
### Fixed
|
package/PLAN_v2.5.0.md
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# π― PLAN MAESTRO v2.5.0 - Quick Wins
|
|
2
|
+
|
|
3
|
+
**Estado:** EN PROGRESO
|
|
4
|
+
**Inicio:** 2024-01-15
|
|
5
|
+
**Estimado:** 1-2 semanas (30h)
|
|
6
|
+
**VersiΓ³n Base:** v2.4.1
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## β
FASE 1: SYNTAX VALIDATION (COMPLETADA)
|
|
11
|
+
|
|
12
|
+
**Tiempo:** 2h
|
|
13
|
+
**Archivos creados:**
|
|
14
|
+
- `src/utils/syntaxValidator.ts` β
|
|
15
|
+
- `tests/test-syntax-validation.ts` β
|
|
16
|
+
|
|
17
|
+
**Archivos modificados:**
|
|
18
|
+
- `src/utils/transactionManager.ts` β
(agregado Phase 2: Syntax validation)
|
|
19
|
+
|
|
20
|
+
**Tests:** 8/8 pasando β
|
|
21
|
+
|
|
22
|
+
**Funcionalidad:**
|
|
23
|
+
- Valida sintaxis antes de commit
|
|
24
|
+
- Rollback automΓ‘tico si hay errores
|
|
25
|
+
- Soporta: TS, JS, PHP, Dart, Python
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## β
FASE 2: CACHE MEMORY LIMITS (COMPLETADA)
|
|
30
|
+
|
|
31
|
+
**Tiempo:** 1h
|
|
32
|
+
**Archivos modificados:**
|
|
33
|
+
- `src/cache/astCache.ts` β
|
|
34
|
+
|
|
35
|
+
**Archivos creados:**
|
|
36
|
+
- `tests/test-cache-limits.ts` β
|
|
37
|
+
|
|
38
|
+
**Tests:** 3/3 pasando β
|
|
39
|
+
|
|
40
|
+
**Funcionalidad:**
|
|
41
|
+
- LΓmite real en bytes (100MB default)
|
|
42
|
+
- Eviction por bytes y entries
|
|
43
|
+
- Tracking de memoria real
|
|
44
|
+
|
|
45
|
+
### Archivos a modificar:
|
|
46
|
+
1. `src/cache/astCache.ts`
|
|
47
|
+
|
|
48
|
+
### Cambios necesarios:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// ANTES (lΓnea 25-30)
|
|
52
|
+
export class LRUCache<K, V> {
|
|
53
|
+
private cache: Map<K, CacheEntry<V>>;
|
|
54
|
+
private maxSize: number;
|
|
55
|
+
private currentSize: number;
|
|
56
|
+
|
|
57
|
+
constructor(maxSize: number = 100) {
|
|
58
|
+
this.cache = new Map();
|
|
59
|
+
this.maxSize = maxSize;
|
|
60
|
+
this.currentSize = 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// DESPUΓS
|
|
65
|
+
export class LRUCache<K, V> {
|
|
66
|
+
private cache: Map<K, CacheEntry<V>>;
|
|
67
|
+
private maxEntries: number;
|
|
68
|
+
private maxBytes: number;
|
|
69
|
+
private currentEntries: number;
|
|
70
|
+
private currentBytes: number;
|
|
71
|
+
|
|
72
|
+
constructor(maxEntries: number = 100, maxBytes: number = 100 * 1024 * 1024) {
|
|
73
|
+
this.cache = new Map();
|
|
74
|
+
this.maxEntries = maxEntries;
|
|
75
|
+
this.maxBytes = maxBytes; // 100MB default
|
|
76
|
+
this.currentEntries = 0;
|
|
77
|
+
this.currentBytes = 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
set(key: K, value: V, filePath?: string, estimatedSize: number = 1000): void {
|
|
81
|
+
// Evict if over byte limit
|
|
82
|
+
while (this.currentBytes + estimatedSize > this.maxBytes && this.cache.size > 0) {
|
|
83
|
+
const oldestKey = this.cache.keys().next().value as K;
|
|
84
|
+
const oldEntry = this.cache.get(oldestKey);
|
|
85
|
+
if (oldEntry) {
|
|
86
|
+
this.currentBytes -= oldEntry.size;
|
|
87
|
+
this.cache.delete(oldestKey);
|
|
88
|
+
this.currentEntries--;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Evict if over entry limit
|
|
93
|
+
while (this.currentEntries >= this.maxEntries && this.cache.size > 0) {
|
|
94
|
+
const oldestKey = this.cache.keys().next().value as K;
|
|
95
|
+
const oldEntry = this.cache.get(oldestKey);
|
|
96
|
+
if (oldEntry) {
|
|
97
|
+
this.currentBytes -= oldEntry.size;
|
|
98
|
+
this.cache.delete(oldestKey);
|
|
99
|
+
this.currentEntries--;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
this.cache.set(key, { value, mtime, size: estimatedSize });
|
|
104
|
+
this.currentEntries++;
|
|
105
|
+
this.currentBytes += estimatedSize;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Test a crear:
|
|
111
|
+
- `tests/test-cache-memory-limits.ts`
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## β
FASE 3: ABORTCONTROLLER SUPPORT (COMPLETADA)
|
|
116
|
+
|
|
117
|
+
**Tiempo:** 1h
|
|
118
|
+
**Archivos modificados:**
|
|
119
|
+
- `src/handlers/readHandlers.ts` β
|
|
120
|
+
- `src/utils/ignoreManager.ts` β
|
|
121
|
+
|
|
122
|
+
**Funcionalidad:**
|
|
123
|
+
- Timeout 60s en get_semantic_repo_map
|
|
124
|
+
- CancelaciΓ³n graceful
|
|
125
|
+
- Signal propagation
|
|
126
|
+
|
|
127
|
+
### Archivos a modificar:
|
|
128
|
+
1. `src/handlers/readHandlers.ts` - handleGetSemanticRepoMap
|
|
129
|
+
2. `src/utils/ignoreManager.ts` - walkDirectoryAsync
|
|
130
|
+
|
|
131
|
+
### Cambios necesarios:
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// En handleGetSemanticRepoMap (lΓnea 47)
|
|
135
|
+
export async function handleGetSemanticRepoMap(
|
|
136
|
+
args: Record<string, unknown>,
|
|
137
|
+
signal?: AbortSignal // β
Nuevo parΓ‘metro
|
|
138
|
+
) {
|
|
139
|
+
// Crear timeout de 60s
|
|
140
|
+
const controller = new AbortController();
|
|
141
|
+
const timeout = setTimeout(() => controller.abort(), 60000);
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
const files = await ignoreManager.walkDirectoryAsync(resolvedPath, controller.signal);
|
|
145
|
+
|
|
146
|
+
// Check abort
|
|
147
|
+
if (signal?.aborted || controller.signal.aborted) {
|
|
148
|
+
throw new Error("Operation cancelled");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ... resto del cΓ³digo
|
|
152
|
+
} finally {
|
|
153
|
+
clearTimeout(timeout);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// En ignoreManager.ts walkDirectoryAsync
|
|
158
|
+
private async walkAsync(
|
|
159
|
+
currentDir: string,
|
|
160
|
+
collected: string[],
|
|
161
|
+
signal?: AbortSignal // β
Nuevo parΓ‘metro
|
|
162
|
+
): Promise<void> {
|
|
163
|
+
// Check abort
|
|
164
|
+
if (signal?.aborted) {
|
|
165
|
+
throw new Error("Operation cancelled");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ... resto del cΓ³digo
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Test a crear:
|
|
173
|
+
- `tests/test-abort-controller.ts`
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## β
FASE 4: AST-AWARE DEPENDENCY CHECK (COMPLETADA)
|
|
178
|
+
|
|
179
|
+
**Tiempo:** 2h
|
|
180
|
+
**Archivos creados:**
|
|
181
|
+
- `src/utils/dependencyChecker.ts` β
|
|
182
|
+
|
|
183
|
+
**Archivos modificados:**
|
|
184
|
+
- `src/handlers/writeHandlers.ts` β
|
|
185
|
+
|
|
186
|
+
**Tests:** 149/149 pasando β
|
|
187
|
+
|
|
188
|
+
**Funcionalidad:**
|
|
189
|
+
- AST parsing para TS/JS/PHP
|
|
190
|
+
- Ignora sΓmbolos en comments/strings
|
|
191
|
+
- Elimina falsos positivos
|
|
192
|
+
|
|
193
|
+
### Archivos a modificar:
|
|
194
|
+
1. `src/handlers/writeHandlers.ts` - handleRemoveSymbol (lΓnea 480-510)
|
|
195
|
+
|
|
196
|
+
### Cambios necesarios:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
// ANTES (lΓnea 493-510) - Regex check
|
|
200
|
+
const escaped = symbolName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
201
|
+
const regex = new RegExp(`(?<=^|[^a-zA-Z0-9_$])(${escaped})(?=[^a-zA-Z0-9_$]|$)`);
|
|
202
|
+
|
|
203
|
+
if (regex.test(fContent)) {
|
|
204
|
+
return errorResponse(`Symbol "${symbolName}" used in ${path.relative(projectRoot, f)}. Use force: true to delete.`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// DESPUΓS - AST check
|
|
208
|
+
import { checkSymbolUsage } from "../utils/dependencyChecker.js";
|
|
209
|
+
|
|
210
|
+
const isUsed = await checkSymbolUsage(f, fContent, symbolName);
|
|
211
|
+
if (isUsed) {
|
|
212
|
+
return errorResponse(`Symbol "${symbolName}" used in ${path.relative(projectRoot, f)}. Use force: true to delete.`);
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Archivo a crear:
|
|
217
|
+
- `src/utils/dependencyChecker.ts`
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
/**
|
|
221
|
+
* AST-aware dependency checker
|
|
222
|
+
* Checks if a symbol is actually used in code (not in comments/strings)
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
import * as ts from "typescript";
|
|
226
|
+
import * as path from "node:path";
|
|
227
|
+
|
|
228
|
+
export async function checkSymbolUsage(
|
|
229
|
+
filePath: string,
|
|
230
|
+
content: string,
|
|
231
|
+
symbolName: string
|
|
232
|
+
): Promise<boolean> {
|
|
233
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
234
|
+
|
|
235
|
+
switch (ext) {
|
|
236
|
+
case ".ts":
|
|
237
|
+
case ".tsx":
|
|
238
|
+
case ".js":
|
|
239
|
+
case ".jsx":
|
|
240
|
+
return checkTSSymbolUsage(content, symbolName);
|
|
241
|
+
|
|
242
|
+
case ".php":
|
|
243
|
+
return checkPHPSymbolUsage(content, symbolName);
|
|
244
|
+
|
|
245
|
+
default:
|
|
246
|
+
// Fallback to regex for unsupported languages
|
|
247
|
+
const escaped = symbolName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
248
|
+
const regex = new RegExp(`(?<=^|[^a-zA-Z0-9_$])(${escaped})(?=[^a-zA-Z0-9_$]|$)`);
|
|
249
|
+
return regex.test(content);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function checkTSSymbolUsage(content: string, symbolName: string): boolean {
|
|
254
|
+
const sourceFile = ts.createSourceFile(
|
|
255
|
+
"temp.ts",
|
|
256
|
+
content,
|
|
257
|
+
ts.ScriptTarget.Latest,
|
|
258
|
+
true
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
let found = false;
|
|
262
|
+
|
|
263
|
+
function visit(node: ts.Node) {
|
|
264
|
+
// Check identifiers (skip string literals and comments)
|
|
265
|
+
if (ts.isIdentifier(node) && node.text === symbolName) {
|
|
266
|
+
found = true;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (!found) {
|
|
270
|
+
ts.forEachChild(node, visit);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
visit(sourceFile);
|
|
275
|
+
return found;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async function checkPHPSymbolUsage(content: string, symbolName: string): Promise<boolean> {
|
|
279
|
+
try {
|
|
280
|
+
const phpParserModule = await import("php-parser");
|
|
281
|
+
const phpParser = phpParserModule.default || phpParserModule;
|
|
282
|
+
const parser = new phpParser.Engine();
|
|
283
|
+
const ast = parser.parseCode(content, "temp.php");
|
|
284
|
+
|
|
285
|
+
let found = false;
|
|
286
|
+
|
|
287
|
+
function visit(node: any) {
|
|
288
|
+
if (node.kind === "identifier" && node.name === symbolName) {
|
|
289
|
+
found = true;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (!found && node.children) {
|
|
293
|
+
for (const child of node.children) {
|
|
294
|
+
visit(child);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
visit(ast);
|
|
300
|
+
return found;
|
|
301
|
+
} catch {
|
|
302
|
+
// Fallback to regex
|
|
303
|
+
const escaped = symbolName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
304
|
+
const regex = new RegExp(`(?<=^|[^a-zA-Z0-9_$])(${escaped})(?=[^a-zA-Z0-9_$]|$)`);
|
|
305
|
+
return regex.test(content);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Test a crear:
|
|
311
|
+
- `tests/test-dependency-checker.ts`
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## π¦ RELEASE v2.5.0
|
|
316
|
+
|
|
317
|
+
### Checklist final:
|
|
318
|
+
|
|
319
|
+
- [ ] Todas las fases completadas
|
|
320
|
+
- [ ] Todos los tests pasando
|
|
321
|
+
- [ ] Actualizar versiones:
|
|
322
|
+
- [ ] `package.json` β 2.5.0
|
|
323
|
+
- [ ] `src/utils/constants.ts` β SERVER_VERSION = "2.5.0"
|
|
324
|
+
- [ ] `README.md` β badge 2.5.0
|
|
325
|
+
- [ ] `llms.txt` β v2.5.0
|
|
326
|
+
- [ ] `CHANGELOG.md` β entrada 2.5.0
|
|
327
|
+
|
|
328
|
+
### CHANGELOG.md template:
|
|
329
|
+
|
|
330
|
+
```markdown
|
|
331
|
+
## [2.5.0] - 2024-01-XX
|
|
332
|
+
|
|
333
|
+
### π Performance & Reliability
|
|
334
|
+
|
|
335
|
+
- **Syntax Validation**: Automatic syntax checking before commit
|
|
336
|
+
- Validates TS, JS, PHP, Dart, Python
|
|
337
|
+
- Automatic rollback on syntax errors
|
|
338
|
+
- Prevents broken code from being written
|
|
339
|
+
|
|
340
|
+
- **Cache Memory Limits**: Real byte-based cache limits
|
|
341
|
+
- Prevents OOM on large repositories
|
|
342
|
+
- 100MB default limit (configurable)
|
|
343
|
+
- Evicts oldest entries when limit reached
|
|
344
|
+
|
|
345
|
+
- **AbortController Support**: Cancellable operations
|
|
346
|
+
- 60s timeout on get_semantic_repo_map
|
|
347
|
+
- Graceful cancellation of long operations
|
|
348
|
+
- Prevents hanging on large repos
|
|
349
|
+
|
|
350
|
+
- **AST-aware Dependency Check**: Eliminates false positives
|
|
351
|
+
- Uses AST parsing instead of regex
|
|
352
|
+
- Ignores symbols in comments and strings
|
|
353
|
+
- More accurate dependency detection in remove_symbol
|
|
354
|
+
|
|
355
|
+
### π Metrics Improvement
|
|
356
|
+
- Reliability: 8.5 β 9.5 (+1.0)
|
|
357
|
+
- Safety: 8.0 β 9.5 (+1.5)
|
|
358
|
+
- User Experience: 8.0 β 9.0 (+1.0)
|
|
359
|
+
|
|
360
|
+
### Technical
|
|
361
|
+
- All tests passing (160+ tests)
|
|
362
|
+
- Zero breaking changes
|
|
363
|
+
- Backward compatible
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Comandos de release:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
# 1. Build y test
|
|
370
|
+
npm run build
|
|
371
|
+
npm test
|
|
372
|
+
|
|
373
|
+
# 2. Git
|
|
374
|
+
git add .
|
|
375
|
+
git commit -m "v2.5.0: Syntax validation, cache limits, abort support, AST dependency check"
|
|
376
|
+
git push origin main
|
|
377
|
+
|
|
378
|
+
# 3. Tag
|
|
379
|
+
git tag -a v2.5.0 -m "v2.5.0: Quick Wins - Reliability & Safety"
|
|
380
|
+
git push origin v2.5.0
|
|
381
|
+
|
|
382
|
+
# 4. Publish
|
|
383
|
+
npm publish
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## π― ESTADO ACTUAL
|
|
389
|
+
|
|
390
|
+
**Γltima actualizaciΓ³n:** 2024-01-15
|
|
391
|
+
**Fase actual:** FASE 1 COMPLETADA β
|
|
392
|
+
**PrΓ³xima fase:** FASE 2 - Cache Memory Limits
|
|
393
|
+
**Progreso:** 25% (1/4 fases)
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## π NOTAS DE RECUPERACIΓN
|
|
398
|
+
|
|
399
|
+
Si la memoria se resetea:
|
|
400
|
+
|
|
401
|
+
1. Leer este archivo: `PLAN_v2.5.0.md`
|
|
402
|
+
2. Verificar fase actual en secciΓ³n "ESTADO ACTUAL"
|
|
403
|
+
3. Ejecutar: `git log --oneline -5` para ver ΓΊltimos commits
|
|
404
|
+
4. Ejecutar: `npm test` para verificar estado
|
|
405
|
+
5. Continuar con la fase marcada como PENDIENTE
|
|
406
|
+
|
|
407
|
+
**Para Dios, no para los hombres** - Colosenses 3:23
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://opensource.org/licenses/MIT)
|
|
4
4
|
[]()
|
|
5
5
|
[]()
|
|
6
|
-
[]()
|
|
7
7
|
|
|
8
8
|
> MCP server that compresses any codebase into LLM-ready semantic context **and provides surgical code editing tools**. AST-based read & write for TypeScript, JavaScript, PHP, Dart & Python.
|
|
9
9
|
|
|
@@ -11,17 +11,21 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export declare class LRUCache<K, V> {
|
|
13
13
|
private cache;
|
|
14
|
-
private
|
|
15
|
-
private
|
|
16
|
-
|
|
14
|
+
private maxEntries;
|
|
15
|
+
private maxBytes;
|
|
16
|
+
private currentEntries;
|
|
17
|
+
private currentBytes;
|
|
18
|
+
constructor(maxEntries?: number, maxBytes?: number);
|
|
17
19
|
get(key: K, filePath?: string): V | undefined;
|
|
18
20
|
set(key: K, value: V, filePath?: string, estimatedSize?: number): void;
|
|
19
21
|
has(key: K, filePath?: string): boolean;
|
|
20
22
|
invalidate(key: K): void;
|
|
21
23
|
clear(): void;
|
|
22
24
|
getStats(): {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
entries: number;
|
|
26
|
+
maxEntries: number;
|
|
27
|
+
bytes: number;
|
|
28
|
+
maxBytes: number;
|
|
25
29
|
};
|
|
26
30
|
}
|
|
27
31
|
export declare const tsAstCache: LRUCache<string, any>;
|
|
@@ -14,12 +14,16 @@ import * as path from "node:path";
|
|
|
14
14
|
// βββ LRU Cache Implementation βββββββββββββββββββββββββββββββββββββββ
|
|
15
15
|
export class LRUCache {
|
|
16
16
|
cache;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
maxEntries;
|
|
18
|
+
maxBytes;
|
|
19
|
+
currentEntries;
|
|
20
|
+
currentBytes;
|
|
21
|
+
constructor(maxEntries = 100, maxBytes = 100 * 1024 * 1024) {
|
|
20
22
|
this.cache = new Map();
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
23
|
+
this.maxEntries = maxEntries;
|
|
24
|
+
this.maxBytes = maxBytes;
|
|
25
|
+
this.currentEntries = 0;
|
|
26
|
+
this.currentBytes = 0;
|
|
23
27
|
}
|
|
24
28
|
get(key, filePath) {
|
|
25
29
|
const entry = this.cache.get(key);
|
|
@@ -31,13 +35,15 @@ export class LRUCache {
|
|
|
31
35
|
const currentMtime = stat.mtimeMs;
|
|
32
36
|
if (currentMtime !== entry.mtime) {
|
|
33
37
|
this.cache.delete(key);
|
|
34
|
-
this.
|
|
38
|
+
this.currentEntries--;
|
|
39
|
+
this.currentBytes -= entry.size;
|
|
35
40
|
return undefined;
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
catch {
|
|
39
44
|
this.cache.delete(key);
|
|
40
|
-
this.
|
|
45
|
+
this.currentEntries--;
|
|
46
|
+
this.currentBytes -= entry.size;
|
|
41
47
|
return undefined;
|
|
42
48
|
}
|
|
43
49
|
}
|
|
@@ -55,39 +61,61 @@ export class LRUCache {
|
|
|
55
61
|
catch { }
|
|
56
62
|
}
|
|
57
63
|
if (this.cache.has(key)) {
|
|
64
|
+
const oldEntry = this.cache.get(key);
|
|
58
65
|
this.cache.delete(key);
|
|
59
|
-
this.
|
|
66
|
+
this.currentEntries--;
|
|
67
|
+
this.currentBytes -= oldEntry.size;
|
|
60
68
|
}
|
|
61
|
-
while (this.
|
|
69
|
+
while (this.currentBytes + estimatedSize > this.maxBytes && this.cache.size > 0) {
|
|
62
70
|
const oldestKey = this.cache.keys().next().value;
|
|
63
|
-
|
|
71
|
+
const oldEntry = this.cache.get(oldestKey);
|
|
72
|
+
if (oldEntry) {
|
|
73
|
+
this.currentBytes -= oldEntry.size;
|
|
64
74
|
this.cache.delete(oldestKey);
|
|
65
|
-
this.
|
|
75
|
+
this.currentEntries--;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
while (this.currentEntries >= this.maxEntries) {
|
|
82
|
+
const oldestKey = this.cache.keys().next().value;
|
|
83
|
+
const oldEntry = this.cache.get(oldestKey);
|
|
84
|
+
if (oldEntry) {
|
|
85
|
+
this.currentBytes -= oldEntry.size;
|
|
86
|
+
this.cache.delete(oldestKey);
|
|
87
|
+
this.currentEntries--;
|
|
66
88
|
}
|
|
67
89
|
else {
|
|
68
90
|
break;
|
|
69
91
|
}
|
|
70
92
|
}
|
|
71
93
|
this.cache.set(key, { value, mtime, size: estimatedSize });
|
|
72
|
-
this.
|
|
94
|
+
this.currentEntries++;
|
|
95
|
+
this.currentBytes += estimatedSize;
|
|
73
96
|
}
|
|
74
97
|
has(key, filePath) {
|
|
75
98
|
return this.get(key, filePath) !== undefined;
|
|
76
99
|
}
|
|
77
100
|
invalidate(key) {
|
|
78
|
-
|
|
101
|
+
const entry = this.cache.get(key);
|
|
102
|
+
if (entry) {
|
|
79
103
|
this.cache.delete(key);
|
|
80
|
-
this.
|
|
104
|
+
this.currentEntries--;
|
|
105
|
+
this.currentBytes -= entry.size;
|
|
81
106
|
}
|
|
82
107
|
}
|
|
83
108
|
clear() {
|
|
84
109
|
this.cache.clear();
|
|
85
|
-
this.
|
|
110
|
+
this.currentEntries = 0;
|
|
111
|
+
this.currentBytes = 0;
|
|
86
112
|
}
|
|
87
113
|
getStats() {
|
|
88
114
|
return {
|
|
89
|
-
|
|
90
|
-
|
|
115
|
+
entries: this.currentEntries,
|
|
116
|
+
maxEntries: this.maxEntries,
|
|
117
|
+
bytes: this.currentBytes,
|
|
118
|
+
maxBytes: this.maxBytes,
|
|
91
119
|
};
|
|
92
120
|
}
|
|
93
121
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"astCache.js","sourceRoot":"","sources":["../../../src/cache/astCache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAUlC,uEAAuE;AAEvE,MAAM,OAAO,QAAQ;IACX,KAAK,CAAwB;IAC7B,
|
|
1
|
+
{"version":3,"file":"astCache.js","sourceRoot":"","sources":["../../../src/cache/astCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - read_file_lines
|
|
9
9
|
* - search_code_pattern
|
|
10
10
|
*/
|
|
11
|
-
export declare function handleGetSemanticRepoMap(args: Record<string, unknown
|
|
11
|
+
export declare function handleGetSemanticRepoMap(args: Record<string, unknown>, signal?: AbortSignal): Promise<{
|
|
12
12
|
content: {
|
|
13
13
|
type: "text";
|
|
14
14
|
text: string;
|