Metadata-Version: 2.4
Name: agents-md-sync
Version: 1.0.1
Summary: Centralize global AI agent instructions into one AGENTS.md file.
Author: Leynier Gutiérrez González
Author-email: Leynier Gutiérrez González <leynier41@gmail.com>
License-Expression: MIT
Requires-Dist: inquirerpy>=0.3.4
Requires-Dist: typer>=0.25.1
Requires-Python: >=3.13
Description-Content-Type: text/markdown

![agents-md-sync banner](assets/banner.jpg)

`agents-md-sync` centralizes global AI agent instructions in one canonical `AGENTS.md`
file and installs symlinks or copies to the paths expected by common agent CLIs.

## Supported agents

| Agent | Target path |
|---|---|
| Amp | `~/.config/AGENTS.md` |
| Codex CLI | `~/.codex/AGENTS.md` |
| OpenCode | `~/.config/opencode/AGENTS.md` |
| Gemini CLI | `~/.gemini/GEMINI.md` |
| GitHub Copilot CLI | `~/.copilot/copilot-instructions.md` |
| Claude Code | `~/.claude/CLAUDE.md` |

## Install

```sh
uvx agents-md-sync --help
```

For local development:

```sh
uv sync
uv run agents-md-sync --help
```

## Quickstart

Create the canonical source from a specific file:

```sh
uvx agents-md-sync init --from ./my-instructions.md --yes
```

Or let `agents-md-sync init` scan existing agent instruction files and ask which one
to use as the base:

```sh
uvx agents-md-sync init
```

Install the configured source to every enabled target:

```sh
uvx agents-md-sync install --yes
```

Use copies instead of symlinks:

```sh
uvx agents-md-sync install --mode copy --yes
```

Show current target state:

```sh
uvx agents-md-sync status
```

## Git-backed source

You can keep your canonical `AGENTS.md` in a Git repository. During `init`, pass
a repo URL directly:

```sh
uvx agents-md-sync init --repo git@github.com:user/agent-config.git --dest ~/.agent-config --yes
```

Or select one of your GitHub repositories interactively:

```sh
uvx agents-md-sync init --select-repo --yes
```

The interactive selector uses `gh repo list` and requires the GitHub CLI (`gh`)
to be installed and authenticated. If `gh` is unavailable or cannot list repos,
`agents-md-sync` falls back to asking for the repo URL manually.

When a repo is configured, `agents-md-sync init` clones it into `--dest` (default:
`~/.agent-config`) or runs `git pull --ff-only` if the destination already
exists. If the repo does not contain `AGENTS.md`, `agents-md-sync` writes the initial
source file there. The config is updated with:

```toml
[source]
path = "~/.agent-config/AGENTS.md"

[repo]
url = "git@github.com:user/agent-config.git"
dest = "~/.agent-config"
```

After editing the configured source:

```sh
uvx agents-md-sync edit
uvx agents-md-sync push -m "update team agent instructions"
```

`agents-md-sync push` commits and pushes changes to the configured repo. It only
tracks `AGENTS.md`, runs `git pull --rebase --autostash` first, and prints
`No changes to push` when there is nothing to publish. Use `--dry-run` to see
the commands without changing the repo.

`agents-md-sync sync` remains pull-only. Use it to clone or update a repository
containing `AGENTS.md`, save it in config, and reinstall targets:

```sh
uvx agents-md-sync sync --repo git@github.com:user/agent-config.git --dest ~/.agent-config --yes
```

After the first sync, this is enough:

```sh
uvx agents-md-sync sync --yes
```

Recommended Git-backed workflow:

```sh
uvx agents-md-sync init --select-repo
uvx agents-md-sync edit
uvx agents-md-sync push
uvx agents-md-sync sync --yes
```

## Configuration

By default, config is stored at `~/.config/agents-md-sync/config.toml`:

```toml
[source]
path = "~/.config/AGENTS.md"

[[targets]]
name = "my-agent"
path = "~/.my-agent/instructions.md"
enabled = true
```

Ad-hoc targets are also supported:

```sh
uvx agents-md-sync install --extra-target my-agent=~/.my-agent/instructions.md --only my-agent --yes
```

## Development

This project uses `uv`, `ruff`, `ty`, `pytest`, and `pytest-cov`.

```sh
uv sync
uv run ruff check .
uv run ruff format --check .
uv run ty check
uv run pytest
```

`uv run pytest` enforces 100% coverage for `agents_md_sync`.

No pre-commit setup is required.
