UNPKG

code-context-mcp

Version:

MCP server for semantic code search powered by MongoDB Atlas Vector Search and Voyage AI embeddings

125 lines 6.92 kB
import * as fs from "fs"; import { FileSynchronizer } from "@zilliz/claude-context-core"; export class SyncManager { context; snapshotManager; isSyncing = false; constructor(context, snapshotManager) { this.context = context; this.snapshotManager = snapshotManager; } async handleSyncIndex() { const syncStartTime = Date.now(); console.log(`[SYNC-DEBUG] handleSyncIndex() called at ${new Date().toISOString()}`); const indexedCodebases = this.snapshotManager.getIndexedCodebases(); if (indexedCodebases.length === 0) { console.log('[SYNC-DEBUG] No codebases indexed. Skipping sync.'); return; } console.log(`[SYNC-DEBUG] Found ${indexedCodebases.length} indexed codebases:`, indexedCodebases); if (this.isSyncing) { console.log('[SYNC-DEBUG] Index sync already in progress. Skipping.'); return; } this.isSyncing = true; console.log(`[SYNC-DEBUG] Starting index sync for all ${indexedCodebases.length} codebases...`); try { let totalStats = { added: 0, removed: 0, modified: 0 }; for (let i = 0; i < indexedCodebases.length; i++) { const codebasePath = indexedCodebases[i]; const codebaseStartTime = Date.now(); console.log(`[SYNC-DEBUG] [${i + 1}/${indexedCodebases.length}] Starting sync for codebase: '${codebasePath}'`); // Check if codebase path still exists try { const pathExists = fs.existsSync(codebasePath); console.log(`[SYNC-DEBUG] Codebase path exists: ${pathExists}`); if (!pathExists) { console.warn(`[SYNC-DEBUG] Codebase path '${codebasePath}' no longer exists. Skipping sync.`); continue; } } catch (pathError) { console.error(`[SYNC-DEBUG] Error checking codebase path '${codebasePath}':`, pathError); continue; } try { console.log(`[SYNC-DEBUG] Calling context.reindexByChange() for '${codebasePath}'`); const stats = await this.context.reindexByChange(codebasePath); const codebaseElapsed = Date.now() - codebaseStartTime; console.log(`[SYNC-DEBUG] Reindex stats for '${codebasePath}':`, stats); console.log(`[SYNC-DEBUG] Codebase sync completed in ${codebaseElapsed}ms`); // Accumulate total stats totalStats.added += stats.added; totalStats.removed += stats.removed; totalStats.modified += stats.modified; if (stats.added > 0 || stats.removed > 0 || stats.modified > 0) { console.log(`[SYNC] Sync complete for '${codebasePath}'. Added: ${stats.added}, Removed: ${stats.removed}, Modified: ${stats.modified} (${codebaseElapsed}ms)`); } else { console.log(`[SYNC] No changes detected for '${codebasePath}' (${codebaseElapsed}ms)`); } } catch (error) { const codebaseElapsed = Date.now() - codebaseStartTime; console.error(`[SYNC-DEBUG] Error syncing codebase '${codebasePath}' after ${codebaseElapsed}ms:`, error); console.error(`[SYNC-DEBUG] Error stack:`, error.stack); if (error.message.includes('Failed to query Milvus')) { // Collection maybe deleted manually, delete the snapshot file await FileSynchronizer.deleteSnapshot(codebasePath); } // Log additional error details if (error.code) { console.error(`[SYNC-DEBUG] Error code: ${error.code}`); } if (error.errno) { console.error(`[SYNC-DEBUG] Error errno: ${error.errno}`); } // Continue with next codebase even if one fails } } const totalElapsed = Date.now() - syncStartTime; console.log(`[SYNC-DEBUG] Total sync stats across all codebases: Added: ${totalStats.added}, Removed: ${totalStats.removed}, Modified: ${totalStats.modified}`); console.log(`[SYNC-DEBUG] Index sync completed for all codebases in ${totalElapsed}ms`); console.log(`[SYNC] Index sync completed for all codebases. Total changes - Added: ${totalStats.added}, Removed: ${totalStats.removed}, Modified: ${totalStats.modified}`); } catch (error) { const totalElapsed = Date.now() - syncStartTime; console.error(`[SYNC-DEBUG] Error during index sync after ${totalElapsed}ms:`, error); console.error(`[SYNC-DEBUG] Error stack:`, error.stack); } finally { this.isSyncing = false; const totalElapsed = Date.now() - syncStartTime; console.log(`[SYNC-DEBUG] handleSyncIndex() finished at ${new Date().toISOString()}, total duration: ${totalElapsed}ms`); } } startBackgroundSync() { console.log('[SYNC-DEBUG] startBackgroundSync() called'); // Execute initial sync immediately after a short delay to let server initialize console.log('[SYNC-DEBUG] Scheduling initial sync in 5 seconds...'); setTimeout(async () => { console.log('[SYNC-DEBUG] Executing initial sync after server startup'); try { await this.handleSyncIndex(); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); if (errorMessage.includes('Failed to query collection')) { console.log('[SYNC-DEBUG] Collection not yet established, this is expected for new cluster users. Will retry on next sync cycle.'); } else { console.error('[SYNC-DEBUG] Initial sync failed with unexpected error:', error); throw error; } } }, 5000); // Initial sync after 5 seconds // Periodically check for file changes and update the index console.log('[SYNC-DEBUG] Setting up periodic sync every 5 minutes (300000ms)'); const syncInterval = setInterval(() => { console.log('[SYNC-DEBUG] Executing scheduled periodic sync'); this.handleSyncIndex(); }, 5 * 60 * 1000); // every 5 minutes console.log('[SYNC-DEBUG] Background sync setup complete. Interval ID:', syncInterval); } } //# sourceMappingURL=sync.js.map