Sync CLAUDE.md with AGENTS.md for AI coding agents
Project description
sync-claude-md
Keeps CLAUDE.md in sync with AGENTS.md for multi-agent development workflows.
Why
AI coding agents disagree on which instruction file to read — Claude Code wants
CLAUDE.md, most others (GitHub Copilot, Cursor, etc.) want AGENTS.md.
Maintaining both by hand is tedious and error-prone.
sync-claude-md keeps them in sync automatically: for every AGENTS.md it
finds, it ensures a sibling CLAUDE.md containing an @AGENTS.md reference
exists — creating the file, or adding the reference to an existing one while
preserving its content — and removes the reference (deleting the file if it's
now empty) once AGENTS.md is gone. Pass --gemini to do the same for
GEMINI.md (@./AGENTS.md).
Works as a pre-commit hook or standalone CLI.
Installation
via npm
npm install --save-dev sync-claude-md
npx sync-claude-md --help
via PyPI
pip install sync-claude-md
sync-claude-md --help
via GitHub Releases
Download the binary for your platform from Releases.
via Go
go install github.com/lohn/sync-claude-md/cmd/sync-claude-md@latest
Usage
CLI
sync-claude-md sync # sync staged AGENTS.md files (default), verified against the git index
sync-claude-md sync --all # scan the entire repository instead
sync-claude-md sync --stage # also stage the synced files (succeeds in one pass)
sync-claude-md check --all # dry-run: report drift without writing
sync-claude-md sync --gemini # also sync GEMINI.md (@./AGENTS.md)
Running sync-claude-md with no command prints help. With no file arguments,
only staged AGENTS.md files are processed — the intended git-hook use.
Outside a git repository, "staged" is meaningless, so the default falls back
to a full scan too.
Flags:
| Flag | Effect |
|---|---|
--all |
Scan the entire repository instead of only staged files |
--stage, -S |
git add the synced target files (inside a git repository only) |
--force, -f |
Overwrite targets with unstaged changes, or write at all outside a git repository |
--gemini |
Also sync GEMINI.md (@./AGENTS.md) in each directory |
--no-claude |
Skip CLAUDE.md (use with --gemini to sync GEMINI.md only) |
--no-ignore |
Also process target files that are git-ignored (skipped by default) |
--fail-on-change |
Exit 1 if any file was written, even after a successful sync/stage |
You can also pass specific files instead of relying on --all/staged
discovery, e.g. sync-claude-md sync path/to/AGENTS.md another/AGENTS.md.
sync enforces three safety guarantees:
- Destroy protection — refuses to overwrite a target file that has
unstaged changes, which would discard your work; exits
1without writing unless--forceis passed. - No writes outside a git repository — there's no git history to recover
from, so it refuses to write anything, even a brand-new file; exits
1unless--forceis passed. - Index sync (inside a git repository only) — the
@AGENTS.mdreference must be staged so the sync actually lands in the next commit. If it isn't (including a freshly created but untrackedCLAUDE.md), it exits1and asks you togit addthe file. Pass--stageto stage the synced files automatically and succeed in a single pass.
Note:
--stageadds the whole target file, so it does not play well with partial staging (git add -p). Omit--stageand stage manually if you rely on partially staged commits.
Exit codes: 0 when there's nothing left to do (everything up to date
and, inside a git repository, staged); 1 on a guarantee violation above, on
drift detected by check, or — with --fail-on-change — on any write at all.
Pre-commit / prek
Add to .pre-commit-config.yaml:
repos:
- repo: https://github.com/lohn/sync-claude-md
rev: v1.0.1
hooks:
- id: sync-claude-md
sync-claude-md is written in Go, and the default sync-claude-md hook uses
language: golang, so prek/pre-commit builds it from source on first run —
which requires a Go toolchain. If you'd rather not require Go on every
machine, swap in one of the other hook ids; all are defined in this repo's
.pre-commit-hooks.yaml:
| Hook id | Installs via | Requires |
|---|---|---|
sync-claude-md |
Go toolchain (build from source) | Go |
sync-claude-md-pip |
PyPI wheel | Python |
sync-claude-md-npm |
npm package | Node.js |
sync-claude-md-system |
a sync-claude-md binary already on PATH |
nothing extra |
The hook runs sync-claude-md sync and, by default, fails the commit when a
synced file is not staged so you re-stage and commit again. To stage the
synced files automatically instead, add args: ['--stage']:
repos:
- repo: https://github.com/lohn/sync-claude-md
rev: v1.0.1
hooks:
- id: sync-claude-md
args: ["--stage"]
Or use repo: local with a pre-installed binary:
repos:
- repo: local
hooks:
- id: sync-claude-md
name: Sync CLAUDE.md
entry: sync-claude-md sync
language: system
always_run: true
pass_filenames: false
Husky
See docs/husky.md for detailed setup instructions.
Quick example for .husky/pre-commit:
sync-claude-md sync --stage
How It Works
For each AGENTS.md found, a CLAUDE.md is created in the same directory
containing just:
@AGENTS.md
The @path/to/file syntax resolves relative to the CLAUDE.md file itself
(not CWD), so @AGENTS.md always points to the correct file. With --gemini,
a GEMINI.md is created the same way using Gemini's import syntax
@./AGENTS.md.
It's idempotent and safe:
- Adds the reference (at the top) only if it isn't already present anywhere in the file, and preserves all existing content
- Removes the reference automatically when
AGENTS.mdis deleted, and deletes the file if that leaves it empty - Refuses to read a target file larger than 10 MiB, capping how much it will ever load into memory at once — no effect on normal-sized files
License
MIT © lohn
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sync_claude_md-1.0.1-py3-none-win_arm64.whl.
File metadata
- Download URL: sync_claude_md-1.0.1-py3-none-win_arm64.whl
- Upload date:
- Size: 875.9 kB
- Tags: Python 3, Windows ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d579395759bd8fd656b7afe521bd5d7f9d3e6981a100b3bb9797caa4888f6fb
|
|
| MD5 |
9e29fea3463f179dce1a2546bb9556c8
|
|
| BLAKE2b-256 |
2e28ad07b82be2977c28d0860f3632d26e3e6f47ef5bbf0bd544cbf1204c2324
|
Provenance
The following attestation bundles were made for sync_claude_md-1.0.1-py3-none-win_arm64.whl:
Publisher:
release.yaml on lohn/sync-claude-md
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sync_claude_md-1.0.1-py3-none-win_arm64.whl -
Subject digest:
7d579395759bd8fd656b7afe521bd5d7f9d3e6981a100b3bb9797caa4888f6fb - Sigstore transparency entry: 1905712149
- Sigstore integration time:
-
Permalink:
lohn/sync-claude-md@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/lohn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sync_claude_md-1.0.1-py3-none-win_amd64.whl.
File metadata
- Download URL: sync_claude_md-1.0.1-py3-none-win_amd64.whl
- Upload date:
- Size: 973.9 kB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53aac35024690f3913bf3dcee248004adfbc0942d189fff1196e9bd5f88388e2
|
|
| MD5 |
8918558da03b0e53a5ab4fc90c25ec6e
|
|
| BLAKE2b-256 |
c4368422269913c67d91dd94a39b60f475e05e04ec072c0bf987a7d44b2b4f94
|
Provenance
The following attestation bundles were made for sync_claude_md-1.0.1-py3-none-win_amd64.whl:
Publisher:
release.yaml on lohn/sync-claude-md
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sync_claude_md-1.0.1-py3-none-win_amd64.whl -
Subject digest:
53aac35024690f3913bf3dcee248004adfbc0942d189fff1196e9bd5f88388e2 - Sigstore transparency entry: 1905711315
- Sigstore integration time:
-
Permalink:
lohn/sync-claude-md@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/lohn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sync_claude_md-1.0.1-py3-none-manylinux_2_17_x86_64.whl.
File metadata
- Download URL: sync_claude_md-1.0.1-py3-none-manylinux_2_17_x86_64.whl
- Upload date:
- Size: 930.7 kB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb3dde151bacf14f617392efb0d54707c7fc70c8df0f4bfb51d3ed68a0d013d4
|
|
| MD5 |
6f8297540bc0aa2e3d4fbd6c3bdcc690
|
|
| BLAKE2b-256 |
d1add4c09da45e0330b2ca6a42910f259969dae9d6d5138bdbfcf853e43ef6b4
|
Provenance
The following attestation bundles were made for sync_claude_md-1.0.1-py3-none-manylinux_2_17_x86_64.whl:
Publisher:
release.yaml on lohn/sync-claude-md
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sync_claude_md-1.0.1-py3-none-manylinux_2_17_x86_64.whl -
Subject digest:
eb3dde151bacf14f617392efb0d54707c7fc70c8df0f4bfb51d3ed68a0d013d4 - Sigstore transparency entry: 1905712610
- Sigstore integration time:
-
Permalink:
lohn/sync-claude-md@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/lohn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sync_claude_md-1.0.1-py3-none-manylinux_2_17_aarch64.whl.
File metadata
- Download URL: sync_claude_md-1.0.1-py3-none-manylinux_2_17_aarch64.whl
- Upload date:
- Size: 847.6 kB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c71b1881105b9d099255f2cb69d3f6b5cad0cce8f723db48e4246b042030e2bd
|
|
| MD5 |
3395dca8e32f1a29bbeb170ba628df3f
|
|
| BLAKE2b-256 |
a142eaa24750e67d19768a2d372813d042fcd4bb1fc3277dff00820135568685
|
Provenance
The following attestation bundles were made for sync_claude_md-1.0.1-py3-none-manylinux_2_17_aarch64.whl:
Publisher:
release.yaml on lohn/sync-claude-md
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sync_claude_md-1.0.1-py3-none-manylinux_2_17_aarch64.whl -
Subject digest:
c71b1881105b9d099255f2cb69d3f6b5cad0cce8f723db48e4246b042030e2bd - Sigstore transparency entry: 1905712383
- Sigstore integration time:
-
Permalink:
lohn/sync-claude-md@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/lohn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sync_claude_md-1.0.1-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: sync_claude_md-1.0.1-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 844.3 kB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7445626584a605dc2ddd116c16c41912e05885e058a96fd6742cf8db917c810
|
|
| MD5 |
74af28343c2be99f484bcaf7a9fe790f
|
|
| BLAKE2b-256 |
6fc1ac7a7e82e458f3b96beefd0481bd74ff4ec7a749efdfadb5bcc99d0844fa
|
Provenance
The following attestation bundles were made for sync_claude_md-1.0.1-py3-none-macosx_11_0_arm64.whl:
Publisher:
release.yaml on lohn/sync-claude-md
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sync_claude_md-1.0.1-py3-none-macosx_11_0_arm64.whl -
Subject digest:
d7445626584a605dc2ddd116c16c41912e05885e058a96fd6742cf8db917c810 - Sigstore transparency entry: 1905711658
- Sigstore integration time:
-
Permalink:
lohn/sync-claude-md@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/lohn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sync_claude_md-1.0.1-py3-none-macosx_10_9_x86_64.whl.
File metadata
- Download URL: sync_claude_md-1.0.1-py3-none-macosx_10_9_x86_64.whl
- Upload date:
- Size: 909.0 kB
- Tags: Python 3, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efbafabb230badf1d4a2164db6804adcdd1c3c2d5e740ff81beaeda64770e5ee
|
|
| MD5 |
6fd31b6a8d41514629b208ef5afccaad
|
|
| BLAKE2b-256 |
35ee683c8dec48baffbfc345d44b63814956d312e89005845f9805fc7e272f89
|
Provenance
The following attestation bundles were made for sync_claude_md-1.0.1-py3-none-macosx_10_9_x86_64.whl:
Publisher:
release.yaml on lohn/sync-claude-md
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sync_claude_md-1.0.1-py3-none-macosx_10_9_x86_64.whl -
Subject digest:
efbafabb230badf1d4a2164db6804adcdd1c3c2d5e740ff81beaeda64770e5ee - Sigstore transparency entry: 1905711921
- Sigstore integration time:
-
Permalink:
lohn/sync-claude-md@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/lohn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@7d51803edfa4540d9d49a532c192a9ffd006b8c7 -
Trigger Event:
push
-
Statement type: