@grec0/memory-bank-mcp 0.1.38 → 0.1.40

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.
@@ -6,7 +6,10 @@
6
6
  import * as path from "path";
7
7
  import * as fs from "fs";
8
8
  import * as crypto from "crypto";
9
+ import { fileURLToPath } from "url";
9
10
  import { encode } from "gpt-tokenizer";
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = path.dirname(__filename);
10
13
  // Constants
11
14
  const MAX_TOKENS_PER_CHUNK = 6000;
12
15
  const DEFAULT_CHUNK_OVERLAP_TOKENS = 200;
@@ -214,6 +214,38 @@ export class IndexManager {
214
214
  .replace(/^-|-$/g, "");
215
215
  return sanitized || "default";
216
216
  }
217
+ /**
218
+ * Processes a batch of files concurrently
219
+ */
220
+ async processBatch(batch, startIndex, totalFiles, forceReindex, projectId) {
221
+ const batchErrors = [];
222
+ const batchChangedFiles = [];
223
+ let batchChunks = 0;
224
+ let batchProcessed = 0;
225
+ const results = await Promise.all(batch.map(async (file, index) => {
226
+ console.error(`\n[${startIndex + index + 1}/${totalFiles}] Processing ${file.path}`);
227
+ return {
228
+ file,
229
+ result: await this.indexFile(file, forceReindex, projectId)
230
+ };
231
+ }));
232
+ for (const { file, result } of results) {
233
+ if (result.error) {
234
+ batchErrors.push(result.error);
235
+ }
236
+ else {
237
+ batchProcessed++;
238
+ batchChunks += result.chunksCreated;
239
+ batchChangedFiles.push(file.path);
240
+ }
241
+ }
242
+ return {
243
+ processedCount: batchProcessed,
244
+ chunksCount: batchChunks,
245
+ changedFiles: batchChangedFiles,
246
+ errors: batchErrors
247
+ };
248
+ }
217
249
  /**
218
250
  * Indexes multiple files or a directory
219
251
  */
@@ -281,18 +313,15 @@ export class IndexManager {
281
313
  const changedFiles = [];
282
314
  let totalChunks = 0;
283
315
  let processedFiles = 0;
284
- for (let i = 0; i < filesToIndex.length; i++) {
285
- const file = filesToIndex[i];
286
- console.error(`\n[${i + 1}/${filesToIndex.length}] Processing ${file.path}`);
287
- const result = await this.indexFile(file, options.forceReindex || false, projectId);
288
- if (result.error) {
289
- errors.push(result.error);
290
- }
291
- else {
292
- processedFiles++;
293
- totalChunks += result.chunksCreated;
294
- changedFiles.push(file.path);
295
- }
316
+ // Process files in batches of 5
317
+ const batchSize = 5;
318
+ for (let i = 0; i < filesToIndex.length; i += batchSize) {
319
+ const batch = filesToIndex.slice(i, i + batchSize);
320
+ const batchResult = await this.processBatch(batch, i, filesToIndex.length, options.forceReindex || false, projectId);
321
+ processedFiles += batchResult.processedCount;
322
+ totalChunks += batchResult.chunksCount;
323
+ changedFiles.push(...batchResult.changedFiles);
324
+ errors.push(...batchResult.errors);
296
325
  }
297
326
  const indexDuration = Date.now() - startTime;
298
327
  console.error(`\n=== Indexing complete ===`);
@@ -101,4 +101,28 @@ export class RegistryManager {
101
101
  const registry = await this.ensureRegistry();
102
102
  return registry.projects.find(p => p.projectId === projectId);
103
103
  }
104
+ /**
105
+ * Syncs all projects from the JSON registry to the vector store.
106
+ * Useful for migrating existing projects to the new semantic discovery system.
107
+ */
108
+ async syncRegistry(embeddingService) {
109
+ const registry = await this.ensureRegistry();
110
+ let processed = 0;
111
+ let failures = 0;
112
+ console.error(`Syncing ${registry.projects.length} projects to vector store...`);
113
+ for (const project of registry.projects) {
114
+ try {
115
+ await this.updateProjectEmbedding(project, embeddingService);
116
+ processed++;
117
+ if (processed % 10 === 0) {
118
+ console.error(`Synced ${processed}/${registry.projects.length} projects`);
119
+ }
120
+ }
121
+ catch (error) {
122
+ console.error(`Failed to sync project ${project.projectId}: ${error}`);
123
+ failures++;
124
+ }
125
+ }
126
+ return { processed, failures };
127
+ }
104
128
  }
@@ -1,2 +1,2 @@
1
1
  // Version of the MCP Kanban server
2
- export const VERSION = "0.1.38";
2
+ export const VERSION = "0.1.39";
package/dist/index.js CHANGED
@@ -82,6 +82,7 @@ import { trackProgress, trackProgressToolDefinition } from "./tools/trackProgres
82
82
  import { manageAgentsTool, manageAgentsToolDefinition } from "./tools/manageAgents.js";
83
83
  import { discoverProjectsTool, discoverProjectsToolDefinition } from "./tools/discoverProjects.js";
84
84
  import { delegateTaskTool, delegateTaskToolDefinition } from "./tools/delegateTask.js";
85
+ import { syncProjectsTool, syncProjectsToolDefinition } from "./tools/syncProjects.js";
85
86
  import { RegistryManager } from "./common/registryManager.js";
86
87
  import { VERSION } from "./common/version.js";
87
88
  // Global services
@@ -837,6 +838,13 @@ server.tool(discoverProjectsToolDefinition.name, discoverProjectsToolDefinition.
837
838
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
838
839
  };
839
840
  });
