Watch mode and incremental update
Keep the structural graph aligned with the working tree without re-running full discover on every edit.
Commands
| Command | Role |
|---|---|
rgctl update | One-shot incremental patch (hash-diff, --files, or --since) |
rgctl serve --watch | Debounced filesystem watcher → same incremental updater |
rgctl status | Reports index_current / dirty file counts (no extract); also watcher_alive / queue depth |
rgctl discover | Cold index + optional analysis (--with-cfg, migration, Kantra, …) |
discover --files path1,path2 remains a compatible alias for update --files.
update vs discover
updateextracts/compacts changed paths only intograph.snapshot.binand refreshesfile_hashes.json. Analysis sidecars keyed on graph digest (CFG/PDG archive, blast snapshot, semantic index, …) are invalidated.discoverwalks the tree and can rebuild analysis artifacts when you pass the relevant flags. Use it for cold start and deliberate analysis refresh — not as the default agent “refresh” step.
serve --watch
rgctl serve --watch --open
# or query-only:
rgctl serve --watch --query-only --no-pipeline
Behavior:
- OS notifications (via
notify) on the session repo - Debounce (
rgctl.toml→[watch] debounce_ms, default 500) - Filter to language extensions; skip
.git,target,node_modules,.rgctl - Poll for CLI update queue + coalesce with FS pending paths
IncrementalUpdateron a dedicated watch thread (sole compact writer)- Existing serve digest poll hot-reloads the mmap graph
Default serve (without --watch) does not watch sources.
Exclusive writer (one watcher per repo)
.rgctl/watch.lock elects a sole snapshot writer (the live serve --watch process).
- A second
rgctl serve --watchon the same repo exits immediately with a clear error (does not start HTTP). - While a live watcher holds the lock,
rgctl updateenqueues work to.rgctl/update_queue.jsonland waits for.rgctl/update_results/<request_id>.jsonby default (does not compact in the CLI process). - Use
--no-waitto return after enqueue with{ queued: true, request_id }. - Use
--wait-timeout <secs>(default 60, orRGCTL_UPDATE_WAIT_TIMEOUT_SECS) to bound the wait. --forceis rejected while a live watcher is elected (stop watch or run fulldiscover).- Stopping the first
serve --watchreleases the lock (normal process exit). A hard kill can leave a stalewatch.lock— the nextupdate/serve --watchreclaims it when the recorded PID is dead.
You do not need to stop serve --watch to refresh the graph after bulk edits or missed notify events — run rgctl update.
Agent guidance
- Prefer
status→ ifindex_current == false→updateonce (works with or without watch) - Long edit sessions: run
serve --watchin the background; keep usingupdatewhen needed - Do not loop full
discoverfor dirty trees - Empty
blast-radiusfor a file that exists on disk →update --files <path>, retry, then source fallback - Optional:
statusfieldswatcher_alive/watcher_pid/update_queue_pendingfor diagnostics
Config
# rgctl.toml
[watch]
debounce_ms = 500
Related
- Issues #69 / #58 (hooks still follow-on)
- JSON API —
status/updateschemas - HTTP Server and Dashboard