Expand description
File system watcher with auto-reindexing for cartog.
Watches a directory for source file changes using debounced filesystem events, triggers incremental re-indexing, and optionally defers RAG embedding to batch changed symbols after a configurable quiet period.
§cartog-watch
File system watcher with auto-reindexing for cartog.
§Overview
Watches a directory for source file changes and triggers incremental re-indexing. Optionally defers RAG embedding to batch changed symbols after a quiet period.
§How it works
§Debounced file watching
Uses notify-debouncer-mini to batch rapid filesystem events into a single re-index call. Default debounce window is 5 seconds.
Events are filtered to relevant paths only: the file must have a supported extension (code or Markdown, via detect_language) and not be under an ignored directory (.git, node_modules, target, etc.).
§RAG timer
RAG auto-embed is on when the repo already has embeddings; rag_override: Some(bool) forces it on or off. When enabled:
- After each re-index, check if any symbols need embedding
- If yes, record
Instant::now()and setrag_pending = true - Poll every 500ms; when
elapsed >= rag_delay(default: 30s), trigger embedding - On graceful shutdown (Ctrl+C), flush any pending embeddings before exiting
The delay avoids re-embedding after every single file save during active editing.
§Execution modes
spawn_watch(config, db_path)— runs the watch loop on a background thread, returns aWatchHandlefor stop/droprun_watch(config, db_path)— runs the watch loop in the foreground (blocking), with Ctrl+C handler for graceful shutdown
Both modes open their own Database connection (SQLite WAL allows concurrent readers).
§Public API
| Export | Description |
|---|---|
WatchConfig | Configuration: root, debounce, rag_override: Option<bool> (force RAG auto-embed on/off; None defers to live data), rag_delay, rag_config: rag::EmbeddingProviderConfig (embedding + reranker config, threaded from .cartog.toml), redact: RedactionConfig (secret scrubbing on re-index), json_events (emit machine-readable event lines), pid_lock_dir + pid_lock_slot (PID-lock tracking; both must be set together or neither), skip_migrations, stale: Option<Arc<StaleState>> (shared staleness state for the MCP server; None disables publishing) |
StaleSnapshot / StaleState | Structural-staleness state (monotonic change_seq counters), written by the watch thread and read by the MCP server over an Arc<StaleState> to drive the ⚠️ staleness banners |
WatchHandle | Handle to stop a background watcher (via stop() or Drop) |
WATCH_LOCK_SLOT | Conventional PID-lock slot name ("watch") |
spawn_watch(config, db_path) | Start watching on a background thread |
run_watch(config, db_path) | Start watching in the foreground (blocking) |
§Crate dependencies
cartog-core, cartog-db, cartog-indexer, cartog-rag, cartog-process-lock
Structs§
- Stale
Snapshot - An immutable read of
StaleState. - Stale
State - Shared staleness state, written by the watch thread and read by the MCP
server over an
Arc<StaleState>. - Watch
Config - Configuration for the watch loop.
- Watch
Handle - Handle returned by
spawn_watch. Drop or callstop()to shut down the watcher.
Constants§
- WATCH_
LOCK_ SLOT - Legacy fallback slot used in untracked mode (
pid_lock_dir = None,pid_lock_slot = None). Whenpid_lock_diris set, callers must provide a DB-scoped slot viacartog::state::slot_for_db("watch", db_path)— seeWatchConfig::pid_lock_slot.
Functions§
- run_
watch - Run the watch loop in the foreground (blocking).
- spawn_
watch - Spawn the watch loop on a background thread.