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.
Files changed (42) hide show
  1. agentmeld-0.1.0/.gitignore +11 -0
  2. agentmeld-0.1.0/CHANGELOG.md +21 -0
  3. agentmeld-0.1.0/LICENSE +21 -0
  4. agentmeld-0.1.0/PKG-INFO +304 -0
  5. agentmeld-0.1.0/README.md +273 -0
  6. agentmeld-0.1.0/pyproject.toml +63 -0
  7. agentmeld-0.1.0/src/agentmeld/__init__.py +12 -0
  8. agentmeld-0.1.0/src/agentmeld/__main__.py +4 -0
  9. agentmeld-0.1.0/src/agentmeld/adopt.py +243 -0
  10. agentmeld-0.1.0/src/agentmeld/cli.py +308 -0
  11. agentmeld-0.1.0/src/agentmeld/config.py +186 -0
  12. agentmeld-0.1.0/src/agentmeld/detect.py +46 -0
  13. agentmeld-0.1.0/src/agentmeld/doctor.py +150 -0
  14. agentmeld-0.1.0/src/agentmeld/hooks.py +138 -0
  15. agentmeld-0.1.0/src/agentmeld/init.py +228 -0
  16. agentmeld-0.1.0/src/agentmeld/linker.py +293 -0
  17. agentmeld-0.1.0/src/agentmeld/model.py +263 -0
  18. agentmeld-0.1.0/src/agentmeld/planner.py +339 -0
  19. agentmeld-0.1.0/src/agentmeld/py.typed +0 -0
  20. agentmeld-0.1.0/src/agentmeld/registry/__init__.py +63 -0
  21. agentmeld-0.1.0/src/agentmeld/registry/adapters/agents.toml +16 -0
  22. agentmeld-0.1.0/src/agentmeld/registry/adapters/claude.toml +44 -0
  23. agentmeld-0.1.0/src/agentmeld/registry/adapters/copilot.toml +54 -0
  24. agentmeld-0.1.0/src/agentmeld/registry/adapters/cursor.toml +39 -0
  25. agentmeld-0.1.0/src/agentmeld/registry/adapters/gemini.toml +26 -0
  26. agentmeld-0.1.0/src/agentmeld/registry/adapters/zed.toml +12 -0
  27. agentmeld-0.1.0/src/agentmeld/registry/schema.py +85 -0
  28. agentmeld-0.1.0/src/agentmeld/state.py +138 -0
  29. agentmeld-0.1.0/src/agentmeld/transform/__init__.py +145 -0
  30. agentmeld-0.1.0/src/agentmeld/transform/aggregate.py +63 -0
  31. agentmeld-0.1.0/src/agentmeld/transform/frontmatter.py +164 -0
  32. agentmeld-0.1.0/src/agentmeld/transform/json_merge.py +118 -0
  33. agentmeld-0.1.0/src/agentmeld/transform/mcp.py +108 -0
  34. agentmeld-0.1.0/src/agentmeld/transform/toml_cmd.py +50 -0
  35. agentmeld-0.1.0/src/agentmeld/watch.py +181 -0
  36. agentmeld-0.1.0/tests/conftest.py +47 -0
  37. agentmeld-0.1.0/tests/test_adopt.py +58 -0
  38. agentmeld-0.1.0/tests/test_end_to_end.py +419 -0
  39. agentmeld-0.1.0/tests/test_frontmatter.py +74 -0
  40. agentmeld-0.1.0/tests/test_packaging.py +46 -0
  41. agentmeld-0.1.0/tests/test_registry.py +108 -0
  42. agentmeld-0.1.0/tests/test_transformers.py +129 -0
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+ .pytest_cache/
8
+ .coverage
9
+ htmlcov/
10
+ .ruff_cache/
11
+ .DS_Store
@@ -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.
@@ -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.
@@ -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&nbsp;※ | gen | merge |
173
+ | Cursor | — | gen | link&nbsp;※ | — | gen&nbsp;※ | merge&nbsp;※ |
174
+ | Gemini CLI | link | — | — | — | gen | merge&nbsp;※ |
175
+ | Zed | — | — | — | — | — | merge&nbsp;※ |
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&nbsp;※ | gen | merge |
142
+ | Cursor | — | gen | link&nbsp;※ | — | gen&nbsp;※ | merge&nbsp;※ |
143
+ | Gemini CLI | link | — | — | — | gen | merge&nbsp;※ |
144
+ | Zed | — | — | — | — | — | merge&nbsp;※ |
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"