claude-agent-sync 0.2.1__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 (37) hide show
  1. claude_agent_sync-0.2.1/LICENSE +21 -0
  2. claude_agent_sync-0.2.1/PKG-INFO +417 -0
  3. claude_agent_sync-0.2.1/README.md +381 -0
  4. claude_agent_sync-0.2.1/pyproject.toml +99 -0
  5. claude_agent_sync-0.2.1/setup.cfg +4 -0
  6. claude_agent_sync-0.2.1/src/agent_sync/__init__.py +13 -0
  7. claude_agent_sync-0.2.1/src/agent_sync/__main__.py +8 -0
  8. claude_agent_sync-0.2.1/src/agent_sync/cli.py +520 -0
  9. claude_agent_sync-0.2.1/src/agent_sync/console.py +454 -0
  10. claude_agent_sync-0.2.1/src/agent_sync/db.py +401 -0
  11. claude_agent_sync-0.2.1/src/agent_sync/errors.py +51 -0
  12. claude_agent_sync-0.2.1/src/agent_sync/git_utils.py +59 -0
  13. claude_agent_sync-0.2.1/src/agent_sync/hooks.py +309 -0
  14. claude_agent_sync-0.2.1/src/agent_sync/locks.py +158 -0
  15. claude_agent_sync-0.2.1/src/agent_sync/messages.py +203 -0
  16. claude_agent_sync-0.2.1/src/agent_sync/models.py +172 -0
  17. claude_agent_sync-0.2.1/src/agent_sync/paths.py +105 -0
  18. claude_agent_sync-0.2.1/src/agent_sync/render.py +280 -0
  19. claude_agent_sync-0.2.1/src/agent_sync/tasks.py +229 -0
  20. claude_agent_sync-0.2.1/src/claude_agent_sync.egg-info/PKG-INFO +417 -0
  21. claude_agent_sync-0.2.1/src/claude_agent_sync.egg-info/SOURCES.txt +35 -0
  22. claude_agent_sync-0.2.1/src/claude_agent_sync.egg-info/dependency_links.txt +1 -0
  23. claude_agent_sync-0.2.1/src/claude_agent_sync.egg-info/entry_points.txt +2 -0
  24. claude_agent_sync-0.2.1/src/claude_agent_sync.egg-info/requires.txt +8 -0
  25. claude_agent_sync-0.2.1/src/claude_agent_sync.egg-info/top_level.txt +1 -0
  26. claude_agent_sync-0.2.1/tests/test_benchmark_comparison.py +78 -0
  27. claude_agent_sync-0.2.1/tests/test_cli_status.py +56 -0
  28. claude_agent_sync-0.2.1/tests/test_console.py +178 -0
  29. claude_agent_sync-0.2.1/tests/test_db.py +79 -0
  30. claude_agent_sync-0.2.1/tests/test_hooks_post_edit.py +29 -0
  31. claude_agent_sync-0.2.1/tests/test_hooks_pre_edit.py +60 -0
  32. claude_agent_sync-0.2.1/tests/test_hooks_stop.py +76 -0
  33. claude_agent_sync-0.2.1/tests/test_hooks_user_prompt_submit.py +67 -0
  34. claude_agent_sync-0.2.1/tests/test_locks.py +85 -0
  35. claude_agent_sync-0.2.1/tests/test_messages.py +146 -0
  36. claude_agent_sync-0.2.1/tests/test_render.py +100 -0
  37. claude_agent_sync-0.2.1/tests/test_tasks.py +136 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 agent-sync 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,417 @@
