@grec0/memory-bank-mcp 0.1.4 → 0.1.6
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/dist/index.js +8 -3
- package/dist/tools/analyzeCoverage.js +40 -32
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -177,22 +177,27 @@ server.tool("memorybank_get_stats", "Obtiene estadísticas del Memory Bank: arch
|
|
|
177
177
|
};
|
|
178
178
|
});
|
|
179
179
|
// Tool: Analyze Coverage
|
|
180
|
-
server.tool("memorybank_analyze_coverage", `Analiza la cobertura de indexación del proyecto.
|
|
180
|
+
server.tool("memorybank_analyze_coverage", `Analiza la cobertura de indexación del proyecto. RÁPIDO (~2s).
|
|
181
181
|
|
|
182
182
|
⚠️ IMPORTANTE:
|
|
183
183
|
- path debe ser RUTA ABSOLUTA al DIRECTORIO raíz del workspace
|
|
184
184
|
- Ejemplo: "C:/workspaces/mi-proyecto" (NO rutas relativas)
|
|
185
|
-
-
|
|
185
|
+
- Por defecto NO incluye árbol de directorios (lento en proyectos grandes)`, {
|
|
186
186
|
projectId: z
|
|
187
187
|
.string()
|
|
188
188
|
.describe("Identificador del proyecto (OBLIGATORIO)"),
|
|
189
189
|
path: z
|
|
190
190
|
.string()
|
|
191
191
|
.describe("RUTA ABSOLUTA al directorio raíz del workspace. Ejemplo: 'C:/workspaces/mi-proyecto'"),
|
|
192
|
+
includeTree: z
|
|
193
|
+
.boolean()
|
|
194
|
+
.optional()
|
|
195
|
+
.default(false)
|
|
196
|
+
.describe("Incluir árbol de directorios detallado (LENTO en proyectos grandes, omitir normalmente)"),
|
|
192
197
|
}, async (args) => {
|
|
193
198
|
try {
|
|
194
199
|
const targetPath = args.path;
|
|
195
|
-
const result = await analyzeCoverage(indexManager, vectorStore, targetPath, args.projectId);
|
|
200
|
+
const result = await analyzeCoverage(indexManager, vectorStore, targetPath, args.projectId, args.includeTree);
|
|
196
201
|
return {
|
|
197
202
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
198
203
|
};
|
|
@@ -202,8 +202,9 @@ function generateRecommendations(stats, tree) {
|
|
|
202
202
|
}
|
|
203
203
|
/**
|
|
204
204
|
* Analyzes indexation coverage of the project
|
|
205
|
+
* @param includeTree - Whether to include directory tree (slow for large projects, default false)
|
|
205
206
|
*/
|
|
206
|
-
export async function analyzeCoverage(indexManager, vectorStore, workspaceRoot, projectId) {
|
|
207
|
+
export async function analyzeCoverage(indexManager, vectorStore, workspaceRoot, projectId, includeTree = false) {
|
|
207
208
|
try {
|
|
208
209
|
console.error("\n=== Analizando cobertura de indexación ===");
|
|
209
210
|
console.error(`Workspace root: ${workspaceRoot}`);
|
|
@@ -234,44 +235,58 @@ export async function analyzeCoverage(indexManager, vectorStore, workspaceRoot,
|
|
|
234
235
|
console.error(`Error escaneando archivos: ${error}`);
|
|
235
236
|
throw error;
|
|
236
237
|
}
|
|
237
|
-
// 2. Get
|
|
238
|
-
console.error("Obteniendo
|
|
238
|
+
// 2. Get ALL chunks from vector store in ONE query (optimized)
|
|
239
|
+
console.error("Obteniendo todos los chunks indexados (query única)...");
|
|
239
240
|
await vectorStore.initialize();
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
//
|
|
241
|
+
const queryStart = Date.now();
|
|
242
|
+
const allChunks = await vectorStore.getAllChunks(projectId);
|
|
243
|
+
console.error(`Query completada en ${Date.now() - queryStart}ms - ${allChunks.length} chunks`);
|
|
244
|
+
// 3. Build indexed files map from chunks (in memory - fast)
|
|
245
|
+
console.error("Procesando chunks en memoria...");
|
|
244
246
|
const indexedFiles = new Map();
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
247
|
+
for (const chunk of allChunks) {
|
|
248
|
+
const existing = indexedFiles.get(chunk.file_path);
|
|
249
|
+
if (!existing) {
|
|
250
|
+
indexedFiles.set(chunk.file_path, {
|
|
251
|
+
lastIndexed: chunk.timestamp,
|
|
252
|
+
chunks: 1,
|
|
253
|
+
hash: chunk.file_hash,
|
|
252
254
|
});
|
|
253
255
|
}
|
|
256
|
+
else {
|
|
257
|
+
existing.chunks++;
|
|
258
|
+
// Keep most recent timestamp
|
|
259
|
+
if (chunk.timestamp > existing.lastIndexed) {
|
|
260
|
+
existing.lastIndexed = chunk.timestamp;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
254
263
|
}
|
|
255
|
-
//
|
|
264
|
+
// 4. Get index stats
|
|
265
|
+
const indexStats = await indexManager.getStats();
|
|
266
|
+
// 5. Identify pending files (files that changed) - in memory comparison
|
|
256
267
|
const pendingFiles = new Set();
|
|
257
268
|
for (const file of allFiles) {
|
|
258
269
|
const indexed = indexedFiles.get(file.path);
|
|
259
|
-
if (indexed) {
|
|
260
|
-
|
|
261
|
-
const chunks = await vectorStore.getChunksByFile(file.path);
|
|
262
|
-
if (chunks.length > 0 && chunks[0].file_hash !== file.hash) {
|
|
263
|
-
pendingFiles.add(file.path);
|
|
264
|
-
}
|
|
270
|
+
if (indexed && indexed.hash !== file.hash) {
|
|
271
|
+
pendingFiles.add(file.path);
|
|
265
272
|
}
|
|
266
273
|
}
|
|
267
274
|
console.error(`Archivos indexados: ${indexedFiles.size}`);
|
|
268
275
|
console.error(`Archivos con cambios: ${pendingFiles.size}`);
|
|
269
|
-
// 6.
|
|
270
|
-
console.error("Construyendo árbol de directorios...");
|
|
271
|
-
const tree = buildDirectoryTree(allFiles, indexedFiles, pendingFiles, workspaceRoot);
|
|
272
|
-
// 7. Calculate statistics
|
|
276
|
+
// 6. Calculate statistics (fast - in memory)
|
|
273
277
|
console.error("Calculando estadísticas...");
|
|
274
278
|
const stats = calculateStats(allFiles, indexedFiles, pendingFiles, indexStats.totalChunks);
|
|
279
|
+
// 7. Build directory tree ONLY if requested (slow for large projects)
|
|
280
|
+
let tree;
|
|
281
|
+
if (includeTree) {
|
|
282
|
+
console.error("Construyendo árbol de directorios (solicitado explícitamente)...");
|
|
283
|
+
const treeStart = Date.now();
|
|
284
|
+
tree = buildDirectoryTree(allFiles, indexedFiles, pendingFiles, workspaceRoot);
|
|
285
|
+
console.error(`Árbol construido en ${Date.now() - treeStart}ms`);
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
console.error("Árbol de directorios omitido (usa includeTree: true si lo necesitas)");
|
|
289
|
+
}
|
|
275
290
|
// 8. Generate recommendations
|
|
276
291
|
const recommendations = generateRecommendations(stats, tree);
|
|
277
292
|
// 9. Format message
|
|
@@ -305,13 +320,6 @@ export async function analyzeCoverage(indexManager, vectorStore, workspaceRoot,
|
|
|
305
320
|
languageBreakdown: {},
|
|
306
321
|
directoryBreakdown: {},
|
|
307
322
|
},
|
|
308
|
-
tree: {
|
|
309
|
-
name: "root",
|
|
310
|
-
path: "",
|
|
311
|
-
type: "directory",
|
|
312
|
-
status: "not_indexed",
|
|
313
|
-
children: [],
|
|
314
|
-
},
|
|
315
323
|
recommendations: [],
|
|
316
324
|
message: `Failed to analyze coverage: ${error}`,
|
|
317
325
|
};
|