How to Use Graphify Watch Mode for Live Knowledge Graph Updates
Graphify watch mode continuously monitors your repository for file changes and automatically rebuilds the knowledge graph when source code is modified, while deferring non-code changes (documentation, images) to a manual update cycle.
Graphify, an open-source tool from safishamsi/graphify that transforms codebases into interactive knowledge graphs, provides a watch mode that eliminates the need to manually regenerate your graph after every edit. According to the source code in graphify/watch.py, this feature uses a watchdog-based observer to detect filesystem events, classifies changes as either code or non-code, and rebuilds the graph incrementally without LLM calls for pure code modifications.
Core Architecture of Watch Mode
The watch system is implemented in graphify/watch.py and consists of several coordinated components that handle event detection, change classification, and safe concurrent rebuilds.
The watch() Entry Point
The watch() function (lines 5-16) initializes the filesystem observer and configures the main monitoring loop. It loads the .graphifyignore patterns once at startup (lines 27-35) to avoid repeated I/O, then enters a loop that applies debouncing logic before dispatching rebuilds.
Incremental Rebuilds via _rebuild_code()
When the watcher detects code file changes, it calls _rebuild_code() (lines 65-98), which performs an AST-only extraction without LLM involvement. This function:
- Acquires a per-repo advisory lock (
.rebuild.lock) to prevent concurrent rebuilds - Drains any queued changes from
.pending_changesusing_queue_pendingand_drain_pending(lines 16-68) - Runs
detect()andextract()from supporting modules to identify and parse changed files - Merges new AST nodes with existing semantic nodes while evicting deleted files
- Executes community detection via
cluster.pyand writes updatedgraph.json,GRAPH_REPORT.md, and optionallygraph.html
Non-Code Change Handling with _notify_only()
For non-code files (markdown, images, papers), the watcher invokes _notify_only() (lines 89-96). This function writes a needs_update flag to graphify-out/needs_update and prints a reminder to run /graphify --update later, since these changes require LLM-backed semantic extraction.
Change Classification and Debouncing
The watcher intelligently filters and batches events to avoid unnecessary rebuilds.
Extension-Based Classification
The system distinguishes between code and non-code files using constants defined in _has_non_code and extension checks (lines 1-8, 49-55). Files matching _CODE_EXTENSIONS trigger immediate rebuilds, while those matching _WATCHED_EXTENSIONS (non-code) trigger notification-only mode.
Debounce Logic
To prevent a rebuild for every keystroke, the watcher implements configurable debouncing (lines 74-82). The main loop waits for a specified number of seconds after the last filesystem event before triggering the rebuild pipeline. The default debounce is 3.0 seconds, ensuring batch processing of rapid file saves.
Ignore Pattern Support
Before processing any event, the watcher checks paths against .graphifyignore patterns cached at startup. This allows you to exclude directories like node_modules/ or venv/ from triggering rebuilds.
Running Watch Mode
You can activate watch mode via the command line or programmatically through the Python API.
CLI Usage
Watch the current directory with default settings:
graphify watch
Watch a specific path with a custom 1-second debounce:
graphify watch /path/to/my/project --debounce 1.0
Typical output shows the watcher status and classification decisions:
[graphify watch] Watching /path/to/my/project - press Ctrl+C to stop
[graphify watch] Code changes rebuild graph automatically. Doc/image changes require /graphify --update.
[graphify watch] Debounce: 3.0s
Programmatic API
Import the watch() function directly for custom integrations:
from pathlib import Path
from graphify.watch import watch
# Start monitoring with a 2.5-second debounce
watch(Path("/my/repo"), debounce=2.5)
Handling Concurrent Rebuilds
The watch system includes a lock and queue mechanism to handle overlapping changes safely. If a second change occurs while a rebuild is in progress, the watcher:
- Attempts to acquire the
.rebuild.lockfile using a non-blocking advisory lock - If the lock is busy, queues the change in
.pending_changes - Prints a status message: "Rebuild already in progress... - changes queued"
- Automatically merges queued changes when the current rebuild completes
This ensures that rapid file modifications don't corrupt the graph or trigger redundant extractions.
Summary
- Graphify watch mode monitors repositories continuously using
watchdogand rebuilds the knowledge graph automatically for code changes. - Code changes (
.py,.js, etc.) trigger_rebuild_code()ingraphify/watch.py(lines 65-98), which performs fast AST extraction without LLM calls. - Non-code changes invoke
_notify_only()(lines 89-96), writing aneeds_updateflag that requires manual/graphify --updatefor LLM processing. - Debounce logic (lines 74-82) waits for 3 seconds of inactivity by default to batch rapid edits.
- Concurrency protection uses advisory locks (
.rebuild.lock) and a pending changes queue to prevent overlapping rebuilds. - Use
.graphifyignoreto exclude directories from monitoring, and control the watcher via CLI (graphify watch --debounce 1.0) or the Python API.
Frequently Asked Questions
Does watch mode require an LLM to rebuild the graph?
No. For code-only changes, watch mode does not use LLM calls. The _rebuild_code() function in graphify/watch.py performs AST-only extraction using the extract.py and detect.py modules. LLM processing is only required for non-code files like documentation or images, which trigger the _notify_only() path and require you to manually run /graphify --update later.
What happens when I edit a Markdown file while watching?
When you save a Markdown file (or any non-code extension), the watcher detects this via _has_non_code (lines 49-55) and calls _notify_only() instead of rebuilding. It writes a flag to graphify-out/needs_update and prints a reminder that semantic re-extraction requires an LLM. Your existing graph remains unchanged until you run the full update command.
How do I prevent the watcher from monitoring certain directories?
Create a .graphifyignore file in your repository root with patterns similar to .gitignore. The watcher loads these patterns once at startup (lines 27-35) and filters out matching paths before any debouncing or classification occurs. Common exclusions include node_modules/, __pycache__/, and virtual environment folders.
Can I run multiple watchers on different projects simultaneously?
Yes, because each watcher maintains a project-specific lock file (.rebuild.lock) and pending changes queue (.pending_changes) within the target repository. However, ensure your system has sufficient resources for multiple watchdog observers, as each runs an independent monitoring thread.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →