MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / startWatching

Method startWatching

src/mcp/engine.ts:278–331  ·  view source on GitHub ↗

* Start file watching on the active CodeGraph instance. Idempotent — the * watcher is per-engine, not per-session, which is why the daemon path * collapses N inotify sets to one. The wording of the disabled-reason log * exactly matches the prior in-tree implementation so log-driven dashboar

()

Source from the content-addressed store, hash-verified

276 * keep working.
277 */
278 private startWatching(): void {
279 if (!this.cg || this.watcherStarted || !this.opts.watch) return;
280
281 const disabledReason = watchDisabledReason(this.projectPath ?? process.cwd());
282 if (disabledReason) {
283 process.stderr.write(
284 `[CodeGraph MCP] File watcher disabled — ${disabledReason}. ` +
285 `The graph will not auto-update; run \`codegraph sync\` (or install the git sync hooks via \`codegraph init\`) to refresh.\n`
286 );
287 this.watcherStarted = true;
288 return;
289 }
290
291 // Optional override for the debounce window via env var (issue #403).
292 // Useful for workspaces with bursty writes (formatter-on-save chains,
293 // large generated outputs) where the 2s default fires too often. Clamped
294 // to [100ms, 60s]; out-of-range / non-numeric values fall back to the
295 // FileWatcher default. We log the active value so it's discoverable.
296 const debounceMs = parseDebounceEnv(process.env.CODEGRAPH_WATCH_DEBOUNCE_MS);
297 if (debounceMs !== undefined) {
298 process.stderr.write(`[CodeGraph MCP] File watcher debounce: ${debounceMs}ms (CODEGRAPH_WATCH_DEBOUNCE_MS)\n`);
299 }
300
301 const started = this.cg.watch({
302 debounceMs,
303 onSyncComplete: (result) => {
304 if (result.filesChanged > 0) {
305 process.stderr.write(
306 `[CodeGraph MCP] Auto-synced ${result.filesChanged} file(s) in ${result.durationMs}ms\n`
307 );
308 }
309 },
310 onSyncError: (err) => {
311 process.stderr.write(`[CodeGraph MCP] Auto-sync error: ${err.message}\n`);
312 },
313 onDegraded: (reason) => {
314 // Live watching gave up permanently (watch-resource exhaustion or a
315 // write lock held past the retry budget). Say so loudly and ONCE — the
316 // graph will no longer auto-update, so a long-running MCP session must
317 // not keep assuming it's fresh. The reason already names the remedy
318 // (`codegraph sync` / git sync hooks).
319 process.stderr.write(`[CodeGraph MCP] File watcher degraded — ${reason}\n`);
320 },
321 });
322
323 this.watcherStarted = true;
324 if (started) {
325 process.stderr.write('[CodeGraph MCP] File watcher active — graph will auto-sync on changes\n');
326 } else {
327 process.stderr.write(
328 '[CodeGraph MCP] File watcher unavailable on this platform — run `codegraph sync` to refresh the graph after changes.\n'
329 );
330 }
331 }
332
333 /**
334 * Reconcile the index with the current filesystem once, right after open —

Callers 2

retryInitializeSyncMethod · 0.95
doInitializeMethod · 0.95

Calls 4

watchDisabledReasonFunction · 0.90
parseDebounceEnvFunction · 0.85
watchMethod · 0.80
writeMethod · 0.65

Tested by

no test coverage detected