内容
# agent-coord
一个小巧的**零依赖**协调层,允许多个编码代理
— **Claude Code**, **Codex**, 或任何支持MCP的代理 — 在同一仓库中同时工作而不会相互冲突。
它解决了特定且现实的问题:当两个代理并行运行时(例如,每个代理都在自己的git工作树中),它们会编辑相同的文件,声称相同的任务,并且通常会相互干扰。`agent-coord`为它们提供了一个共享的**板子**来进行协调:
- 🔒 **文件锁** — 在编辑前预留仓库相对路径的通配符;其他代理可以看到它们。
- 🧩 **任务声明** — 声称计划/任务ID,以便其他代理选择其他任务。
- 📣 **状态消息** — 代理之间的轻量级广播通道。
- 🛡️ **对Claude Code的严格执行** — `PreToolUse`钩子 *阻止* 编辑另一个代理锁定的文件,并 *自动声称* Claude触摸的文件。
无需SDK,无需`npm install`,无需数据库。板子是一个单独的JSON文件
(`~/.agent-coord/board.json`),由原子、多进程安全的互斥锁保护。
---
## 工作原理
```
Claude Code ──┐ ┌── Codex
(MCP client) │ stdio MCP ┌────────────┐ │ (MCP client)
├───────────────▶│ server.mjs │◀───┤
PreToolUse │ └─────┬──────┘ │ (协作:
钩子(守卫) │ │ │ 调用工具)
阻止编辑 ─┘ ┌─────▼──────┐ │
到锁定文件 │ board.json │◀───┘
│ (共享) │
└────────────┘
```
- 每个代理都指向 **相同的板子文件**,该文件位于任何工作树的**外部** — 因此在工作树A中锁定的内容在工作树B中可见。
- 锁定的键是 **仓库相对路径** (+ 从git顶级目录派生的项目ID),因此`src/cart.ts`在仓库的每个工作树中都是相同的锁定,并且无关的仓库永远不会冲突。
- **Claude Code** 获得 **强制执行** (钩子可以拒绝编辑)。**Codex** 没有预工具钩子,因此它通过调用MCP工具 **协作** — 这就是为什么下面的代理指令对其很重要。
> 最佳搭配是 **每个代理使用单独的git工作树**。每个代理一个工作树,git本身处理文件合并;`agent-coord`阻止两个代理重复工作或在提交之前竞争同一个文件。
---
## 安装
```bash
git clone https://github.com/ThatHunky/agent-coord
cd agent-coord
node test/smoke.mjs # 可选:验证(无需依赖)
```
需要Node ≥ 18。无需构建。
### 连接Claude Code
注册MCP服务器(用户范围,身份 = `claude`):
```bash
claude mcp add agent-coord -s user \
-e AGENT_COORD_AGENT=claude \
-- node /ABSOLUTE/PATH/TO/agent-coord/src/server.mjs
```
在 `~/.claude/settings.json` 中添加强制执行钩子(参见
[`examples/claude-settings.json`](examples/claude-settings.json)):
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write|MultiEdit|NotebookEdit",
"hooks": [
{
"type": "command",
"command": "AGENT_COORD_AGENT=claude node /ABSOLUTE/PATH/TO/agent-coord/src/guard.mjs"
}
]
}
]
}
}
```
### 连接Codex
在 `~/.codex/config.toml` 中添加(参见 [`examples/codex-config.toml`](examples/codex-config.toml)):
```toml
[mcp_servers.agent_coord]
command = "node"
args = ["/ABSOLUTE/PATH/TO/agent-coord/src/server.mjs"]
env = { AGENT_COORD_AGENT = "codex" }
```
### 告诉两个代理使用它
将 [`docs/AGENTS-snippet.md`](docs/AGENTS-snippet.md) 粘贴到项目的
`CLAUDE.md` 和 `AGENTS.md` 中,以便每个代理都知道协议。
---
## MCP工具
| 工具 | 功能 |
|------|--------------|
| `coord_status` | 显示板子:活动锁、任务声明、最近的消息。 **先调用此工具。** |
| `coord_claim_paths` | 预留仓库相对路径通配符;返回跨代理冲突。 |
| `coord_release_paths` | 释放锁(`lockId`)或所有锁(`all: true`)。 |
| `coord_claim_task` | 声称任务/计划ID;如果另一个代理持有它,则失败。 |
| `coord_complete_task` | 标记声称的任务完成。 |
| `coord_post` | 广播状态消息。 |
| `coord_whoami` | 显示此代理的身份、项目和板子路径。 |
## CLI(适用于人类)
实时查看两个代理正在执行的操作:
```bash
agent-coord watch # 当前仓库的实时板子
agent-coord status [project] # 一次性
agent-coord post "消息" # 广播(先设置 AGENT_COORD_AGENT)
agent-coord locks # 所有项目的所有锁
agent-coord clear # 删除您代理的所有锁
```
(通过 `node src/cli.mjs …` 或 `npm link` 获取 `agent-coord` 二进制文件运行)
---
## 配置
所有配置均可选,通过环境变量:
| 变量 | 默认值 | 含义 |
|----------|---------|---------|
| `AGENT_COORD_AGENT` | `unknown` | 此代理的身份(`claude`、`codex`、...)。 **请设置此变量。** |
| `AGENT_COORD_DIR` | `~/.agent-coord` | 共享板子存储位置。 |
| `AGENT_COORD_PROJECT` | git顶级目录basename | 作用域锁定的项目ID。 |
| `AGENT_COORD_LOCK_TTL_MINUTES` | `120` | 默认锁定过期时间。 |
| `AGENT_COORD_AUTOCLAIM` | `1` | Claude钩子自动声称编辑的文件(`0`禁用)。 |
| `AGENT_COORD_AUTOCLAIM_MINUTES` | `20` | 自动声称锁定的TTL。 |
| `AGENT_COORD_MAX_MESSAGES` | `50` | 消息环缓冲区大小。 |
---
## 设计笔记和限制
- **失败开放**。Claude钩子从不因错误而阻止您的工作 — 任何意外的错误都允许编辑。唯一拒绝的是由 **不同代理** 持有的真正且未过期的锁定。
- **锁定过期**。它们是具有TTL的协调提示,而不是永久保留,因此崩溃的代理无法阻塞仓库。
- **Codex是协作的,而不是强制执行的**。由于没有预工具钩子,Codex仅通过调用工具来尊重板子。代理指令使其可靠。
- **单台机器**。板子是一个本地文件;这是用于共享文件系统的代理,而不是跨机器。
## 许可证
MIT — 参见 [LICENSE](LICENSE)。