@knath2000/codebase-indexing-mcp
Version:
MCP server for codebase indexing with Voyage AI embeddings and Qdrant vector storage
80 lines • 3.18 kB
JavaScript
import chokidar from 'chokidar';
import { extname } from 'path';
/**
* Watches the workspace directory for file changes and triggers incremental re-indexing.
*/
export class WorkspaceWatcher {
constructor(rootDir, indexingService, supportedExtensions, excludePatterns) {
this.watcher = null;
this.rootDir = rootDir;
this.indexingService = indexingService;
this.supportedExtensions = new Set(supportedExtensions);
this.excludePatterns = excludePatterns;
}
/** Start watching the workspace directory. */
start() {
if (this.watcher) {
console.log('👁️ Workspace watcher already active');
return; // already watching
}
console.log(`👁️ Starting workspace watcher for: ${this.rootDir}`);
console.log(`📁 Watching extensions: ${Array.from(this.supportedExtensions).join(', ')}`);
console.log(`🚫 Excluding patterns: ${this.excludePatterns.join(', ')}`);
this.watcher = chokidar.watch(this.rootDir, {
ignored: this.excludePatterns,
persistent: true,
ignoreInitial: true,
});
this.watcher
.on('add', (filePath) => void this.handleAdd(filePath))
.on('change', (filePath) => void this.handleChange(filePath))
.on('unlink', (filePath) => void this.handleUnlink(filePath))
.on('error', (err) => console.error('❌ File watcher error:', err));
console.log(`✅ Workspace watcher active - monitoring for file changes...`);
}
/** Stop watching the workspace directory. */
stop() {
this.watcher?.close();
this.watcher = null;
}
isSupportedFile(filePath) {
return this.supportedExtensions.has(extname(filePath));
}
async handleAdd(filePath) {
if (!this.isSupportedFile(filePath))
return;
try {
console.log(`📄 File added: ${filePath} - indexing...`);
await this.indexingService.indexFile(filePath);
console.log(`✅ File indexed: ${filePath}`);
}
catch (err) {
console.error(`❌ Failed to index new file ${filePath}:`, err);
}
}
async handleChange(filePath) {
if (!this.isSupportedFile(filePath))
return;
try {
console.log(`🔄 File changed: ${filePath} - re-indexing...`);
await this.indexingService.reindexFile(filePath);
console.log(`✅ File re-indexed: ${filePath}`);
}
catch (err) {
console.error(`❌ Failed to re-index changed file ${filePath}:`, err);
}
}
async handleUnlink(filePath) {
if (!this.isSupportedFile(filePath))
return;
try {
console.log(`🗑️ File removed: ${filePath} - removing from index...`);
await this.indexingService.removeFile(filePath);
console.log(`✅ File removed from index: ${filePath}`);
}
catch (err) {
console.error(`❌ Failed to remove file ${filePath} from index:`, err);
}
}
}
//# sourceMappingURL=workspace-watcher.js.map