@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 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
- - Puede tardar en workspaces grandes`, {
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 indexed files from vector store
238
- console.error("Obteniendo archivos indexados...");
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 fileHashes = await vectorStore.getFileHashes();
241
- // 3. Get index metadata
242
- const indexStats = await indexManager.getStats();
243
- // 4. Build indexed files map with chunk counts
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
- // Get chunks grouped by file from vector store
246
- for (const [filePath, hash] of fileHashes) {
247
- const chunks = await vectorStore.getChunksByFile(filePath);
248
- if (chunks.length > 0) {
249
- indexedFiles.set(filePath, {
250
- lastIndexed: chunks[0].timestamp,
251
- chunks: chunks.length,
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
- // 5. Identify pending files (files that changed)
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
- // Check if file hash matches
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. Build directory tree
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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grec0/memory-bank-mcp",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "MCP server for semantic code indexing with Memory Bank - AI-powered codebase understanding",
5
5
  "license": "MIT",
6
6
  "author": "@grec0",