agentmeld 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentmeld-0.1.0/.gitignore +11 -0
- agentmeld-0.1.0/CHANGELOG.md +21 -0
- agentmeld-0.1.0/LICENSE +21 -0
- agentmeld-0.1.0/PKG-INFO +304 -0
- agentmeld-0.1.0/README.md +273 -0
- agentmeld-0.1.0/pyproject.toml +63 -0
- agentmeld-0.1.0/src/agentmeld/__init__.py +12 -0
- agentmeld-0.1.0/src/agentmeld/__main__.py +4 -0
- agentmeld-0.1.0/src/agentmeld/adopt.py +243 -0
- agentmeld-0.1.0/src/agentmeld/cli.py +308 -0
- agentmeld-0.1.0/src/agentmeld/config.py +186 -0
- agentmeld-0.1.0/src/agentmeld/detect.py +46 -0
- agentmeld-0.1.0/src/agentmeld/doctor.py +150 -0
- agentmeld-0.1.0/src/agentmeld/hooks.py +138 -0
- agentmeld-0.1.0/src/agentmeld/init.py +228 -0
- agentmeld-0.1.0/src/agentmeld/linker.py +293 -0
- agentmeld-0.1.0/src/agentmeld/model.py +263 -0
- agentmeld-0.1.0/src/agentmeld/planner.py +339 -0
- agentmeld-0.1.0/src/agentmeld/py.typed +0 -0
- agentmeld-0.1.0/src/agentmeld/registry/__init__.py +63 -0
- agentmeld-0.1.0/src/agentmeld/registry/adapters/agents.toml +16 -0
- agentmeld-0.1.0/src/agentmeld/registry/adapters/claude.toml +44 -0
- agentmeld-0.1.0/src/agentmeld/registry/adapters/copilot.toml +54 -0
- agentmeld-0.1.0/src/agentmeld/registry/adapters/cursor.toml +39 -0
- agentmeld-0.1.0/src/agentmeld/registry/adapters/gemini.toml +26 -0
- agentmeld-0.1.0/src/agentmeld/registry/adapters/zed.toml +12 -0
- agentmeld-0.1.0/src/agentmeld/registry/schema.py +85 -0
- agentmeld-0.1.0/src/agentmeld/state.py +138 -0
- agentmeld-0.1.0/src/agentmeld/transform/__init__.py +145 -0
- agentmeld-0.1.0/src/agentmeld/transform/aggregate.py +63 -0
- agentmeld-0.1.0/src/agentmeld/transform/frontmatter.py +164 -0
- agentmeld-0.1.0/src/agentmeld/transform/json_merge.py +118 -0
- agentmeld-0.1.0/src/agentmeld/transform/mcp.py +108 -0
- agentmeld-0.1.0/src/agentmeld/transform/toml_cmd.py +50 -0
- agentmeld-0.1.0/src/agentmeld/watch.py +181 -0
- agentmeld-0.1.0/tests/conftest.py +47 -0
- agentmeld-0.1.0/tests/test_adopt.py +58 -0
- agentmeld-0.1.0/tests/test_end_to_end.py +419 -0
- agentmeld-0.1.0/tests/test_frontmatter.py +74 -0
- agentmeld-0.1.0/tests/test_packaging.py +46 -0
- agentmeld-0.1.0/tests/test_registry.py +108 -0
- agentmeld-0.1.0/tests/test_transformers.py +129 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Canonical `.ai/` tree for instructions, rules, skills, agents, commands and MCP.
|
|
7
|
+
- Declarative adapter registry (TOML, no Python needed to add a tool) covering
|
|
8
|
+
AGENTS.md, Claude Code, GitHub Copilot, Cursor, Gemini CLI and Zed, each path
|
|
9
|
+
marked `verified` or `unverified` against the vendor's own documentation.
|
|
10
|
+
- Four mirror strategies: `link` (symlink), `generate` (translated frontmatter
|
|
11
|
+
with a provenance header), `merge` (surgical edits to shared config such as
|
|
12
|
+
MCP), and `aggregate` (rules folded into single-document tools).
|
|
13
|
+
- Reverse adoption: a file written by any agent is pulled into the canonical tree
|
|
14
|
+
and fanned out to every other tool, with provenance recorded.
|
|
15
|
+
- Automatic triggers: `install-hooks` (Claude Code PostToolUse + git pre-commit),
|
|
16
|
+
`watch` (dependency-free polling daemon with feedback-loop guards), and
|
|
17
|
+
`sync --check` for CI, plus a bundled GitHub Action.
|
|
18
|
+
- Windows support: symlink capability is probed, with automatic fallback to real
|
|
19
|
+
copies and a `--mode {link,copy,auto}` override.
|
|
20
|
+
- `doctor`, reporting drift, conflicts, orphans, gated paths, and every
|
|
21
|
+
frontmatter key dropped in translation.
|
agentmeld-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 agentmeld contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
agentmeld-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: agentmeld
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: One AI context, every agent. Symlink-first, always-on sync of instructions, rules, skills, agents, commands and MCP config across every AI coding tool.
|
|
5
|
+
Project-URL: Homepage, https://github.com/moneytool/agentmeld
|
|
6
|
+
Project-URL: Repository, https://github.com/moneytool/agentmeld
|
|
7
|
+
Project-URL: Issues, https://github.com/moneytool/agentmeld/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/moneytool/agentmeld/blob/main/CHANGELOG.md
|
|
9
|
+
Author: moneytool
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: agents,agents-md,ai,claude,claude-md,codex,copilot,cursor,developer-tools,gemini,mcp,symlink
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# agentmeld
|
|
33
|
+
|
|
34
|
+
**One AI context, every agent.**
|
|
35
|
+
|
|
36
|
+
Your repo is used with Claude Code, Copilot, and Cursor. So you maintain
|
|
37
|
+
`CLAUDE.md`, `.github/copilot-instructions.md`, and `.cursor/rules/*.mdc` — three
|
|
38
|
+
copies of the same knowledge, drifting apart. Add a fourth tool, write it a
|
|
39
|
+
fourth time.
|
|
40
|
+
|
|
41
|
+
agentmeld keeps **one canonical copy in `.ai/`** and mirrors it into every
|
|
42
|
+
vendor location — a **real symlink** where the formats agree, a small
|
|
43
|
+
**generated file** where they genuinely differ.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
.ai/rules/testing.md ← you edit this, once
|
|
47
|
+
├─ .cursor/rules/testing.mdc generated: description / globs / alwaysApply
|
|
48
|
+
├─ .github/instructions/testing.instructions.md generated: applyTo
|
|
49
|
+
└─ CLAUDE.md folded in (Claude has no rule files)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
> **Not on PyPI yet** — the first release is pending. Until then, install straight
|
|
55
|
+
> from this repo (verified working):
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
uv tool install git+https://github.com/moneytool/agentmeld
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or try it without installing anything at all:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
uvx --from git+https://github.com/moneytool/agentmeld agentmeld detect
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Once published, it will be `uv tool install agentmeld` (or `pipx install
|
|
68
|
+
agentmeld`, or `pip install agentmeld`). `agm` is a shorter alias for the same
|
|
69
|
+
CLI.
|
|
70
|
+
|
|
71
|
+
## Quickstart
|
|
72
|
+
|
|
73
|
+
In the repo you actually work in:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
agentmeld detect
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
That only reads — it tells you which AI tools it found and what it would manage.
|
|
80
|
+
Then look before you leap:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
agentmeld init --dry-run
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`init` is the one command that moves files, so it shows you the list first. When
|
|
87
|
+
it looks right:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
agentmeld init
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This creates `.ai/`, moves your existing `CLAUDE.md` / `.cursor/rules` / etc. into
|
|
94
|
+
it, backs the originals up to `.ai/.backup/<timestamp>/`, and replaces them with
|
|
95
|
+
mirrors. It refuses to run on a dirty worktree unless you pass `--force`, so
|
|
96
|
+
commit first and the whole thing is one `git checkout` away from undone.
|
|
97
|
+
|
|
98
|
+
Finally, make it automatic:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
agentmeld install-hooks
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Commands
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
agentmeld detect # which AI tools does this repo actually use?
|
|
108
|
+
agentmeld init # create .ai/, adopt existing config, mirror it back
|
|
109
|
+
agentmeld sync # materialise every mirror
|
|
110
|
+
agentmeld sync --adopt # pull in new vendor files first, then mirror
|
|
111
|
+
agentmeld sync --check # CI: exit 1 if any mirror is stale
|
|
112
|
+
agentmeld install-hooks # auto-sync on agent writes and on commit
|
|
113
|
+
agentmeld watch # or run a daemon instead
|
|
114
|
+
agentmeld doctor # drift, conflicts, orphans, dropped keys
|
|
115
|
+
agentmeld list-adapters # the support matrix, with confidence levels
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Every command that writes accepts `--dry-run`. `--include-unverified` opts into
|
|
119
|
+
paths not confirmed against vendor docs.
|
|
120
|
+
|
|
121
|
+
## Working on agentmeld itself
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
git clone https://github.com/moneytool/agentmeld && cd agentmeld
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
uv sync
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
uv run pytest
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
uv run agentmeld --help
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The suite must also pass on the oldest supported Python:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
uv run --python 3.9 --with pytest --with pyyaml --with tomli python -m pytest -q
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Why not the existing tools?
|
|
146
|
+
|
|
147
|
+
[rulesync](https://github.com/dyoshikawa/rulesync) and
|
|
148
|
+
[ruler](https://github.com/intellectronica/ruler) are mature, excellent, and
|
|
149
|
+
support far more tools than agentmeld does. **If you want the widest tool
|
|
150
|
+
coverage, use them** — that is not false modesty, rulesync covers 40+ tools and
|
|
151
|
+
tracks vendor minutiae in real depth.
|
|
152
|
+
|
|
153
|
+
agentmeld exists for two things neither of them does:
|
|
154
|
+
|
|
155
|
+
| | rulesync / ruler | agentmeld |
|
|
156
|
+
|---|---|---|
|
|
157
|
+
| Mirrors are | generated copies | **symlinks** wherever the format allows |
|
|
158
|
+
| Editing a mirror | discarded on next generate | **writes straight to the canonical file** |
|
|
159
|
+
| Runs | manually (`npx … generate`) | **automatically** — agent hooks, watch, pre-commit |
|
|
160
|
+
| A file your agent just wrote | stays vendor-local until you import | **adopted into canonical and fanned out** |
|
|
161
|
+
| Runtime | Node | Python, no Node required |
|
|
162
|
+
| Tool coverage | 40+ | a handful, each checked against vendor docs |
|
|
163
|
+
|
|
164
|
+
That last row is deliberate. Read on.
|
|
165
|
+
|
|
166
|
+
## Support matrix
|
|
167
|
+
|
|
168
|
+
| Tool | instructions | rules | skills | agents | commands | MCP |
|
|
169
|
+
|---|---|---|---|---|---|---|
|
|
170
|
+
| AGENTS.md (open standard) | link | — | — | — | — | — |
|
|
171
|
+
| Claude Code | link | — | link | gen | gen | merge |
|
|
172
|
+
| GitHub Copilot | link | gen | — | gen ※ | gen | merge |
|
|
173
|
+
| Cursor | — | gen | link ※ | — | gen ※ | merge ※ |
|
|
174
|
+
| Gemini CLI | link | — | — | — | gen | merge ※ |
|
|
175
|
+
| Zed | — | — | — | — | — | merge ※ |
|
|
176
|
+
|
|
177
|
+
`link` = symlink · `gen` = generated file · `merge` = surgical edit of shared
|
|
178
|
+
config · `link/agg` = symlink until a rule exists, then an aggregate ·
|
|
179
|
+
**※ = unverified**
|
|
180
|
+
|
|
181
|
+
### Unverified means excluded
|
|
182
|
+
|
|
183
|
+
Every path is marked `verified` or `unverified`. **Unverified paths are skipped
|
|
184
|
+
unless you pass `--include-unverified`.** `verified` means the path and its
|
|
185
|
+
frontmatter keys are stated in the vendor's own documentation, linked from the
|
|
186
|
+
adapter file.
|
|
187
|
+
|
|
188
|
+
This is not bureaucracy. A tool that moves your files cannot act on a guess: a
|
|
189
|
+
wrong path does not fail loudly, it scatters your context into a directory the
|
|
190
|
+
tool never reads. Much of what a web search returns on this subject is
|
|
191
|
+
AI-generated filler that contradicts itself, so anything not confirmed at the
|
|
192
|
+
source is opt-in. Correcting one is a one-line pull request.
|
|
193
|
+
|
|
194
|
+
## Automatic syncing
|
|
195
|
+
|
|
196
|
+
Three triggers, in order of how much you should rely on them:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
agentmeld install-hooks # 1. a Claude Code PostToolUse hook + a git pre-commit hook
|
|
200
|
+
agentmeld watch # 2. a polling daemon, for editors without hooks
|
|
201
|
+
agentmeld sync --check # 3. in CI
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Hooks and CI are the defaults on purpose: **a daemon dies quietly and nobody
|
|
205
|
+
notices for a week**, whereas a failing CI check cannot be silently lost.
|
|
206
|
+
|
|
207
|
+
In CI, via the bundled action:
|
|
208
|
+
|
|
209
|
+
```yaml
|
|
210
|
+
- uses: moneytool/agentmeld@main
|
|
211
|
+
with:
|
|
212
|
+
args: sync --check
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
(Pin to `@v1` once the first release is tagged. Before agentmeld is on PyPI the
|
|
216
|
+
action installs itself from this repository, so it works either way.)
|
|
217
|
+
|
|
218
|
+
### Adoption, not just generation
|
|
219
|
+
|
|
220
|
+
When any agent writes a new `.claude/skills/foo/SKILL.md`, agentmeld moves it
|
|
221
|
+
into `.ai/skills/foo/`, records where it came from, and fans it out to every
|
|
222
|
+
other tool. Your context converges on one source instead of accumulating in
|
|
223
|
+
whichever tool happened to create it.
|
|
224
|
+
|
|
225
|
+
## The canonical tree
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
.ai/
|
|
229
|
+
├── agentmeld.toml # config
|
|
230
|
+
├── instructions.md # the main "how to work here" doc
|
|
231
|
+
├── rules/<slug>.md # scoped rules (frontmatter: description, globs, always)
|
|
232
|
+
├── skills/<slug>/SKILL.md
|
|
233
|
+
├── agents/<slug>.md
|
|
234
|
+
├── commands/<slug>.md
|
|
235
|
+
├── mcp.json # canonical MCP servers (mcpServers schema)
|
|
236
|
+
└── .state.json # what we manage, and its hashes
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Canonical frontmatter is a **superset vocabulary**, using the hyphenated Agent
|
|
240
|
+
Skills spelling (`allowed-tools`, `argument-hint`) so skills can stay symlinks.
|
|
241
|
+
Each adapter maps it down and drops what its vendor cannot express — and
|
|
242
|
+
`doctor` lists every key it had to drop, so nothing vanishes quietly.
|
|
243
|
+
|
|
244
|
+
## Why symlinks *and* generated files
|
|
245
|
+
|
|
246
|
+
Because a symlink is sometimes physically impossible:
|
|
247
|
+
|
|
248
|
+
- Gemini CLI commands are **TOML** with a `prompt =` key; Claude commands are
|
|
249
|
+
Markdown. Different container format, not just different field names.
|
|
250
|
+
- Copilot rules need `applyTo:`; Cursor needs `globs:` and `alwaysApply:` — and
|
|
251
|
+
Cursor **ignores plain `.md` files** inside `.cursor/rules`.
|
|
252
|
+
- MCP config is three incompatible schemas: `mcpServers` (Claude), `servers`
|
|
253
|
+
(VS Code), `context_servers` (Zed).
|
|
254
|
+
|
|
255
|
+
So there are four strategies:
|
|
256
|
+
|
|
257
|
+
- **link** — the vendor reads the canonical bytes as-is → relative symlink.
|
|
258
|
+
- **generate** — a derived file with a provenance header and a content hash, so
|
|
259
|
+
drift is detectable and your hand edits are never silently discarded (you get a
|
|
260
|
+
reported conflict instead).
|
|
261
|
+
- **merge** — the target is shared config we do not own → parse it, replace only
|
|
262
|
+
our subtree, **preserve every other key and every server you added by hand**.
|
|
263
|
+
- **aggregate** — the tool reads one document and has no rule mechanism, so rules
|
|
264
|
+
are folded in under their own headings. Stays a plain symlink while no rules
|
|
265
|
+
exist.
|
|
266
|
+
|
|
267
|
+
## Windows, macOS, Linux
|
|
268
|
+
|
|
269
|
+
| Platform | Behaviour |
|
|
270
|
+
|---|---|
|
|
271
|
+
| macOS / Linux | real symlinks |
|
|
272
|
+
| Windows + Developer Mode (or admin) | real symlinks |
|
|
273
|
+
| Windows without either | automatic fallback to real copies |
|
|
274
|
+
| Checkout with `core.symlinks=false` | copies, with a warning |
|
|
275
|
+
|
|
276
|
+
`--mode {link,copy,auto}` overrides the probe. `auto` attempts an actual symlink
|
|
277
|
+
in a temp directory and degrades gracefully — never a traceback. The test suite
|
|
278
|
+
runs on all three platforms and on Python 3.9 through 3.13.
|
|
279
|
+
|
|
280
|
+
## Mirrors are committed
|
|
281
|
+
|
|
282
|
+
By default the mirrors are checked in, so teammates and CI **without**
|
|
283
|
+
agentmeld installed still get working AI config. Set `git_policy = "ignore"`
|
|
284
|
+
in `.ai/agentmeld.toml` for the opposite tradeoff.
|
|
285
|
+
|
|
286
|
+
## Safety
|
|
287
|
+
|
|
288
|
+
- `init` is the only destructive command. It backs everything up to
|
|
289
|
+
`.ai/.backup/<timestamp>/` and refuses to run on a dirty worktree without
|
|
290
|
+
`--force`.
|
|
291
|
+
- Nothing is ever written inside the canonical tree.
|
|
292
|
+
- A file agentmeld did not create is never overwritten — it is reported as a
|
|
293
|
+
conflict and left alone.
|
|
294
|
+
- `sync` twice in a row produces byte-identical output.
|
|
295
|
+
- `--dry-run` on every command that writes.
|
|
296
|
+
|
|
297
|
+
## Status
|
|
298
|
+
|
|
299
|
+
Alpha. The engine and the verified adapters work and are tested end to end;
|
|
300
|
+
expect the matrix to keep moving, because the vendors keep moving.
|
|
301
|
+
|
|
302
|
+
## License
|
|
303
|
+
|
|
304
|
+
MIT
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# agentmeld
|
|
2
|
+
|
|
3
|
+
**One AI context, every agent.**
|
|
4
|
+
|
|
5
|
+
Your repo is used with Claude Code, Copilot, and Cursor. So you maintain
|
|
6
|
+
`CLAUDE.md`, `.github/copilot-instructions.md`, and `.cursor/rules/*.mdc` — three
|
|
7
|
+
copies of the same knowledge, drifting apart. Add a fourth tool, write it a
|
|
8
|
+
fourth time.
|
|
9
|
+
|
|
10
|
+
agentmeld keeps **one canonical copy in `.ai/`** and mirrors it into every
|
|
11
|
+
vendor location — a **real symlink** where the formats agree, a small
|
|
12
|
+
**generated file** where they genuinely differ.
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
.ai/rules/testing.md ← you edit this, once
|
|
16
|
+
├─ .cursor/rules/testing.mdc generated: description / globs / alwaysApply
|
|
17
|
+
├─ .github/instructions/testing.instructions.md generated: applyTo
|
|
18
|
+
└─ CLAUDE.md folded in (Claude has no rule files)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
> **Not on PyPI yet** — the first release is pending. Until then, install straight
|
|
24
|
+
> from this repo (verified working):
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
uv tool install git+https://github.com/moneytool/agentmeld
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or try it without installing anything at all:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
uvx --from git+https://github.com/moneytool/agentmeld agentmeld detect
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Once published, it will be `uv tool install agentmeld` (or `pipx install
|
|
37
|
+
agentmeld`, or `pip install agentmeld`). `agm` is a shorter alias for the same
|
|
38
|
+
CLI.
|
|
39
|
+
|
|
40
|
+
## Quickstart
|
|
41
|
+
|
|
42
|
+
In the repo you actually work in:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
agentmeld detect
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
That only reads — it tells you which AI tools it found and what it would manage.
|
|
49
|
+
Then look before you leap:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
agentmeld init --dry-run
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`init` is the one command that moves files, so it shows you the list first. When
|
|
56
|
+
it looks right:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
agentmeld init
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This creates `.ai/`, moves your existing `CLAUDE.md` / `.cursor/rules` / etc. into
|
|
63
|
+
it, backs the originals up to `.ai/.backup/<timestamp>/`, and replaces them with
|
|
64
|
+
mirrors. It refuses to run on a dirty worktree unless you pass `--force`, so
|
|
65
|
+
commit first and the whole thing is one `git checkout` away from undone.
|
|
66
|
+
|
|
67
|
+
Finally, make it automatic:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
agentmeld install-hooks
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Commands
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
agentmeld detect # which AI tools does this repo actually use?
|
|
77
|
+
agentmeld init # create .ai/, adopt existing config, mirror it back
|
|
78
|
+
agentmeld sync # materialise every mirror
|
|
79
|
+
agentmeld sync --adopt # pull in new vendor files first, then mirror
|
|
80
|
+
agentmeld sync --check # CI: exit 1 if any mirror is stale
|
|
81
|
+
agentmeld install-hooks # auto-sync on agent writes and on commit
|
|
82
|
+
agentmeld watch # or run a daemon instead
|
|
83
|
+
agentmeld doctor # drift, conflicts, orphans, dropped keys
|
|
84
|
+
agentmeld list-adapters # the support matrix, with confidence levels
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Every command that writes accepts `--dry-run`. `--include-unverified` opts into
|
|
88
|
+
paths not confirmed against vendor docs.
|
|
89
|
+
|
|
90
|
+
## Working on agentmeld itself
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
git clone https://github.com/moneytool/agentmeld && cd agentmeld
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
uv sync
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
uv run pytest
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
uv run agentmeld --help
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The suite must also pass on the oldest supported Python:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
uv run --python 3.9 --with pytest --with pyyaml --with tomli python -m pytest -q
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Why not the existing tools?
|
|
115
|
+
|
|
116
|
+
[rulesync](https://github.com/dyoshikawa/rulesync) and
|
|
117
|
+
[ruler](https://github.com/intellectronica/ruler) are mature, excellent, and
|
|
118
|
+
support far more tools than agentmeld does. **If you want the widest tool
|
|
119
|
+
coverage, use them** — that is not false modesty, rulesync covers 40+ tools and
|
|
120
|
+
tracks vendor minutiae in real depth.
|
|
121
|
+
|
|
122
|
+
agentmeld exists for two things neither of them does:
|
|
123
|
+
|
|
124
|
+
| | rulesync / ruler | agentmeld |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| Mirrors are | generated copies | **symlinks** wherever the format allows |
|
|
127
|
+
| Editing a mirror | discarded on next generate | **writes straight to the canonical file** |
|
|
128
|
+
| Runs | manually (`npx … generate`) | **automatically** — agent hooks, watch, pre-commit |
|
|
129
|
+
| A file your agent just wrote | stays vendor-local until you import | **adopted into canonical and fanned out** |
|
|
130
|
+
| Runtime | Node | Python, no Node required |
|
|
131
|
+
| Tool coverage | 40+ | a handful, each checked against vendor docs |
|
|
132
|
+
|
|
133
|
+
That last row is deliberate. Read on.
|
|
134
|
+
|
|
135
|
+
## Support matrix
|
|
136
|
+
|
|
137
|
+
| Tool | instructions | rules | skills | agents | commands | MCP |
|
|
138
|
+
|---|---|---|---|---|---|---|
|
|
139
|
+
| AGENTS.md (open standard) | link | — | — | — | — | — |
|
|
140
|
+
| Claude Code | link | — | link | gen | gen | merge |
|
|
141
|
+
| GitHub Copilot | link | gen | — | gen ※ | gen | merge |
|
|
142
|
+
| Cursor | — | gen | link ※ | — | gen ※ | merge ※ |
|
|
143
|
+
| Gemini CLI | link | — | — | — | gen | merge ※ |
|
|
144
|
+
| Zed | — | — | — | — | — | merge ※ |
|
|
145
|
+
|
|
146
|
+
`link` = symlink · `gen` = generated file · `merge` = surgical edit of shared
|
|
147
|
+
config · `link/agg` = symlink until a rule exists, then an aggregate ·
|
|
148
|
+
**※ = unverified**
|
|
149
|
+
|
|
150
|
+
### Unverified means excluded
|
|
151
|
+
|
|
152
|
+
Every path is marked `verified` or `unverified`. **Unverified paths are skipped
|
|
153
|
+
unless you pass `--include-unverified`.** `verified` means the path and its
|
|
154
|
+
frontmatter keys are stated in the vendor's own documentation, linked from the
|
|
155
|
+
adapter file.
|
|
156
|
+
|
|
157
|
+
This is not bureaucracy. A tool that moves your files cannot act on a guess: a
|
|
158
|
+
wrong path does not fail loudly, it scatters your context into a directory the
|
|
159
|
+
tool never reads. Much of what a web search returns on this subject is
|
|
160
|
+
AI-generated filler that contradicts itself, so anything not confirmed at the
|
|
161
|
+
source is opt-in. Correcting one is a one-line pull request.
|
|
162
|
+
|
|
163
|
+
## Automatic syncing
|
|
164
|
+
|
|
165
|
+
Three triggers, in order of how much you should rely on them:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
agentmeld install-hooks # 1. a Claude Code PostToolUse hook + a git pre-commit hook
|
|
169
|
+
agentmeld watch # 2. a polling daemon, for editors without hooks
|
|
170
|
+
agentmeld sync --check # 3. in CI
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Hooks and CI are the defaults on purpose: **a daemon dies quietly and nobody
|
|
174
|
+
notices for a week**, whereas a failing CI check cannot be silently lost.
|
|
175
|
+
|
|
176
|
+
In CI, via the bundled action:
|
|
177
|
+
|
|
178
|
+
```yaml
|
|
179
|
+
- uses: moneytool/agentmeld@main
|
|
180
|
+
with:
|
|
181
|
+
args: sync --check
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
(Pin to `@v1` once the first release is tagged. Before agentmeld is on PyPI the
|
|
185
|
+
action installs itself from this repository, so it works either way.)
|
|
186
|
+
|
|
187
|
+
### Adoption, not just generation
|
|
188
|
+
|
|
189
|
+
When any agent writes a new `.claude/skills/foo/SKILL.md`, agentmeld moves it
|
|
190
|
+
into `.ai/skills/foo/`, records where it came from, and fans it out to every
|
|
191
|
+
other tool. Your context converges on one source instead of accumulating in
|
|
192
|
+
whichever tool happened to create it.
|
|
193
|
+
|
|
194
|
+
## The canonical tree
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
.ai/
|
|
198
|
+
├── agentmeld.toml # config
|
|
199
|
+
├── instructions.md # the main "how to work here" doc
|
|
200
|
+
├── rules/<slug>.md # scoped rules (frontmatter: description, globs, always)
|
|
201
|
+
├── skills/<slug>/SKILL.md
|
|
202
|
+
├── agents/<slug>.md
|
|
203
|
+
├── commands/<slug>.md
|
|
204
|
+
├── mcp.json # canonical MCP servers (mcpServers schema)
|
|
205
|
+
└── .state.json # what we manage, and its hashes
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Canonical frontmatter is a **superset vocabulary**, using the hyphenated Agent
|
|
209
|
+
Skills spelling (`allowed-tools`, `argument-hint`) so skills can stay symlinks.
|
|
210
|
+
Each adapter maps it down and drops what its vendor cannot express — and
|
|
211
|
+
`doctor` lists every key it had to drop, so nothing vanishes quietly.
|
|
212
|
+
|
|
213
|
+
## Why symlinks *and* generated files
|
|
214
|
+
|
|
215
|
+
Because a symlink is sometimes physically impossible:
|
|
216
|
+
|
|
217
|
+
- Gemini CLI commands are **TOML** with a `prompt =` key; Claude commands are
|
|
218
|
+
Markdown. Different container format, not just different field names.
|
|
219
|
+
- Copilot rules need `applyTo:`; Cursor needs `globs:` and `alwaysApply:` — and
|
|
220
|
+
Cursor **ignores plain `.md` files** inside `.cursor/rules`.
|
|
221
|
+
- MCP config is three incompatible schemas: `mcpServers` (Claude), `servers`
|
|
222
|
+
(VS Code), `context_servers` (Zed).
|
|
223
|
+
|
|
224
|
+
So there are four strategies:
|
|
225
|
+
|
|
226
|
+
- **link** — the vendor reads the canonical bytes as-is → relative symlink.
|
|
227
|
+
- **generate** — a derived file with a provenance header and a content hash, so
|
|
228
|
+
drift is detectable and your hand edits are never silently discarded (you get a
|
|
229
|
+
reported conflict instead).
|
|
230
|
+
- **merge** — the target is shared config we do not own → parse it, replace only
|
|
231
|
+
our subtree, **preserve every other key and every server you added by hand**.
|
|
232
|
+
- **aggregate** — the tool reads one document and has no rule mechanism, so rules
|
|
233
|
+
are folded in under their own headings. Stays a plain symlink while no rules
|
|
234
|
+
exist.
|
|
235
|
+
|
|
236
|
+
## Windows, macOS, Linux
|
|
237
|
+
|
|
238
|
+
| Platform | Behaviour |
|
|
239
|
+
|---|---|
|
|
240
|
+
| macOS / Linux | real symlinks |
|
|
241
|
+
| Windows + Developer Mode (or admin) | real symlinks |
|
|
242
|
+
| Windows without either | automatic fallback to real copies |
|
|
243
|
+
| Checkout with `core.symlinks=false` | copies, with a warning |
|
|
244
|
+
|
|
245
|
+
`--mode {link,copy,auto}` overrides the probe. `auto` attempts an actual symlink
|
|
246
|
+
in a temp directory and degrades gracefully — never a traceback. The test suite
|
|
247
|
+
runs on all three platforms and on Python 3.9 through 3.13.
|
|
248
|
+
|
|
249
|
+
## Mirrors are committed
|
|
250
|
+
|
|
251
|
+
By default the mirrors are checked in, so teammates and CI **without**
|
|
252
|
+
agentmeld installed still get working AI config. Set `git_policy = "ignore"`
|
|
253
|
+
in `.ai/agentmeld.toml` for the opposite tradeoff.
|
|
254
|
+
|
|
255
|
+
## Safety
|
|
256
|
+
|
|
257
|
+
- `init` is the only destructive command. It backs everything up to
|
|
258
|
+
`.ai/.backup/<timestamp>/` and refuses to run on a dirty worktree without
|
|
259
|
+
`--force`.
|
|
260
|
+
- Nothing is ever written inside the canonical tree.
|
|
261
|
+
- A file agentmeld did not create is never overwritten — it is reported as a
|
|
262
|
+
conflict and left alone.
|
|
263
|
+
- `sync` twice in a row produces byte-identical output.
|
|
264
|
+
- `--dry-run` on every command that writes.
|
|
265
|
+
|
|
266
|
+
## Status
|
|
267
|
+
|
|
268
|
+
Alpha. The engine and the verified adapters work and are tested end to end;
|
|
269
|
+
expect the matrix to keep moving, because the vendors keep moving.
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
MIT
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "agentmeld"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "One AI context, every agent. Symlink-first, always-on sync of instructions, rules, skills, agents, commands and MCP config across every AI coding tool."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
authors = [{ name = "moneytool" }]
|
|
13
|
+
keywords = [
|
|
14
|
+
"ai", "agents", "claude", "copilot", "cursor", "gemini", "codex",
|
|
15
|
+
"agents-md", "claude-md", "mcp", "symlink", "developer-tools",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Environment :: Console",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Programming Language :: Python :: 3.14",
|
|
29
|
+
"Operating System :: OS Independent",
|
|
30
|
+
"Topic :: Software Development :: Build Tools",
|
|
31
|
+
"Typing :: Typed",
|
|
32
|
+
]
|
|
33
|
+
dependencies = [
|
|
34
|
+
"PyYAML>=6.0",
|
|
35
|
+
"tomli>=2.0; python_version<'3.11'",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://github.com/moneytool/agentmeld"
|
|
40
|
+
Repository = "https://github.com/moneytool/agentmeld"
|
|
41
|
+
Issues = "https://github.com/moneytool/agentmeld/issues"
|
|
42
|
+
Changelog = "https://github.com/moneytool/agentmeld/blob/main/CHANGELOG.md"
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
agentmeld = "agentmeld.cli:main"
|
|
46
|
+
agm = "agentmeld.cli:main"
|
|
47
|
+
|
|
48
|
+
[dependency-groups]
|
|
49
|
+
dev = ["pytest>=8.0", "pytest-cov>=5.0"]
|
|
50
|
+
|
|
51
|
+
[tool.hatch.build.targets.wheel]
|
|
52
|
+
packages = ["src/agentmeld"]
|
|
53
|
+
|
|
54
|
+
[tool.hatch.build.targets.sdist]
|
|
55
|
+
include = ["src/agentmeld", "tests", "README.md", "LICENSE", "CHANGELOG.md"]
|
|
56
|
+
|
|
57
|
+
[tool.pytest.ini_options]
|
|
58
|
+
testpaths = ["tests"]
|
|
59
|
+
addopts = "-q"
|
|
60
|
+
|
|
61
|
+
[tool.ruff]
|
|
62
|
+
line-length = 100
|
|
63
|
+
target-version = "py39"
|