1
+ Metadata-Version: 2.4
2
+ Name: claude-agent-sync
3
+ Version: 0.2.1
4
+ Summary: Coordinate multiple AI coding-agent sessions in one repo: file locks, task board, presence, and messaging over shared SQLite. Claude Code skill + hooks included.
5
+ Author: agent-sync contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/denfry/agent-sync
8
+ Project-URL: Repository, https://github.com/denfry/agent-sync
9
+ Project-URL: Documentation, https://github.com/denfry/agent-sync#readme
10
+ Project-URL: Issues, https://github.com/denfry/agent-sync/issues
11
+ Project-URL: Changelog, https://github.com/denfry/agent-sync/blob/main/CHANGELOG.md
12
+ Keywords: claude,claude-code,ai-agents,agents,multi-agent,agentic,coordination,file-locking,concurrency,cli,sqlite,hooks,cursor,codex,developer-tools
13
+ Classifier: Development Status :: 4 - Beta
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.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3 :: Only
23
+ Classifier: Topic :: Software Development :: Quality Assurance
24
+ Classifier: Topic :: Software Development :: Version Control
25
+ Classifier: Topic :: Utilities
26
+ Requires-Python: >=3.10
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Provides-Extra: tui
30
+ Requires-Dist: prompt_toolkit>=3.0; extra == "tui"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7.0; extra == "dev"
33
+ Requires-Dist: ruff>=0.8; extra == "dev"
34
+ Requires-Dist: prompt_toolkit>=3.0; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # agent-sync
38
+
39
+ [![Release](https://github.com/denfry/agent-sync/actions/workflows/release.yml/badge.svg)](https://github.com/denfry/agent-sync/actions/workflows/release.yml)
40
+ [![Latest release](https://img.shields.io/github/v/release/denfry/agent-sync?sort=semver)](https://github.com/denfry/agent-sync/releases)
41
+ [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE)
42
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](pyproject.toml)
43
+
44
+ **Coordinate multiple AI coding-agent sessions running in the same repository.**
45
+
46
+ `agent-sync` gives independent CLI coding-agent sessions — Claude Code, and any
47
+ other agent or shell — a shared, local coordination layer so they can *see each
48
+ other, claim tasks, lock files, exchange messages, log activity, and avoid edit
49
+ conflicts* — with no server and no network access. It ships as a small
50
+ stdlib-only Python CLI (`agent-sync`), a Claude Code **skill** (`/agent-sync`),
51
+ and a set of Claude Code **hooks** — and the agent-agnostic CLI works from any
52
+ tool.
53
+
54
+ > **Works with:** Claude Code (skill + hooks today) · any other CLI agent or
55
+ > shell via the `agent-sync` command · Python 3.10+ · macOS · Linux · Windows.
56
+
57
+ ## Contents
58
+
59
+ [Problem](#the-problem) · [Solution](#the-solution) · [Features](#features) ·
60
+ [Install](#install) · [Quickstart](#quickstart) · [Example](#example-three-agents) ·
61
+ [Commands](#commands) · [Hooks](#hook-setup) · [Storage](#data-storage) ·
62
+ [Safety](#safety-model) · [Limitations](#limitations) · [Roadmap](#roadmap) ·
63
+ [Comparison](#comparison) · [FAQ](#faq) · [Contributing](#contributing)
64
+
65
+ ---
66
+
67
+ ## The problem
68
+
69
+ You open three Claude Code sessions on the same project — one on the frontend,
70
+ one on the backend, one writing tests. Each is its own process with its own
71
+ context. They have **no idea the others exist**. So:
72
+
73
+ - Two sessions edit the same file and silently clobber each other.
74
+ - One renames an API while another is still coding against the old shape.
75
+ - Nobody knows who is doing what, or what was already decided.
76
+
77
+ `CLAUDE.md` is static. A human relaying messages between windows doesn't scale.
78
+ There is no shared operational state.
79
+
80
+ ## The solution
81
+
82
+ A single SQLite database inside your repo (`.claude/coordination/state.sqlite`)
83
+ acts as shared memory for every session, exposed through:
84
+
85
+ 1. **A CLI** — `agent-sync` — for agents (and humans) to read and update state.
86
+ 2. **A skill** — `/agent-sync` — that teaches Claude *when and how* to coordinate.
87
+ 3. **Hooks** — a `PreToolUse` hook that **blocks an edit to a file another active
88
+ agent has locked** (exit code 2), `UserPromptSubmit`/`Stop` hooks that **push
89
+ messages from other agents into this session's context** (so they can't be
90
+ ignored), plus `SessionStart`/`PostToolUse`/`SessionEnd` hooks for presence,
91
+ activity logging, and cleanup.
92
+
93
+ ```text
94
+ ┌────────────┐ ┌────────────┐ ┌────────────┐
95
+ │ frontend │ │ backend │ │ tests │ Claude Code sessions
96
+ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘
97
+ │ agent-sync │ agent-sync │ agent-sync (CLI + hooks)
98
+ └────────────────┼────────────────┘
99
+
100
+ .claude/coordination/state.sqlite (shared state, no server)
101
+ agents · tasks · locks · messages · decisions · activity
102
+ ```
103
+
104
+ ## Features
105
+
106
+ - 🔒 **File locks with TTL** — claim a file before editing; locks auto-expire
107
+ after 60 minutes so a crashed session never blocks others forever.
108
+ - ✅ **Task board** — create / claim / complete / block tasks; a task owned by an
109
+ active agent can't be stolen.
110
+ - 👥 **Presence** — agents register and heartbeat; stale and offline agents decay
111
+ automatically and stop holding locks.
112
+ - ✉️ **Messaging that reaches busy agents** — send to an agent, a name, a role,
113
+ or `all`. With the hooks installed, messages are **pushed into other sessions'
114
+ context**: injected on every prompt (`UserPromptSubmit`), and a message aimed
115
+ at a *specific* agent even blocks that agent's turn-end (`Stop`) until it reacts
116
+ — so a session deep in a task can't silently ignore it. Still a polled inbox
117
+ (`agent-sync inbox`) for everything else.
118
+ - 🧠 **Decisions & activity log** — record architecture decisions and an audit
119
+ trail of edits.
120
+ - 🪝 **Hooks that actually enforce** — `PreToolUse` fails *closed* on a real lock
121
+ conflict; everything else fails *open* so it never gets in your way.
122
+ - 📺 **Live operator console** — `agent-sync console` streams who's doing what,
123
+ how agents talk to each other, and lets a human steer in real time (send
124
+ messages/directives, lock files to stop edits, drive the task board).
125
+ - 🧰 **Zero runtime dependencies for the core** — the CLI and hooks are pure
126
+ Python standard library + SQLite. Only the live console needs an extra
127
+ (`pip install "claude-agent-sync[tui]"`).
128
+
129
+ ## Install
130
+
131
+ ```bash
132
+ # Once released to PyPI:
133
+ pip install claude-agent-sync
134
+ # Until then, install from source:
135
+ pip install "git+https://github.com/denfry/agent-sync"
136
+ # …or from a clone of this repo:
137
+ pip install -e .
138
+
139
+ # Optional: the live operator console (`agent-sync console`) needs the TUI extra:
140
+ pip install "claude-agent-sync[tui]" # or: pip install -e ".[tui]"
141
+ ```
142
+
143
+ Then install the skill and hooks into a repository:
144
+
145
+ ```bash
146
+ # from a clone of this project, run inside your target repo:
147
+ python /path/to/agent-sync/skills/agent-sync/scripts/install.py --write-settings
148
+ ```
149
+
150
+ Or, working straight from a checkout without installing the package:
151
+
152
+ ```bash
153
+ python scripts/install-local.py --write-settings
154
+ ```
155
+
156
+ This copies the skill into `<repo>/.claude/skills/agent-sync/`, creates
157
+ `<repo>/.claude/coordination/`, and (with `--write-settings`) merges the hooks
158
+ into `<repo>/.claude/settings.json`.
159
+
160
+ ## Quickstart
161
+
162
+ ```bash
163
+ agent-sync init # create the database (optional; auto-runs)
164
+ agent-sync register --name frontend --role "React UI"
165
+ agent-sync create-task "Update login UI" --file src/login.tsx
166
+ agent-sync claim-task "Update login UI"
167
+ agent-sync lock src/login.tsx --reason "editing login page"
168
+ agent-sync status # full view
169
+ agent-sync status --compact # terse Markdown for Claude's context
170
+ agent-sync send --to all --message "Login UI task started"
171
+ agent-sync decision "Use SQLite for coordination state"
172
+ agent-sync complete-task "Update login UI"
173
+ agent-sync unlock src/login.tsx
174
+ agent-sync gc # drop expired locks, re-status agents
175
+ ```
176
+
177
+ ## Example: three agents
178
+
179
+ In real use each agent is a separate Claude Code window. To simulate them in one
180
+ shell, set `AGENT_SYNC_ID` per command (in Claude Code, identity is derived
181
+ automatically from the session).
182
+
183
+ ```bash
184
+ # everyone registers
185
+ AGENT_SYNC_ID=frontend agent-sync register --name frontend --role "React UI"
186
+ AGENT_SYNC_ID=backend agent-sync register --name backend --role "API + DB"
187
+ AGENT_SYNC_ID=tests agent-sync register --name tests --role "pytest + e2e"
188
+
189
+ # backend claims a task and locks its files
190
+ AGENT_SYNC_ID=backend agent-sync create-task "Add /login endpoint" --file src/api/auth.py
191
+ AGENT_SYNC_ID=backend agent-sync claim-task "Add /login endpoint"
192
+ AGENT_SYNC_ID=backend agent-sync lock src/api/auth.py --reason "writing /login"
193
+
194
+ # tests tries to edit the locked file -> the PreToolUse hook blocks it (exit 2)
195
+ printf '{"tool_name":"Edit","tool_input":{"file_path":"src/api/auth.py"}}' \
196
+ | AGENT_SYNC_ID=tests agent-sync hook pre-tool-use
197
+ # [agent-sync] BLOCKED: src/api/auth.py is locked by backend ...
198
+
199
+ # backend announces the contract and finishes
200
+ AGENT_SYNC_ID=backend agent-sync send --to all --message "/login returns {token,user} in body"
201
+ AGENT_SYNC_ID=backend agent-sync complete-task "Add /login endpoint"
202
+ AGENT_SYNC_ID=backend agent-sync unlock src/api/auth.py
203
+ ```
204
+
205
+ See [`examples/workflow.md`](examples/workflow.md) for the full narrative.
206
+
207
+ ## Live console
208
+
209
+ Besides the agent sessions, a human can open a live, interactive view of the
210
+ whole coordination layer and steer it as it happens:
211
+
212
+ ```bash
213
+ pip install "claude-agent-sync[tui]" # one-time: the console needs this extra
214
+ agent-sync console
215
+ ```
216
+
217
+ ```text
218
+ agent-sync console — live coordination view. Type 'help', 'quit' to leave.
219
+ agents (2 active / 2 total):
220
+ backend [active] API + DB
221
+ tests [active] pytest + e2e
222
+ locks (1):
223
+ src/api/auth.py → backend — writing /login
224
+ ------------------------------------------------------------
225
+ 12:01:03 act backend Edit src/api/auth.py
226
+ 12:01:04 msg backend →all: /login returns {token,user}
227
+ 12:01:06 who frontend joined [active]
228
+ 12:01:09 lock backend released src/api/auth.py
229
+ operator> directive all "freeze feature work — hotfix on main"
230
+ directive -> 3 active agent(s)
231
+ operator> lock src/api/auth.py refactor incoming
232
+ locked src/api/auth.py (until 2026-06-14T13:01:00+00:00)
233
+ ```
234
+
235
+ The feed tails new activity, inter-agent messages, presence changes, and lock
236
+ events; the `operator>` prompt lets you act as a first-class participant:
237
+
238
+ | Operator command | Effect |
239
+ | --- | --- |
240
+ | `send <to> <msg>` | Message an id/name/role/`all`. A **directed** message is pushed forcefully (the `Stop` hook makes that agent react before it can end its turn). |
241
+ | `directive <to> <msg>` | Like `send`, but `directive all` fans out a *directed* copy to every active agent, so each is forced to react this turn. |
242
+ | `lock <path> [reason]` | Lock a file — the `PreToolUse` hook blocks other agents' edits to it **immediately**, on their next attempt. The one truly real-time lever. |
243
+ | `unlock <path>` | Release a lock (the operator can break anyone's). |
244
+ | `task new\|done\|block` | Drive the task board (`task block <ref> :: <reason>`). |
245
+ | `decision <text>` | Record a shared decision. |
246
+ | `status` · `msgs` | Print a snapshot / recent messages. `help` lists everything. |
247
+
248
+ The console acts as a reserved `operator` identity: it registers as active so
249
+ its locks are enforced and its messages reach agents like any other, but it is
250
+ kept out of the "active agents" count so it never looks like a code-editing peer.
251
+ When you quit, the operator goes idle and its locks stop holding the repo.
252
+ Influence reaches a *running* agent at its next turn (messages) or on its next
253
+ edit (locks); there is no mid-tool-call interrupt — see [Limitations](#limitations).
254
+
255
+ ## Commands
256
+
257
+ | Command | What it does |
258
+ | --- | --- |
259
+ | `agent-sync init` | Create the database and tables (auto-runs on any command). |
260
+ | `agent-sync register --name N [--role R]` | Register / update the current agent. |
261
+ | `agent-sync heartbeat` | Mark the current agent active now. |
262
+ | `agent-sync status [--compact]` | Show agents, tasks, locks, messages, activity. |
263
+ | `agent-sync tasks` | List all tasks. |
264
+ | `agent-sync create-task "T" [--description D] [--file P ...] [--priority N]` | Create a task. |
265
+ | `agent-sync claim-task T` | Claim a task by id or title. |
266
+ | `agent-sync claim-next` | Auto-claim the next available task (highest priority first; reclaims tasks abandoned by crashed sessions). |
267
+ | `agent-sync complete-task T` | Mark a task done. |
268
+ | `agent-sync block-task T --reason R` | Mark a task blocked. |
269
+ | `agent-sync lock FILE [--reason R] [--ttl MIN]` | Lock a file (default TTL 60 min). |
270
+ | `agent-sync unlock FILE [--force]` | Release a lock (owner only, unless `--force`). |
271
+ | `agent-sync locks [--all]` | List live locks (`--all` includes expired). |
272
+ | `agent-sync send --to R --message M` | Send to an id, name, role, or `all`. |
273
+ | `agent-sync inbox [--all]` | Show unread (or all) messages addressed to you. |
274
+ | `agent-sync read-message ID` | Show a message and mark it read. |
275
+ | `agent-sync decision "..."` | Record a shared decision. |
276
+ | `agent-sync log --type T --message M [--file P]` | Append an activity entry. |
277
+ | `agent-sync gc` | Re-status stale agents and drop expired locks. |
278
+ | `agent-sync console [--interval S] [--name N]` | Live operator console: stream activity and steer agents (needs the `tui` extra). |
279
+ | `agent-sync hook {session-start,user-prompt-submit,pre-tool-use,post-tool-use,stop,session-end}` | Hook entry points (read JSON from stdin). |
280
+
281
+ Run `agent-sync --help` or `agent-sync <command> --help` for details.
282
+
283
+ ## Hook setup
284
+
285
+ Merge the `hooks` block from [`examples/settings.json`](examples/settings.json)
286
+ into your repo's `.claude/settings.json` (or run an installer with
287
+ `--write-settings`):
288
+
289
+ | Event | Matcher | Behaviour |
290
+ | --- | --- | --- |
291
+ | `SessionStart` | (all) | Register/heartbeat the agent; inject compact status into context. |
292
+ | `UserPromptSubmit` | (all) | Push any undelivered messages (directed + broadcast) into context for this turn. |
293
+ | `PreToolUse` | `Edit\|Write\|MultiEdit` | **Block (exit 2)** if the target file is locked by another active agent. |
294
+ | `PostToolUse` | `Edit\|Write\|MultiEdit` | Log the successful edit to the activity feed. |
295
+ | `Stop` | (all) | **Block turn-end** (`decision: block`) while a message addressed to *this* agent is still undelivered, so it reacts before stopping. |
296
+ | `SessionEnd` | (all) | Mark the agent idle (locks are left to expire by default). |
297
+
298
+ If `agent-sync` isn't on `PATH`, use
299
+ [`examples/settings.skill-path.json`](examples/settings.skill-path.json), which
300
+ calls the bundled launcher: `python .claude/skills/agent-sync/scripts/agent-sync ...`.
301
+
302
+ ## Data storage
303
+
304
+ All state lives in **`.claude/coordination/state.sqlite`** inside the target
305
+ repo, created automatically on first use. Tables:
306
+
307
+ - `agents` — id, name, role, session, cwd, status, current task, timestamps.
308
+ - `tasks` + `task_files` — the task board and the files each task touches.
309
+ - `locks` — one row per locked path, with owner and `expires_at` (TTL).
310
+ - `messages` — sender, recipient (id/name/role/`all`), body, read state.
311
+ - `message_deliveries` — per-(message, agent) record of which messages have been
312
+ pushed into which agent's context (so a broadcast reaches each agent once).
313
+ - `decisions` — recorded decisions.
314
+ - `activity` — an append-only audit log of edits and events.
315
+
316
+ SQLite runs in WAL mode with a busy timeout, and every write uses a short
317
+ `BEGIN IMMEDIATE` transaction, so several Claude Code processes can hit the same
318
+ database concurrently. Add `.claude/coordination/` to your `.gitignore`
319
+ (this project's `.gitignore` already does).
320
+
321
+ ## Safety model
322
+
323
+ - **Local-only.** No network calls, no telemetry, no external service. State is a
324
+ file in your repo.
325
+ - **Fail open, except for locks.** Hooks tolerate malformed/empty input and never
326
+ crash your session — the *one* deliberate exception is `PreToolUse`, which fails
327
+ **closed** (exit 2) on a genuine lock conflict, which is exactly when you want
328
+ the edit blocked.
329
+ - **TTLs prevent deadlock.** Locks expire (60 min default) and locks held by
330
+ stale/offline agents are ignored, so a crashed session can't wedge the repo.
331
+ - **Owner-only unlock.** Releasing someone else's lock requires `--force` (the
332
+ operator console always uses force — the human is in charge).
333
+ - **Untrusted text stays data.** State injected into an agent's LLM context is
334
+ wrapped in an `<agent-sync-state trust="untrusted">` frame; the live console
335
+ additionally strips control/ANSI bytes from agent-authored values before
336
+ printing them, so a hostile name or message can't hijack your terminal.
337
+ - **No secrets.** Tasks, messages, and decisions are plaintext shared state — do
338
+ not put tokens, passwords, or keys in them. See [SECURITY.md](SECURITY.md).
339
+
340
+ ## Limitations
341
+
342
+ - Coordination is **advisory**. The `PreToolUse` hook enforces locks for
343
+ `Edit`/`Write`/`MultiEdit`, but a shell command (`sed`, `>`) can still bypass
344
+ it. Locks are a cooperation tool, not OS-level file locking.
345
+ - Identity is auto-detected per Claude Code session: it's `AGENT_SYNC_ID` if set,
346
+ else a hash of the session id (from a hook payload or the
347
+ `CLAUDE_CODE_SESSION_ID` env var Claude Code exports into every shell), else a
348
+ per-repo local id. Because hooks and the skill both key off the same session
349
+ id, they resolve to the same agent — so you never get blocked from editing a
350
+ file *you* locked. Outside Claude Code with none of those set, all sessions in
351
+ a repo share the local id and look like one agent.
352
+ - Single-repo scope. There's no cross-repo or cross-machine coordination.
353
+ - Messaging is **pushed** by the `UserPromptSubmit`/`Stop` hooks (so a message
354
+ lands in another agent's context at its next prompt or turn-end), but it is not
355
+ a real-time bus: there's no mid-tool-call interrupt, and locks/tasks/presence
356
+ are still observed by polling `status`. Without the hooks installed (e.g. a bare
357
+ CLI agent), messaging falls back to a polled `inbox`.
358
+
359
+ ## Roadmap
360
+
361
+ - [ ] An MCP server exposing the same state as tools/resources (no hooks needed).
362
+ - [ ] First-class adapters for other CLI agents (Cursor, Codex CLI, Gemini CLI).
363
+ - [ ] Richer presence (per-agent current file, progress %).
364
+ - [ ] Optional auto-release of locks on `SessionEnd`.
365
+ - [x] A live console for watching and steering agents — shipped as
366
+ [`agent-sync console`](#live-console).
367
+ - [ ] Lock leases with renewal and configurable policies.
368
+
369
+ ## Comparison
370
+
371
+ | Approach | Shared live state? | Blocks conflicting edits? | Setup | Best for |
372
+ | --- | --- | --- | --- | --- |
373
+ | **Plain `CLAUDE.md`** | No (static text) | No | Trivial | Conventions, not coordination |
374
+ | **Human relays chat** | In your head | No | None | 2 windows, low traffic |
375
+ | **Git worktrees** | No (isolated trees) | Avoids conflicts by isolation | Medium | Big independent features |
376
+ | **agent-sync** | Yes (SQLite) | Yes (PreToolUse hook) | One install | Several agents, one repo |
377
+ | **Future MCP version** | Yes | Yes (tool-mediated) | MCP config | Same, server-mediated |
378
+
379
+ `agent-sync` composes with git worktrees: use worktrees to isolate big
380
+ features and `agent-sync` to lock the shared/generated files they still touch.
381
+
382
+ ## FAQ
383
+
384
+ **Do I need a server or database engine?** No. It's a single SQLite file managed
385
+ by Python's stdlib `sqlite3`. Nothing to run.
386
+
387
+ **What if two agents start at the same time?** Writes use `BEGIN IMMEDIATE` and a
388
+ busy timeout, so they serialize. Claiming a task or lock is atomic; the loser
389
+ gets a clear conflict error.
390
+
391
+ **A session crashed and left a lock.** Locks expire after their TTL, and locks
392
+ owned by stale/offline agents are ignored immediately. Run `agent-sync gc` to
393
+ clean up now.
394
+
395
+ **Does this work with agents other than Claude Code?** Yes. The `agent-sync` CLI
396
+ works anywhere Python runs, so any CLI agent or shell can read and update the
397
+ shared state. The bundled skill and hooks are Claude Code-specific today (other
398
+ agents are on the [roadmap](#roadmap)), but the coordination database isn't tied
399
+ to any one tool.
400
+
401
+ **Will the hook block my own edits?** No — you can always edit files *you* have
402
+ locked. It only blocks edits to files locked by *other active* agents.
403
+
404
+ ## Contributing
405
+
406
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for dev setup, running tests, coding
407
+ conventions, and how to add commands and hooks. Security policy:
408
+ [SECURITY.md](SECURITY.md). Changes are tracked in [CHANGELOG.md](CHANGELOG.md).
409
+
410
+ ## Maintainer
411
+
412
+ Built and maintained by [@denfry](https://github.com/denfry). Issues and pull
413
+ requests welcome — start with [CONTRIBUTING.md](CONTRIBUTING.md).
414
+
415
+ ## License
416
+
417
+ [MIT](LICENSE).