Skip to content

Commit c3595d2

Browse files
committed
feat: add structured task protocol, agent archiving, and capability metadata
- Align all AI-facing instructions on one-shot receive; --wait is debug-only - Leave archives agents instead of deleting unread work; rejoin reactivates - Add tasks table with create/ack/complete/requeue/list lifecycle - Add send --task-id/--reply-to for structured task follow-ups - Add receive --json for structured envelope output - Add join --client/--protocol-version capability metadata - Add agents --json with raw/effective capability fields - Add squad doctor for compatibility diagnostics - Extend receive --wait default timeout and add re-enter prompt
1 parent 69b6aae commit c3595d2

18 files changed

Lines changed: 3521 additions & 242 deletions

README.md

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,17 @@ Multiple agents with the same role get unique IDs automatically (`worker`, `work
9999

100100
| Command | Description |
101101
|---------|-------------|
102-
| `squad init` | Initialize workspace, create `.squad/`, add `.squad/` to `.gitignore`, and append squad guidance to `CLAUDE.md`, `AGENTS.md`, and `GEMINI.md` if missing |
103-
| `squad join <id> [--role <role>]` | Join as agent (auto-suffixes if ID is taken) |
104-
| `squad leave <id>` | Remove agent |
105-
| `squad agents` | List online agents |
106-
| `squad send <from> <to> <message>` | Send message (`@all` to broadcast, or `squad send --file <path-or-> <from> <to>` to read from file/stdin) |
107-
| `squad receive <id> [--wait]` | Check inbox (`--wait` is for manual/debug use) |
102+
| `squad init [--refresh-roles]` | Initialize workspace, create `.squad/`, add `.squad/` to `.gitignore`, and append squad guidance to `CLAUDE.md`, `AGENTS.md`, and `GEMINI.md` if missing. `--refresh-roles` rewrites only builtin `manager`/`worker`/`inspector` files under `.squad/roles/`. |
103+
| `squad join <id> [--role <role>] [--client <claude\|gemini\|codex\|opencode>] [--protocol-version <n>]` | Join as agent (auto-suffixes if ID is taken; omitted capability metadata stays `NULL`) |
104+
| `squad leave <id>` | Archive agent and preserve unread work |
105+
| `squad agents [--all] [--json]` | List online agents (`--json` emits one JSON object per line including raw/effective capability fields and protocol-derived support booleans) |
106+
| `squad send [--task-id <id>] [--reply-to <message-id>] <from> <to> <message>` | Send a note (`@all` to broadcast, or `squad send [flags] --file <path-or-> <from> <to>` to read from file/stdin) |
107+
| `squad receive <id> [--wait] [--timeout N] [--json]` | Check inbox (`--wait --timeout N` is for manual/debug use; `--json` emits one JSON object per line) |
108+
| `squad task create <from> <to> --title <title> [--body <body>]` | Create a structured task assignment |
109+
| `squad task ack <agent> <task-id>` | Claim a queued task |
110+
| `squad task complete <agent> <task-id> --summary <text>` | Mark an acked task complete with a summary |
111+
| `squad task requeue <task-id> [--to <agent>]` | Put a task back into the queue, optionally to a new assignee |
112+
| `squad task list [--agent <id>] [--status <status>]` | List tasks with optional filters |
108113
| `squad pending` | Show all unread messages |
109114
| `squad history [agent] [--from <id>] [--to <id>] [--since <RFC3339\|unix-seconds>]` | Show timestamped message history with optional filters |
110115
| `squad roles` | List available roles |
@@ -133,9 +138,9 @@ Supported platforms:
133138
| Codex CLI | `codex` | `~/.codex/prompts/squad.md` |
134139
| OpenCode | `opencode` | `~/.config/opencode/commands/squad.md` |
135140

136-
Once installed, use `/squad <role>` in any project where `squad init` has been run.
141+
Once installed, use `/squad <role>` in any project where `squad init` has been run. Generated slash templates automatically join with their platform client type and the current supported protocol version.
137142

138-
`squad init` does more than create `.squad/`: it also appends `.squad/` to `.gitignore` and adds a short squad collaboration section to `CLAUDE.md`, `AGENTS.md`, and `GEMINI.md` when those files do not already contain one.
143+
`squad init` does more than create `.squad/`: it also appends `.squad/` to `.gitignore` and adds a short squad collaboration section to `CLAUDE.md`, `AGENTS.md`, and `GEMINI.md` when those files do not already contain one. Existing builtin role files stay untouched unless you run `squad init --refresh-roles`.
139144

140145
## How It Works
141146

@@ -147,47 +152,69 @@ Terminal 1 (manager) Terminal 2 (worker) Terminal 3 (worker-2)
147152
│ /squad manager │ │ /squad worker │ │ /squad worker │
148153
│ │ │ (auto-ID: worker) │ │ (auto-ID: worker-2) │
149154
│ │ │ │ │ │
150-
│ squad send manager │─────>│ squad receive worker │ │ │
151-
│ worker "task A" │ │ │ │ │
155+
│ squad task create │─────>│ squad receive worker │ │ │
156+
│ manager worker │ │ │ │ │
157+
│ "task-a" "details" │ │ │ │ │
152158
│ │ │ │ │ │
153-
│ squad send manager │──────────────────────────────────>│ squad receive │
154-
│ worker-2 "task B" │ │ │ │ worker-2 │
159+
│ squad task create │──────────────────────────────────>│ squad receive │
160+
│ manager worker-2 │ │ │ │ worker-2 │
161+
│ "task-b" "details" │ │ │ │ │
155162
│ │ │ │ │ │
156-
│ squad receive manager│<─────│ squad send worker │ │ │
157-
│ │ │ manager "done A" │ │ │
163+
│ squad receive manager│<─────│ squad task complete │ │ │
164+
│ │ │ worker <task-id> │ │ │
165+
│ │ │ "done A" │ │ │
158166
│ │ │ │ │ │
159-
│ │<──────────────────────────────────│ squad send worker-2 │
160-
│ │ │ │ │ manager "done B" │
167+
│ │<──────────────────────────────────│ squad task complete │
168+
│ │ │ │ │ worker-2 <task-id> │
169+
│ │ │ │ │ "done B" │
161170
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘
162171
```
163172

164173
All messages flow through SQLite — no daemon, no sockets, no background processes.
165174

166175
### Message Flow
167176

168-
Agents should use one-shot `squad receive` checks inside their work loop:
177+
Agents should prefer `squad task ...` when assignment state matters, and keep `squad send` / `squad receive` as the fallback path for freeform coordination until capability checks land. They should still use one-shot `squad receive` checks inside their work loop:
169178

170179
```
171180
Agent joins
172181
→ squad receive <id> ← checks once and returns
173182
→ receives task from manager
183+
→ squad task ack <id> <task-id>
174184
→ executes the task
175-
→ squad send <id> manager "done: summary..."
185+
→ squad task complete <id> <task-id> --summary "done: summary..."
176186
→ squad receive <id> ← checks again when ready
177187
```
178188

189+
`squad receive <id> --wait --timeout <secs>` remains available for manual/debug use, but the default guidance is one-shot receive.
190+
179191
### ID Auto-Suffix
180192

181193
When multiple agents join with the same ID, squad automatically assigns unique IDs:
182194

183195
```bash
184-
squad join worker # → Joined as worker
185-
squad join worker # → ID 'worker' was taken. Joined as worker-2
186-
squad join worker # → ID 'worker' was taken. Joined as worker-3
196+
squad join worker --role worker --client codex --protocol-version 2
197+
# → Joined as worker
198+
199+
squad join worker --role worker --client opencode --protocol-version 2
200+
# → ID 'worker' was taken. Joined as worker-2
187201
```
188202

189203
This is handled server-side (atomic `INSERT OR IGNORE`), so even simultaneous joins from different terminals are safe.
190204

205+
## Agent Capability Metadata
206+
207+
`squad join` can optionally record agent capability metadata:
208+
209+
```bash
210+
squad join worker --role worker --client codex --protocol-version 2
211+
```
212+
213+
- If `--client` or `--protocol-version` is omitted, the database stores `NULL`.
214+
- `squad agents` shows client/protocol details in human-readable output using the effective fallback view, so legacy rows appear as `client: unknown, protocol: 1`.
215+
- `squad agents --json` exposes `client_type_raw`, `protocol_version_raw`, `effective_client_type`, `effective_protocol_version`, `supports_task_commands`, and `supports_json_receive`.
216+
- In the current phase, `supports_task_commands` and `supports_json_receive` are both derived from the effective protocol version, with support enabled at protocol `>= 2`.
217+
191218
## Role Templates
192219

193220
Roles are `.md` files in `.squad/roles/` that define agent behavior. Three are built in:
@@ -203,6 +230,8 @@ echo "You are a database specialist..." > .squad/roles/dba.md
203230
squad join db-expert --role dba
204231
```
205232

233+
If the builtin role templates in `.squad/roles/` drift from the bundled defaults, run `squad init --refresh-roles` to refresh only `manager.md`, `worker.md`, and `inspector.md`. Custom role files are left untouched.
234+
206235
## Team Templates
207236

208237
Teams are YAML files in `.squad/teams/` that define which roles are needed:
@@ -230,6 +259,11 @@ squad team dev
230259
Send a message to all agents at once:
231260

232261
```bash
262+
squad task create manager worker --title "auth-module" --body "implement auth module with JWT"
263+
squad task ack worker <task-id>
264+
squad task complete worker <task-id> --summary "JWT auth shipped"
265+
squad send --task-id <task-id> inspector worker "please handle follow-up edge cases"
266+
squad receive worker --json
233267
squad send manager @all "API contract changed, update your implementations"
234268
```
235269

README.zh-CN.md

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,17 @@ squad init
101101

102102
| 命令 | 说明 |
103103
|------|------|
104-
| `squad init` | 初始化工作区,创建 `.squad/`,将 `.squad/` 加入 `.gitignore`,并在缺失时向 `CLAUDE.md``AGENTS.md``GEMINI.md` 追加 squad 说明 |
105-
| `squad join <id> [--role <role>]` | 以 Agent 身份加入(ID 冲突时自动添加后缀) |
106-
| `squad leave <id>` | 移除 Agent |
107-
| `squad agents` | 列出在线 Agent |
108-
| `squad send <from> <to> <message>` | 发送消息(`@all` 广播给所有人,或用 `squad send --file <path-or-> <from> <to>` 从文件/标准输入读取内容) |
109-
| `squad receive <id> [--wait]` | 检查收件箱(`--wait` 仅建议手动调试时使用) |
104+
| `squad init [--refresh-roles]` | 初始化工作区,创建 `.squad/`,将 `.squad/` 加入 `.gitignore`,并在缺失时向 `CLAUDE.md``AGENTS.md``GEMINI.md` 追加 squad 说明。`--refresh-roles` 只会重写 `.squad/roles/` 下内置的 `manager`/`worker`/`inspector` 文件。 |
105+
| `squad join <id> [--role <role>] [--client <claude\|gemini\|codex\|opencode>] [--protocol-version <n>]` | 以 Agent 身份加入(ID 冲突时自动添加后缀;省略能力元数据时数据库存 `NULL`|
106+
| `squad leave <id>` | 归档 Agent,并保留未读工作 |
107+
| `squad agents [--all] [--json]` | 列出在线 Agent(`--json` 每行输出一个 JSON 对象,包含原始/生效能力字段和基于协议版本推导的支持布尔值) |
108+
| `squad send [--task-id <id>] [--reply-to <message-id>] <from> <to> <message>` | 发送普通消息(`@all` 广播给所有人,或用 `squad send [flags] --file <path-or-> <from> <to>` 从文件/标准输入读取内容) |
109+
| `squad receive <id> [--wait] [--timeout N] [--json]` | 检查收件箱(`--wait --timeout N` 仅建议手动调试时使用;`--json` 每行输出一个 JSON 对象) |
110+
| `squad task create <from> <to> --title <title> [--body <body>]` | 创建结构化任务分配 |
111+
| `squad task ack <agent> <task-id>` | 领取排队中的任务 |
112+
| `squad task complete <agent> <task-id> --summary <text>` | 用结果摘要完成已 ack 的任务 |
113+
| `squad task requeue <task-id> [--to <agent>]` | 将任务重新排队,并可选地改派给新执行者 |
114+
| `squad task list [--agent <id>] [--status <status>]` | 按可选过滤条件查看任务 |
110115
| `squad pending` | 查看所有未读消息 |
111116
| `squad history [agent] [--from <id>] [--to <id>] [--since <RFC3339\|unix-seconds>]` | 查看带时间戳的消息历史,并支持基础过滤 |
112117
| `squad roles` | 列出可用角色 |
@@ -131,9 +136,9 @@ squad setup --list # 查看支持的平台
131136
| Codex CLI | `codex` | `~/.codex/prompts/squad.md` |
132137
| OpenCode | `opencode` | `~/.config/opencode/commands/squad.md` |
133138

134-
安装后,在任何执行过 `squad init` 的项目中使用 `/squad <角色>` 即可。
139+
安装后,在任何执行过 `squad init` 的项目中使用 `/squad <角色>` 即可。生成的 slash 模板会自动带上所属平台的 `client` 值和当前支持的协议版本。
135140

136-
`squad init` 不只是创建 `.squad/`:它还会把 `.squad/` 追加到 `.gitignore`,并在 `CLAUDE.md``AGENTS.md``GEMINI.md` 尚未包含相关段落时,补上一段简短的 squad 协作说明。
141+
`squad init` 不只是创建 `.squad/`:它还会把 `.squad/` 追加到 `.gitignore`,并在 `CLAUDE.md``AGENTS.md``GEMINI.md` 尚未包含相关段落时,补上一段简短的 squad 协作说明。已有内置角色文件默认不会被覆盖,除非你显式运行 `squad init --refresh-roles`
137142

138143
## 工作原理
139144

@@ -145,47 +150,69 @@ Agent 通过共享的 SQLite 数据库(`.squad/messages.db`)通信。每个
145150
│ /squad manager │ │ /squad worker │ │ /squad worker │
146151
│ │ │ (自动 ID: worker) │ │ (自动 ID: worker-2) │
147152
│ │ │ │ │ │
148-
│ squad send manager │─────>│ squad receive worker │ │ │
149-
│ worker "任务 A" │ │ │ │ │
153+
│ squad task create │─────>│ squad receive worker │ │ │
154+
│ manager worker │ │ │ │ │
155+
│ "task-a" "详情" │ │ │ │ │
150156
│ │ │ │ │ │
151-
│ squad send manager │──────────────────────────────────>│ squad receive │
152-
│ worker-2 "任务 B" │ │ │ │ worker-2 │
157+
│ squad task create │──────────────────────────────────>│ squad receive │
158+
│ manager worker-2 │ │ │ │ worker-2 │
159+
│ "task-b" "详情" │ │ │ │ │
153160
│ │ │ │ │ │
154-
│ squad receive manager│<─────│ squad send worker │ │ │
155-
│ │ │ manager "完成 A" │ │ │
161+
│ squad receive manager│<─────│ squad task complete │ │ │
162+
│ │ │ worker <task-id> │ │ │
163+
│ │ │ "完成 A" │ │ │
156164
│ │ │ │ │ │
157-
│ │<──────────────────────────────────│ squad send worker-2 │
158-
│ │ │ │ │ manager "完成 B" │
165+
│ │<──────────────────────────────────│ squad task complete │
166+
│ │ │ │ │ worker-2 <task-id> │
167+
│ │ │ │ │ "完成 B" │
159168
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘
160169
```
161170

162171
所有消息通过 SQLite 传递 — 无守护进程、无 socket、无后台进程。
163172

164173
### 消息流程
165174

166-
Agent 应该在工作循环里使用 one-shot `squad receive`
175+
当任务状态需要被显式跟踪时,Agent 应优先使用 `squad task ...`;在能力检查尚未落地前,`squad send` / `squad receive` 仍然是自由协作的兜底路径。工作循环里仍建议使用 one-shot `squad receive`
167176

168177
```
169178
Agent 加入
170179
→ squad receive <id> ← 检查一次后返回
171180
→ 收到 Manager 分配的任务
181+
→ squad task ack <id> <task-id>
172182
→ 执行任务
173-
→ squad send <id> manager "完成:摘要..."
183+
→ squad task complete <id> <task-id> --summary "完成:摘要..."
174184
→ squad receive <id> ← 准备好后再检查一次
175185
```
176186

187+
`squad receive <id> --wait --timeout <secs>` 仍然保留,适合手动排查或调试;默认推荐仍然是 one-shot `receive`
188+
177189
### ID 自动后缀
178190

179191
当多个 Agent 使用相同 ID 加入时,squad 自动分配唯一 ID:
180192

181193
```bash
182-
squad join worker # → Joined as worker
183-
squad join worker # → ID 'worker' was taken. Joined as worker-2
184-
squad join worker # → ID 'worker' was taken. Joined as worker-3
194+
squad join worker --role worker --client codex --protocol-version 2
195+
# → Joined as worker
196+
197+
squad join worker --role worker --client opencode --protocol-version 2
198+
# → ID 'worker' was taken. Joined as worker-2
185199
```
186200

187201
这是服务端原子操作(`INSERT OR IGNORE`),即使多个终端同时加入也不会冲突。
188202

203+
## Agent 能力元数据
204+
205+
`squad join` 现在可以选择性记录 Agent 的能力元数据:
206+
207+
```bash
208+
squad join worker --role worker --client codex --protocol-version 2
209+
```
210+
211+
- 如果省略 `--client``--protocol-version`,数据库中对应字段会存为 `NULL`
212+
- `squad agents` 的人类可读输出会使用生效后的 fallback 视图,因此 legacy 记录也会显示为 `client: unknown, protocol: 1`
213+
- `squad agents --json` 会暴露 `client_type_raw``protocol_version_raw``effective_client_type``effective_protocol_version``supports_task_commands``supports_json_receive`
214+
- 当前阶段里,`supports_task_commands``supports_json_receive` 都只根据生效后的协议版本推导,阈值为 `>= 2`
215+
189216
## 角色模板
190217

191218
角色是 `.squad/roles/` 下的 `.md` 文件,定义 Agent 行为。内置三个角色:
@@ -201,6 +228,8 @@ echo "你是数据库专家..." > .squad/roles/dba.md
201228
squad join db-expert --role dba
202229
```
203230

231+
如果 `.squad/roles/` 里的内置角色模板和当前内置默认值发生漂移,可运行 `squad init --refresh-roles`,它只会刷新 `manager.md``worker.md``inspector.md`,不会触碰自定义角色文件。
232+
204233
## 团队模板
205234

206235
团队是 `.squad/teams/` 下的 YAML 文件,定义所需角色组合:
@@ -224,6 +253,11 @@ roles:
224253
向所有 Agent 发送消息:
225254

226255
```bash
256+
squad task create manager worker --title "auth-module" --body "实现 JWT 登录模块"
257+
squad task ack worker <task-id>
258+
squad task complete worker <task-id> --summary "JWT 登录已完成"
259+
squad send --task-id <task-id> inspector worker "请继续检查边界场景"
260+
squad receive worker --json
227261
squad send manager @all "API 接口已更新,请更新你们的实现"
228262
```
229263

0 commit comments

Comments
 (0)