# How to Use Graphify Watch Mode for Live Knowledge Graph Updates

> Learn how to use Graphify watch mode to automatically rebuild your knowledge graph on code changes. Keep your graph live and up-to-date effortlessly with safishamsi/graphify.

- Repository: [Safi/graphify](https://github.com/safishamsi/graphify)
- Tags: how-to-guide
- Published: 2026-06-15

---

**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`](https://github.com/safishamsi/graphify/blob/main/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`](https://github.com/safishamsi/graphify/blob/main/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_changes` using `_queue_pending` and `_drain_pending` (lines 16-68)
- Runs `detect()` and `extract()` 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.py`](https://github.com/safishamsi/graphify/blob/main/cluster.py) and writes updated [`graph.json`](https://github.com/safishamsi/graphify/blob/main/graph.json), [`GRAPH_REPORT.md`](https://github.com/safishamsi/graphify/blob/main/GRAPH_REPORT.md), and optionally [`graph.html`](https://github.com/safishamsi/graphify/blob/main/graph.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:

```bash
graphify watch

```

Watch a specific path with a custom 1-second debounce:

```bash
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:

```python
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:

1. Attempts to acquire the `.rebuild.lock` file using a non-blocking advisory lock
2. If the lock is busy, queues the change in `.pending_changes`
3. Prints a status message: "Rebuild already in progress... - changes queued"
4. 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 `watchdog` and rebuilds the knowledge graph automatically for code changes.
- **Code changes** (`.py`, `.js`, etc.) trigger `_rebuild_code()` in [`graphify/watch.py`](https://github.com/safishamsi/graphify/blob/main/graphify/watch.py) (lines 65-98), which performs fast AST extraction without LLM calls.
- **Non-code changes** invoke `_notify_only()` (lines 89-96), writing a `needs_update` flag that requires manual `/graphify --update` for 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 `.graphifyignore` to 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`](https://github.com/safishamsi/graphify/blob/main/graphify/watch.py) performs AST-only extraction using the [`extract.py`](https://github.com/safishamsi/graphify/blob/main/extract.py) and [`detect.py`](https://github.com/safishamsi/graphify/blob/main/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.