← The Tickd Guide

Tutorials & Guides

How to Build a Local File-Watcher that Uses Claude to Auto-Document Your Codebase

Stop writing documentation manually. Build a lightweight Python daemon that monitors your local files and uses Claude to update your project docs in the background every time you hit save.

Updated 9/2/2026

The Documentation Debt is Real

We all know the drill. You start a project with the grandest intentions of maintaining pristine, comprehensive documentation. Three days later, you’re knee-deep in a refactoring session, your functions have mutated three times, and your markdown files are relics of a distant past.

Instead of breaking your flow to update documentation, we can automate the chore. In this tutorial, we will build a lightweight Python daemon that sits quietly in the background, watches your local directories for changes, and uses the Claude API to update your project's documentation files in real-time. It runs locally, respects your gitignore, and keeps your project’s documentation ticked over without you having to lift a finger.

Why Build a Daemon Instead of Using an IDE Extension?

IDE extensions are brilliant, but they are also incredibly noisy. They pop up suggestions when you are mid-thought, interrupt your typing, and demand immediate attention.

By building an independent background file-watcher, we separate code execution from documentation generation. You write code, hit save, and go grab a cup of tea. By the time you look at your docs/ folder, the changes have been catalogued. We will use /platforms/claude for this, as its ability to grasp codebase architecture and write structured markdown is unmatched in the current LLM landscape.

Prerequisites

To build this tool, you will need: - Python 3.10 or higher installed on your machine. - An Anthropic API key. - A clean workspace directory to test on.

First, let's install the necessary Python packages. We will use watchdog to monitor our filesystem and the official anthropic SDK to communicate with Claude.

`bash pip install watchdog anthropic python-dotenv `

Create a .env file in your root folder and add your credentials:

`env ANTHROPIC_API_KEY=your_api_key_here `

Step 1: Setting Up the File Watcher

First, we need to detect when a file has actually changed. We don’t want to trigger an API call for every single keystroke or draft autosave, so we will implement a simple debouncing mechanism. This ensures that we only call Claude after a file has stopped changing for a few seconds.

Create a file named watcher.py and write the core watchdog logic:

`python import os import time from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler from dotenv import load_dotenv

load_dotenv()

class CodebaseHandler(FileSystemEventHandler): def __init__(self, callback): self.callback = callback self.last_modified = {} self.debounce_interval = 3.0 # seconds

def on_modified(self, event): if event.is_directory: return # We only care about Python, JS, TS, or Rust files in this example allowed_extensions = ('.py', '.js', '.ts', '.rs') if not event.src_path.endswith(allowed_extensions): return

Ignore things in virtual environments, build folders, or git directories ignored_paths = ['venv', '.git', '__pycache__', 'node_modules', 'dist', 'build'] if any(ignored in event.src_path for ignored in ignored_paths): return

now = time.time() filepath = event.src_path # Check if the file was modified very recently to avoid double-triggers if filepath in self.last_modified: if now - self.last_modified[filepath] < self.debounce_interval: return self.last_modified[filepath] = now print(f"File change detected: {filepath}. Queueing documentation run...") self.callback(filepath) `

Step 2: Crafting the System Prompt

Now we need to instruct Claude how to behave. We don't want conversational fluff; we want highly accurate, structured documentation that mirrors the codebase structure.

To construct solid guidelines, we can lean on some of the structural design rules found in our /prompts. We will instruct Claude to return only valid Markdown with clear headings detailing: 1. A high-level description of what the module does. 2. Key functions/classes and their arguments. 3. Dependencies and side effects.

Let's write a function in a new module, generator.py, to handle this transaction:

`python from anthropic import Anthropic

client = Anthropic()

SYSTEM_PROMPT = """ You are a senior technical writer. Your task is to generate clean, professional technical documentation for a codebase file. Analyze the code provided and write a corresponding markdown documentation file.

Your output must be strictly markdown, following this exact structure: # [Module Name] - Overview: A 2-sentence summary of the purpose of this file. - Dependencies: Any imported libraries or external systems. - Interface: A breakdown of the classes and public functions, including their parameters, return types, and exceptions. - Developer Notes: Any architectural caveats, performance considerations, or scaling gotchas.

Do not include any conversational filler. Start directly with the markdown content. """

def generate_docs(file_path): try: with open(file_path, 'r') as f: code_content = f.read() except Exception as e: print(f"Could not read file {file_path}: {e}") return None

print(f"Sending code to Claude for generation...") response = client.messages.create( model="claude-3-5-sonnet-20241022", max_tokens=1500, temperature=0.2, # We want deterministic, low-creativity documentation system=SYSTEM_PROMPT, messages=[ { "role": "user", "content": f"Please document the following code file: {file_path}\n\nCode:\n`\n{code_content}\n`" } ] ) return response.content[0].text `

Step 3: Mirroring the Directory and Saving the Docs

Instead of polluting your source folders with random markdown files, it is cleaner to mirror your project structure inside a dedicated docs/ directory. For example, if you edit src/utils/parser.py, the documentation should automatically write to docs/src/utils/parser.md.

Let’s implement this directory mapping logic back in our main execution pipeline inside main.py:

`python import os import sys import time from watcher import CodebaseHandler from generator import generate_docs from watchdog.observers import Observer

def process_file_change(file_path): # Prevent writing documentation for the documentation script itself! if os.path.basename(file_path) in ['main.py', 'watcher.py', 'generator.py']: return

docs_root = os.path.abspath('docs') project_root = os.path.abspath('.') # Get the relative path of the file from the project root relative_path = os.path.relpath(file_path, project_root) # Generate documentation content from Claude doc_content = generate_docs(file_path) if not doc_content: return # Create the mirror path in the docs folder doc_file_name = os.path.splitext(relative_path)[0] + '.md' target_path = os.path.join(docs_root, doc_file_name) # Create parent directories if they don't exist os.makedirs(os.path.dirname(target_path), exist_ok=True) with open(target_path, 'w') as f: f.write(doc_content) print(f"Successfully updated documentation at: {target_path}\n")

if __name__ == "__main__": path_to_watch = "." event_handler = CodebaseHandler(process_file_change) observer = Observer() observer.schedule(event_handler, path=path_to_watch, recursive=True) print(f"Monitoring changes in '{path_to_watch}' recursive modes... Press Ctrl+C to stop.") observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join() `

Running and Testing the Pipeline

Create a test script in your project root, say calculator.py:

`python # calculator.py def add(a: float, b: float) -> float: """Adds two numbers.""" return a + b

def divide(a: float, b: float) -> float: """Divides two numbers, raising an error if dividing by zero.""" if b == 0: raise ValueError("Cannot divide by zero.") return a / b `

Run your daemon in one terminal window:

`bash python main.py `

Now, open your calculator.py file, add a new function (like subtract), and save it. Within seconds, your file-watcher will detect the modify event, hand the updated code over to Claude, and write a beautiful, structured document into docs/calculator.md.

Troubleshooting and Production Caveats

While this local script works beautifully for personal projects, there are a couple of practical limits to keep in mind when scale increases:

  • Rate Limits: If you run massive refactoring commands (like a search-and-replace across 50 files), you will instantly hit Claude's rate limits. You can read up on rate limit management on the Anthropic Support Hub. Consider wrapping the generate_docs function in a queue with a slight delay if you plan to batch-edit files.
  • Sensitive Data: If your codebase contains hardcoded credentials (which they shouldn't!) or private algorithms, be conscious of sending that data to external APIs. Always use a proper .gitignore file and filter out files containing key secrets before sending them off to Claude.

Now you have no excuse for stale documentation. Happy coding!

pythonclaudeautomationdeveloper-tools

Keep going

Build something with the prompt generator, decode the jargon in the glossary, or compare the tools on our platform deep-dives.