841
+ // Tool: Sync Projects
842
+ server.tool(syncProjectsToolDefinition.name, syncProjectsToolDefinition.description, {}, async () => {
843
+ const result = await syncProjectsTool();
844
+ return {
845
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
846
+ };
847
+ });
840
848
  // Tool: Delegate Task
841
849
  server.tool(delegateTaskToolDefinition.name, delegateTaskToolDefinition.description, {
842
850
  projectId: z.string().describe("ID del proyecto origen (quien pide)"),
@@ -10,6 +10,7 @@ export * from "./readFile.js";
10
10
  export * from "./writeFile.js";
11
11
  export * from "./getStats.js";
12
12
  export * from "./analyzeCoverage.js";
13
+ export * from "./syncProjects.js";
13
14
  // Export Project Knowledge Layer tools
14
15
  export * from "./generateProjectDocs.js";
15
16
  export * from "./getProjectDocs.js";
@@ -0,0 +1,34 @@
1
+ import { RegistryManager } from '../common/registryManager.js';
2
+ import { EmbeddingService } from '../common/embeddingService.js';
3
+ export async function syncProjectsTool() {
4
+ if (!process.env.OPENAI_API_KEY) {
5
+ return {
6
+ success: false,
7
+ message: "OPENAI_API_KEY environment variable is required for syncing projects."
8
+ };
9
+ }
10
+ try {
11
+ const registryManager = new RegistryManager();
12
+ const embeddingService = new EmbeddingService(process.env.OPENAI_API_KEY);
13
+ const result = await registryManager.syncRegistry(embeddingService);
14
+ return {
15
+ success: true,
16
+ message: `Synchronization complete. Processed: ${result.processed}, Failures: ${result.failures}`,
17
+ details: result
18
+ };
19
+ }
20
+ catch (error) {
21
+ return {
22
+ success: false,
23
+ message: `Error during synchronization: ${error}`
24
+ };
25
+ }
26
+ }
27
+ export const syncProjectsToolDefinition = {
28
+ name: "memorybank_sync_projects",
29
+ description: "Sincroniza todos los proyectos del registro JSON al store vectorial para habilitar la búsqueda semántica. Útil para migrar datos existentes.",
30
+ inputSchema: {
31
+ type: "object",
32
+ properties: {}
33
+ }
34
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grec0/memory-bank-mcp",
3
- "version": "0.1.38",
3
+ "version": "0.1.40",
4
4
  "description": "MCP server for semantic code indexing with Memory Bank - AI-powered codebase understanding",
5
5
  "license": "MIT",
6
6
  "author": "@grec0",