# How Daemon Mode Handles Multiple Repositories with Auto-Watch in Code-Review-Graph

> Discover how the crg-daemon handles multiple repositories in daemon mode. Learn how it auto-watches and manages watchers for your Code-Review-Graph projects automatically and efficiently.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: internals
- Published: 2026-07-18

---

**The `crg-daemon` background process monitors a central TOML configuration file to automatically spawn, manage, and restart individual watcher processes for each repository without requiring manual intervention when repositories are added or removed.**

The **code-review-graph** daemon provides a centralized background service capable of watching unlimited repositories simultaneously. Instead of running separate `code-review-graph watch` commands for each project, the daemon maintains a persistent configuration at `~/.code-review-graph/watch.toml` and handles process lifecycle management automatically. This architecture ensures that code review graphs stay synchronized across all monitored repositories through a single controlling process.

## Configuration Loading and Validation

The daemon initializes by loading repository definitions from a TOML configuration file located at `~/.code-review-graph/watch.toml` (referenced via `CONFIG_PATH` at line 41 in [`code_review_graph/daemon.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/daemon.py)).

The `load_config` function (lines 84-118) parses this file and constructs a **`DaemonConfig`** dataclass containing a list of **`WatchRepo`** records. During loading, the daemon validates each repository entry to ensure the path exists and contains a version control marker (`.git`, `.svn`, or `.code-review-graph`). Invalid entries are filtered out before the daemon proceeds to process initialization.

## Spawning Per-Repository Watch Processes

When the daemon starts via the `_handle_start` function in [`code_review_graph/daemon_cli.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/daemon_cli.py) (line 31), it instantiates the **`WatchDaemon`** class (defined at line 588 in [`daemon.py`](https://github.com/tirth8205/code-review-graph/blob/main/daemon.py)) with the loaded configuration.

For each repository in `config.repos`, the `WatchDaemon.start` method launches a dedicated child process running the standard `code-review-graph watch` CLI command. Each child process receives its own log file under `~/.code-review-graph/logs/<alias>.log`, ensuring isolated logging for every monitored repository. This separation prevents crashes in one repository watcher from affecting others.

## Auto-Watch Mechanism and Health Monitoring

The daemon implements **auto-watch** through a continuous polling loop that checks the configuration file every 2 seconds (`poll_interval` default). When users modify [`watch.toml`](https://github.com/tirth8205/code-review-graph/blob/main/watch.toml)—either manually or through `crg-daemon add` and `remove` commands—the daemon detects the file change, reloads the configuration, and automatically starts or stops the associated child watchers without requiring a daemon restart.

A separate health-check thread runs every 30 seconds (controlled by `_HEALTH_CHECK_INTERVAL` at line 44) to verify that each child process remains alive. If a watcher process dies unexpectedly, the daemon automatically respawns it, ensuring continuous monitoring of all configured repositories.

## Managing Repositories via CLI

The daemon provides a complete command-line interface for runtime repository management. The following workflow demonstrates adding multiple repositories and monitoring their status:

```bash

# Add repositories to the watch list

crg-daemon add ~/projects/api --alias api
crg-daemon add ~/projects/web

# Start the background daemon

crg-daemon start

# Check individual watcher status

crg-daemon status

# Output shows PID and health for each repository:

# Daemon:  running (PID 12345)

# Name:    crg-watch

# Log dir: /home/user/.code-review-graph/logs

# Poll:    2s

#

#  Alias   Status   PID      Path

#  -----   ------   ---      ----

#  api     alive    12346    /home/user/projects/api

#  web     alive    12347    /home/user/projects/web

# Add a new repository without restarting the daemon

crg-daemon add ~/projects/cli --alias cli

# Remove a repository and stop its watcher

crg-daemon remove api

```

The `add_repo_to_config` and `remove_repo_from_config` functions safely modify [`watch.toml`](https://github.com/tirth8205/code-review-graph/blob/main/watch.toml) while the daemon is running, triggering the auto-watch reload mechanism immediately.

## Summary

- **Centralized configuration**: The daemon reads repository definitions from `~/.code-review-graph/watch.toml` using the `load_config` parser (lines 84-118).
- **Isolated child processes**: Each repository runs in its own `code-review-graph watch` subprocess managed by the `WatchDaemon` class (line 588), with dedicated log files in `~/.code-review-graph/logs/`.
- **Automatic reconciliation**: The daemon polls the configuration file every 2 seconds to detect additions or removals, updating active watchers without restarts.
- **Self-healing architecture**: A health-check loop running every 30 seconds (`_HEALTH_CHECK_INTERVAL`) automatically restarts any crashed watcher processes.

## Frequently Asked Questions

### How does the daemon detect new repositories without restarting?

The daemon polls `~/.code-review-graph/watch.toml` every 2 seconds (configurable via `poll_interval`). When you execute `crg-daemon add` or manually edit the file, the `WatchDaemon` detects the modification timestamp change, reloads the configuration through `load_config`, and spawns new child processes for any added repositories while leaving existing watchers untouched.

### What happens if a watcher process crashes?

The daemon's health-check thread evaluates every child PID every 30 seconds using the `_HEALTH_CHECK_INTERVAL` constant (line 44). If a process is no longer alive, the daemon automatically invokes the spawning logic again to restart that specific repository watcher, ensuring continuous monitoring without user intervention.

### Where does the daemon store its configuration and logs?

Configuration persists at `~/.code-review-graph/watch.toml` (defined in `CONFIG_PATH` at line 41), while runtime logs reside in `~/.code-review-graph/logs/`. Each repository receives its own log file named `<alias>.log`, and the daemon itself writes to `daemon.log` in the same directory.

### Can I run the daemon in the foreground for debugging?

Yes. Start the daemon with the `--foreground` flag to prevent background detachment. This mode keeps the process attached to your terminal, allowing you to observe the polling loop and health-check output directly without checking log files.