Blocks (or warns on) commits where source files changed but the corresponding documentation was not updated. Optionally runs a shell script or invokes claude to fix the gap automatically.
1. Install Husky and autodoc-hooks:
npm install -D husky autodoc-hooks2. Initialise Husky (creates .husky/ and wires up the prepare script):
npx husky init3. Add autodoc-hooks to the pre-commit hook:
echo "npx autodoc-hooks" >> .husky/pre-commit4. For scope: push rules, also add a pre-push hook:
echo "npx autodoc-hooks" > .husky/pre-push
chmod +x .husky/pre-push5. Commit the Husky config:
git add .husky package.json
git commit -m "chore: add autodoc-hooks pre-commit hook"After this, npx autodoc-hooks runs automatically on every git commit (and git push if you added the pre-push hook). Other developers get the hooks automatically when they run npm install.
# .pre-commit-config.yaml
repos:
- repo: https://github.com/mediasuitenz/autodoc-hooks
rev: v0.3.0
hooks:
- id: autodoc-hookspre-commit install
pre-commit install --hook-type pre-push # if you use scope: push rulesNote: pre-commit's
language: nodeinstalls the hook's dependencies but not the package binary itself, so the hook invokesnode dist/cli.jsdirectly. Thedist/folder is committed to this repo for that reason.
Create .doc-guard.yml in your project root.
version: 1
rules:
- name: Database schema
watch:
- supabase/migrations/**
require_change_in:
- docs/architecture/data-model.mdversion: 1
defaults:
on_failure: block # block | warn (default: block)
scope: staged # staged | push (default: staged)
rules:
- name: Database schema
watch:
- supabase/migrations/**
- supabase/schema.sql
require_change_in:
- docs/architecture/data-model.md
on_failure: block # overrides defaults.on_failure for this rule
scope: staged # overrides defaults.scope for this rule
on_resolve:
type: script # script | claude
run: ./scripts/update-docs.sh {changed_files}| Key | Values | Default | Description |
|---|---|---|---|
on_failure |
block | warn |
block |
What to do when a rule fires and docs are not updated |
scope |
staged | push |
staged |
Which changed files to inspect |
Per-rule override of defaults.on_failure.
block— exit 1, aborting the commit or pushwarn— print a warning but allow the operation to proceed (exit 0)
staged— checks files in the git staging area (git diff --cached)push— checks files in commits not yet on the remote (git diff <upstream>...HEAD)
A list of glob patterns. The rule passes if any one of them matches a staged/pushed file (OR logic).
| Pattern | Matches |
|---|---|
src/** |
Any file anywhere under src/ |
**/*.md |
Any .md file in any directory |
docs/api.md |
Exactly that file |
src/*.py |
.py files directly in src/ (not subdirs) |
When a rule fires, on_resolve runs a command to fix the docs automatically. After it completes the rule is re-checked once. If the docs are still not updated the configured on_failure mode is applied.
Runs a shell command. The script is responsible for writing and staging any doc files it changes.
on_resolve:
type: script
run: ./scripts/update-data-model.sh {changed_files}Invokes claude -p "<prompt>" (requires the Claude Code CLI to be installed and authenticated).
After claude exits, autodoc-hooks runs git add on any files matching require_change_in (controlled by stage_after).
on_resolve:
type: claude
prompt: >-
The following source files changed: {changed_files}.
Update {missing_docs} to reflect these changes.
stage_after: true # auto-stage matching doc files after claude runs (default: true)
allowed_tools: # tools claude may use without interactive approval (default: Write, Edit, Read)
- Write
- Edit
- Read
timeout_ms: 120000 # kill claude if it hasn't finished within this many ms (default: 120000)Available in both run: and prompt::
| Variable | Value |
|---|---|
{changed_files} |
Space-separated list of staged source files that matched the watch pattern |
{missing_docs} |
Space-separated list of require_change_in patterns with no staged changes |
{rule_name} |
The rule's name field |
Unknown variables (e.g. {docs} instead of {missing_docs}) are printed as a warning and left unsubstituted rather than silently passed through.
Run with --dry-run to print the fully-substituted prompt without executing anything:
npx autodoc-hooks --dry-runThis is useful for verifying that template variables resolve to the expected file lists before your first real commit.
If you press Ctrl+C while on_resolve is running, autodoc-hooks removes .git/index.lock before exiting so subsequent git commands are not blocked. The interrupted commit is simply aborted — no manual cleanup is needed.
npm install
npm run build # compile TypeScript → dist/
npm test # run Vitest suite (47 tests)The tests/integration/resolve-claude.test.ts evals require claude to be installed and authenticated. They are skipped automatically when claude is not on $PATH.