agent-sync-sh 1.0.0__py3-none-any.whl
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.
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: agent-sync-sh
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Canonical configs, fanned out to all your AI coding agents from the Commons, the canonical ~/.agents directory
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Project-URL: Homepage, https://agent-sync.sh
|
|
8
|
+
Project-URL: Repository, https://github.com/agent-sync-sh/agent-sync
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: MacOS
|
|
15
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Rust
|
|
18
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
19
|
+
Classifier: Topic :: Utilities
|
|
20
|
+
|
|
21
|
+
# agent-sync
|
|
22
|
+
|
|
23
|
+
**One canonical .agents/ folder, fanned out to all your AI coding agents.**
|
|
24
|
+
|
|
25
|
+
Website and docs: <https://agent-sync.sh/>
|
|
26
|
+
|
|
27
|
+
The Commons — the canonical `~/.agents/` directory — holds the single real copy of every
|
|
28
|
+
config you share: skills, instructions, MCP servers, slash commands, agents and hooks.
|
|
29
|
+
`agent-sync sync` fans it out to every agent you actually have installed.
|
|
30
|
+
|
|
31
|
+
Configs that can be byte-identical everywhere are **symlinked**, so there is one file seen
|
|
32
|
+
from ten places and drift is impossible by construction. Configs that cannot be — MCP
|
|
33
|
+
servers and hooks, which live inside files the agent also owns, in formats no two agents
|
|
34
|
+
share — are **rendered and key-merged**, with your other keys preserved.
|
|
35
|
+
|
|
36
|
+
There is no state file. There never will be. The filesystem is the state.
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
~/.agents/
|
|
40
|
+
├── skills/<name>/ fanned out as symlinks
|
|
41
|
+
├── commands/<name>.md
|
|
42
|
+
├── agents/<name>.md
|
|
43
|
+
├── AGENTS.md symlink, import-line, or rules-dir link per agent
|
|
44
|
+
├── mcp.json rendered into each agent's native dialect
|
|
45
|
+
└── hooks/<Event>.toml merged by command string
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Install
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npm install -g agent-sync-sh # prebuilt binary, macOS, Linux and Windows, no toolchain
|
|
52
|
+
pip install agent-sync-sh # the same binary, shipped as a wheel
|
|
53
|
+
cargo install agent-sync-sh # from source, needs Rust 1.97+
|
|
54
|
+
|
|
55
|
+
npx agent-sync-sh doctor # or try it first, without installing anything
|
|
56
|
+
uvx agent-sync-sh doctor # the same, if you reach for uv rather than npm
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
On macOS and Linux there is also a Homebrew tap. It lives in this repository rather
|
|
60
|
+
than a separate `homebrew-agent-sync` one, so it is tapped by URL:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
brew tap agent-sync-sh/tap https://github.com/agent-sync-sh/agent-sync
|
|
64
|
+
brew trust agent-sync-sh/tap # Homebrew 6 refuses to load untrusted third-party taps
|
|
65
|
+
brew install agent-sync
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Use
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
agent-sync init # create the Commons and report what this machine already has
|
|
72
|
+
agent-sync adopt <path> # take a path under management; --dry-run names the mechanic
|
|
73
|
+
agent-sync sync # fan out; --dry-run prints the full plan
|
|
74
|
+
agent-sync status # what is linked, what is not, and what is not ours
|
|
75
|
+
agent-sync doctor # installed agents, Commons hygiene, Sourced entries
|
|
76
|
+
agent-sync revert <agent> # offboard one agent (refuses until you disable it)
|
|
77
|
+
agent-sync mcp list | adopt | remove | enable | disable
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`adopt` picks its mechanic from where the path lives: a real config inside an agent's
|
|
81
|
+
directory is **moved** into the Commons with a link left behind; a path inside a git repo
|
|
82
|
+
becomes a **Sourced** entry — the Commons links out to it and the repo keeps the truth;
|
|
83
|
+
anything else is **copied** in. To gate CI on drift use `status` (exit 0 clean, 2
|
|
84
|
+
actionable, 1 error) — `sync --dry-run` previews, it does not gate.
|
|
85
|
+
|
|
86
|
+
## Agents
|
|
87
|
+
|
|
88
|
+
Claude Code, Codex, opencode, pi, oh-my-pi, OpenClaw, Hermes, Gemini CLI, Cursor, Windsurf,
|
|
89
|
+
Roo and Cline. Detection is simply whether the agent's config directory exists — agent-sync
|
|
90
|
+
never creates one. Agents that read `~/.agents/skills` natively (Codex, opencode, oh-my-pi,
|
|
91
|
+
Gemini CLI, Cursor) get no skill links written, because nothing needs to be — and where an
|
|
92
|
+
agent still reads its old fan-out directory beside the Commons (Codex, Cursor), `sync`
|
|
93
|
+
prunes agent-sync's now-duplicate links from it.
|
|
94
|
+
|
|
95
|
+
## Interop
|
|
96
|
+
|
|
97
|
+
The Commons speaks the conventions that won: `skills/<name>/SKILL.md` — the layout
|
|
98
|
+
opencode and friends read natively — one `AGENTS.md`, and an `mcp.json` in the standard
|
|
99
|
+
`mcpServers` shape. `.agents` Protocol surfaces (`tasks/`, `memories/`, `models.json`,
|
|
100
|
+
`system-prompt.md`) are recognized by `doctor` and never touched.
|
|
101
|
+
|
|
102
|
+
## What it will not touch
|
|
103
|
+
|
|
104
|
+
Anything it does not own. A symlink pointing outside the Commons, a hand-written file, an
|
|
105
|
+
MCP server whose name isn't in the Commons — all Foreign, all reported by `status`, none
|
|
106
|
+
ever modified. A real directory shadowing a Commons entry is a **Variant**: deliberate,
|
|
107
|
+
preserved, and counted as actionable only when its contents are identical to the Commons
|
|
108
|
+
copy, so you can dedupe on purpose.
|
|
109
|
+
|
|
110
|
+
The Commons is exactly that — a commons, not agent-sync's alone. opencode, oh-my-pi and
|
|
111
|
+
Hermes read `~/.agents/` themselves, and other tools keep their own files there. `doctor`
|
|
112
|
+
names entries that aren't agent-sync's and leaves them be; `status` stays target-only,
|
|
113
|
+
since a neighbour's file has no fan-out to report.
|
|
114
|
+
|
|
115
|
+
## Configuration
|
|
116
|
+
|
|
117
|
+
Optional `agent-sync.toml` in `$XDG_CONFIG_HOME/agent-sync/` (default `~/.config/agent-sync/`):
|
|
118
|
+
disable targets, define custom ones, scope MCP servers per agent, per-agent Tweaks. The
|
|
119
|
+
lock — agent-sync's only machine state — lives in `$XDG_STATE_HOME/agent-sync/` (default
|
|
120
|
+
`~/.local/state/agent-sync/`). Environment: `AGENT_SYNC_HOME` relocates the Commons (doctor
|
|
121
|
+
warns — native readers won't follow), `AGENT_SYNC_TARGET_ROOT` resolves everything against
|
|
122
|
+
another root, `AGENT_SYNC_LOCK_TIMEOUT_MS` bounds the lock wait.
|
|
123
|
+
|
|
124
|
+
## What it does not do
|
|
125
|
+
|
|
126
|
+
No cross-machine sync — version the Commons with git or chezmoi. No undo — refusals come
|
|
127
|
+
before writes, `sync` plans everything before writing anything, `sync` and `adopt` preview
|
|
128
|
+
with `--dry-run`, re-runs are idempotent, and a git-versioned Commons is better history
|
|
129
|
+
than any journal. **No memory sync**: agent memory is not a defined artifact and agent-sync will
|
|
130
|
+
not pretend otherwise. No GUI, daemon or file watcher. It does not install skills; it fans
|
|
131
|
+
out whatever is in the Commons, whoever put it there.
|
|
132
|
+
|
|
133
|
+
On Windows, creating symlinks requires Developer Mode (Settings → System → For
|
|
134
|
+
developers) or an elevated shell; `sync` says exactly that when it cannot link.
|
|
135
|
+
|
|
136
|
+
## Name and inspiration
|
|
137
|
+
|
|
138
|
+
The name is a nod to [GNU Stow](https://www.gnu.org/software/stow/), the classic symlink-farm
|
|
139
|
+
manager — agent-sync does for agent configs what Stow does for dotfiles. The project is also
|
|
140
|
+
inspired by two neighbours in the same space:
|
|
141
|
+
[dotagents](https://github.com/iannuttall/dotagents) and
|
|
142
|
+
[agentsync](https://github.com/spxrogers/agentsync).
|
|
143
|
+
|
|
144
|
+
[Documentation](https://agent-sync.sh/docs) · [agent-sync.sh](https://agent-sync.sh) · MIT
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
agent_sync_unsupported.py,sha256=dzYHQBizTv_AcZMabCA8eD2Iwkuk7TPvrWJNRUpvML0,824
|
|
2
|
+
agent_sync_sh-1.0.0.dist-info/METADATA,sha256=fYZCCEeRua0rPVKHxHOQgdXPhsWnwBH5WjGsHW4WnIo,7009
|
|
3
|
+
agent_sync_sh-1.0.0.dist-info/WHEEL,sha256=6uNMMHETqbni0mf_lve6cdt1R0kd90bPilAVwAQsESI,97
|
|
4
|
+
agent_sync_sh-1.0.0.dist-info/entry_points.txt,sha256=dvOuQXgYWNsWhiijZ04-XFNnjULB0kHp7TEpPatfQls,59
|
|
5
|
+
agent_sync_sh-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Stand-in for platforms with no prebuilt agent-sync binary.
|
|
2
|
+
|
|
3
|
+
Ships only in the py3-none-any wheel. pip prefers a platform wheel whenever
|
|
4
|
+
one matches, so this is reached only where none does.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import platform
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
SUPPORTED = (
|
|
11
|
+
"macOS arm64 and x86_64, Linux aarch64 and x86_64 (manylinux 2.17+), "
|
|
12
|
+
"and Windows x64 and arm64"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def main():
|
|
17
|
+
sys.stderr.write(
|
|
18
|
+
f"agent-sync: no prebuilt binary for {sys.platform}-{platform.machine()}.\n"
|
|
19
|
+
"This is the fallback wheel — pip installs it only when no platform "
|
|
20
|
+
"wheel matches your machine.\n"
|
|
21
|
+
f"Prebuilt wheels exist for {SUPPORTED}.\n"
|
|
22
|
+
"To build from source instead: cargo install agent-sync-sh\n"
|
|
23
|
+
"Details: https://agent-sync.sh\n"
|
|
24
|
+
)
|
|
25
|
+
return 1
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
sys.exit(main())
|