Skip to content
Back to skills

Pair Crew

ASecurity

> **pair-crew**(结对班组):多个 agent 分角色结对开发——有人实现、有人写测试、有人评审。 > **任何 agent 都能当指挥**:MiMo Desktop、Claude Code、Codex、WorkBuddy、ZCode、用户自定义 agent……只要能读本目录、跑 Python3、发 prompt。

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 26, 2026
developmentpythonbashsqlapi

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Pro scans all 15 files and shows the line behind each finding

Scanned October 26, 2026

npx -y skills add tcwhvi/coding-pair-crew --skill pair-crew --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Pair Crew?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Pair Crew
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tcwhvi-pair-crew/badge)](https://www.skillsdirectory.com/skills/tcwhvi-pair-crew)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# pair-crew — 多 Agent 结对班组(agent 无关)

> **pair-crew**(结对班组):多个 agent 分角色结对开发——有人实现、有人写测试、有人评审。  
> **任何 agent 都能当指挥**:MiMo Desktop、Claude Code、Codex、WorkBuddy、ZCode、用户自定义 agent……只要能读本目录、跑 Python3、发 prompt。

## 谁能用

| 角色 | 用什么 | 说明 |
|---|---|---|
| **指挥 Conductor** | 本 `SKILL.md` | **不限产品**。Claude Code / Codex / MiMo / 自定义 CLI agent 均可 |
| **工位 Worker** | 只收派发 prompt | Qoder / Qoder CN / WorkBuddy / ZCode / 任意 agent 会话 |
| **脚本 Scripts** | `scripts/*.py` | 纯 Python3 + 标准库(CDP 处复用 `websocket-client`);与 agent 无关 |
| **契约 Contracts** | `contracts/**` | 人与 agent 共用的事实源 |

### 不同 agent 怎么挂上本 skill

| Agent | 做法 |
|---|---|
| **Claude Code** | 把 `skills/pair-crew/` 拷到 `~/.claude/skills/pair-crew/` 或项目 `.claude/skills/pair-crew/`;或在 CLAUDE.md 写「服从 pair-crew 流程」 |
| **Codex** | 放到项目内并在 AGENTS.md / 项目说明里引用本 SKILL.md |
| **MiMo** | 项目 `skills/pair-crew/` 或引擎 skill 目录 |
| **自定义 / CLI agent** | 设定「工作前先读 `SKILL.md` + `templates/`」;脚本用 `python` 调用即可 |
| **多指挥协作** | 同一仓库只保留一份契约与 BOARD;指挥可换人,**不要复制多份 contracts** |

触发:`/pair-crew`、「pair 开发 / 结对 / 多 agent 车间 / 一人实现一人测试」。

## 核心原则

1. **角色与工具解耦**:实现 / 测试 / 评审是角色;Qoder、WorkBuddy、ZCode、任意 LLM 会话是壳
2. **契约先于代码**:SPEC / API / SCOPE / examples.yaml 先冻结
3. **单写者**:一 task 一 worktree,禁止并发写同一业务区
4. **高频对齐**:用户需求确认 → 班组圆桌 → 搭档并写(例粒度)→ 评审可批
5. **能力门禁**:UI 布局目检必须多模态;`routing_check` 开工前校验
6. **【硬性】必须找用户确认,禁止 agent 自行拍板**——尤其是需求澄清:
   - Story 目标/边界、不明白的点、任务怎么拆、测试用例怎么写,**必须经用户确认后才能冻结**
   - 外部工具派发:目标工具、项目名、绝对路径、新建/续写、**完全访问**
   - 范围变更、P0 裁决、合入 main 等高风险动作
   - 用户已明确授权「按此执行」的同类动作可在授权范围内连续执行;**新开的歧义/需求问题仍要问**
7. **【硬性】派发后核对读回**含真实路径;读不到多半是工作区或权限问题

## 目录约定(与 agent 无关)

```
<repo>/
  docs/multi-agent-pair-plan.md
  skills/pair-crew/                 # 本 skill(可被任意 agent 引用)
  contracts/<task_id>/              # SPEC API SCOPE examples.yaml HANDOFF review/
  .agents/ROUTING.yaml              # 角色 → 运行时/模型/能力
  .agents/BOARD.md                  # 工单板
  worktrees/                        # impl / review / qa 隔离区
```

## 主流程

### 0.【硬门禁】Story 需求确认(未冻结不得派发)

- **不是**假设用户「已经说清楚」;凡进入 pair + 测试流水线的 Story 必须先对齐
- **【硬性】提问必须结合项目现状,禁止空中楼阁**
  - 先扫一眼仓库/目录/文档/库表/接口/截图,再出问题
  - 每条问题要能指向:**哪个文件、哪张表、哪段流程、哪份文档**(例如「Word 里 `paydatetime` 注释是分钟,库里样本像时间戳,以哪个为准?」)
  - 禁止只问「你要什么功能?目标是什么?」这类无锚点空问题
  - 材料里已写明的不要重复问;材料矛盾处问「以哪边为准」
- 一次性呈报(见 `templates/STORY_KICKOFF.md`):
  1. 我读到的项目现状(证据路径 + 一句摘要)
  2. 我理解的目标(一句话 + 做/不做)
  3. 基于项目的疑问(绑文件/表/字段/流程;可附我的倾向)
  4. 任务拆分草案(谁实现谁测试、依赖)
  5. 测试用例草案(happy / boundary / error / **ui_layout** / **ui_journey**,能落到真实数据/页面)
  6. 风险与验收
- 用户确认后写入 `contracts/<id>/SPEC.md` + `examples.yaml` → **冻结**
- 冻结后大改 = 重新确认;禁止静默扩 scope

### 1. 能力检查

```bash
python skills/pair-crew/scripts/routing_check.py --routing .agents/ROUTING.yaml
```

- ERROR(VISION_REQUIRED / IDE_OFFLINE)先处理或改路由

### 2. 班组圆桌

- 把**用户已确认**的 SPEC 落进契约
- 实现 / 测试确认 `examples.yaml`
- 班组分歧升级主持;**用户确认过的例子不得静默改写**

### 3. 隔离区

- worktree / 分支 `impl/<task_id>`

### 4. 搭档并写

- 实现者:生产码
- 测试者:单测 + 契约测 + UI 布局 / 流程测
- 例粒度同步,写 HANDOFF

### 5. 派发外部工具(每次先与用户确认)

```bash
# 【前置门禁】先按绝对路径确认目标 IDE 里确实有这个项目
python skills/pair-crew/scripts/ide_guard.py --ide zcode --path "D:\projects\xxx"
python skills/pair-crew/scripts/ide_guard.py --ide qoder --path "D:\projects\xxx"
python skills/pair-crew/scripts/ide_guard.py --ide zcode --list      # 看已绑定的目录
python skills/pair-crew/scripts/ide_guard.py --ide qoder --sessions  # 看各会话绑的目录

# Qoder CN / 国际版(指定端口)
python skills/pair-crew/scripts/send_qoder.py --port 9222 \
  --project-name <项目名> --project-path <绝对路径> --text-file prompt.md

# ZCode
python skills/pair-crew/scripts/send_zcode.py --port 9224 \
  --project-name <项目名> --project-path <绝对路径> --text-file prompt.md

# WorkBuddy / 其他(external-review 派发器)
python ~/.agents/skills/external-review/scripts/review_dispatch.py \
  --to workbuddy --project-name <项目名> --project-path <绝对路径> --text-file prompt.md
```

> **⚠ 归属门禁(真实事故)**:`send_zcode.py` / `send_qoder.py` 的旧逻辑只检查
> 「侧栏文本里含不含这个项目名」,含就发到**当前打开的会话**。
> 结果:目标目录在 ZCode 里根本不存在时,任务被静默发进当时开着的
> `coding_skill` 会话(`directory = E:\project_self\coding_skill\.mimocode`),
> 与用户要的项目毫无关系,而脚本一路打印 "SENT"。
> 现在两个脚本都内置 `ide_guard.require()`,**按绝对路径核对,不存在直接拒绝并列出可用目录**。
>
> **被拒绝时不要想办法绕过** —— 那是「需要用户亲自操作」的环节:
> 告诉用户「请在 `<IDE>` 里新建项目 / 打开文件夹,选 `<绝对路径>`」,
> 等他做完再重跑。系统原生文件夹对话框 CDP 碰不到,别硬试。

确认项:工具、项目名、路径、新建/续写、完全访问。

### 6. 读回

```bash
python ~/.agents/skills/external-review/scripts/read_review_replies.py \
  --only qoder --tail 8000 --project-path <绝对路径>
# 或直接读 Worker UI / 其输出目录
```

### 6.5 同一会话续写 / 催收尾

`send_qoder.py` / `send_zcode.py` 只做「新建任务」。要在**已跑起来的会话**里补指令
(补上下文、纠正方向、催它出结论),用 `send_followup.py`:

```bash
# 推荐写法:带 --ide,按 chat id 查数据库核对会话身份
python skills/pair-crew/scripts/send_followup.py --port 9222 --ide qoder \
  --switch-to "生产导入脚本评审" --expect "生产导入脚本评审" --text-file note.md

python skills/pair-crew/scripts/send_followup.py --port 9224 --ide zcode \
  --switch-to "评审" --expect "评审" --text-file note.md
```

> **⚠ 坑 1:会话身份不能看页面文本**
> `document.body.innerText` 包含整个侧栏,按文本匹配会把侧栏里**别的会话名**当成当前会话。
> 实测:评审指令被发进「查找TTFT插件」,因为那一页的侧栏里恰好有「评审」二字。
> `--ide` + `--expect` 现在是**按 chat id 查 IDE 数据库里的真实标题**比对;
> 查不到就拒发,并列出最近会话供选。

> **⚠ 坑 2:插话按钮不叫「立即」**
> agent 正在生成时消息只进队列,气泡上多一个按钮,必须点它才插队。
> ZCode 叫 `立即`,**Qoder CN 叫 `插话`**。只匹配「立即」的脚本在 Qoder 上
> 一个也点不到,消息永远排队,看起来像「发了没反应」。
> `send_followup.py` 覆盖 `立即 / 插话 / 立即发送 / 立即执行 / 打断 / 现在就发`,
> 并取**最靠下**(最新)那个,避免误点历史残留按钮。

> **⚠ 坑 3:侧栏项可能滚出视口**
> 实测侧栏项的 `getBoundingClientRect().y` 会是负数(-86),点击坐标落在视口外,
> 事件被丢弃但脚本不报错,表现为「切了但没切过去」。
> 现在点击前先 `scrollIntoView({block:'center'})`,并回读 `visible` 标志。

> **⚠ 读回结果的更好办法:直接读 IDE 数据库**
> CDP 只能读**当前活动视图**,用户一切走你就读到别人的会话。要拿某个会话的完整输出,
> 直接读库更可靠、也不占用用户界面:
> - Qoder:`main.sqlite` 的 `chat_session_messages`(`payload_json.parts`)
> - ZCode:`~/.zcode/cli/db/db.sqlite` 的 `message` / `part` 表

### 7. 评审收口

- P0–P3;轮次 ≤5;连续 2 轮无新 P0/P1 → QA

#### 【硬性】未收口不得收工

这是最容易犯、代价最大的错:**派发是异步的,agent 的会话是同步的**。
外部 IDE 一跑就是半小时到一小时,一波指令发出去,agent 这边一轮答完就要结束,
于是「派发了」被当成了「评审完了」,结论永远没人读,用户那边还在跑、这边已经收工。

规矩:

1. **派发后立刻登记**:在 `.agents/BOARD.md` 写一行
   `task_id | 工具 | 会话标题 | session_id | 派发时间 | 状态=in_review`
2. **收工前必须做收口检查**,三问:
   - 我这次派出去几个评审?各自的 `session_id` 是什么?
   - **每一个**都拿到明确判定(`可以开工` / `还不能开工` / 换方案)了吗?
   - 没拿到的,有没有在 HANDOFF 里写清「怎么读回」?
3. **禁止**在还有 `in_review` 未读回时,宣称任务完成或说「评审已通过」
4. 拿不到结论就**明说**:「X 还在跑,我下次用 `collect_review.py --session <id>` 读回」,
   并把命令写进回复里,不要含糊过去

#### 【硬性】续写之前先读回,禁止重复派发

同一件事发两遍,会让对方重做一遍、白烧一轮额度和时间,还污染评审记录。

**派发前必做**:

```bash
python skills/pair-crew/scripts/collect_review.py --session <session_id>
```

看「最后一条 assistant 消息」的 **时间** 和 **正文**:

- 时间**晚于**我上次派发 → 它已经处理过了,**不要再发**
- 时间早于上次派发、且结论对不上我这次要说的内容 → 才需要发

> **⚠ 判断「它回没回我」不能看消息条数。**
> 实测 Qoder 在**同一条 assistant 消息**上原地更新:条数一直是 6,
> 但内容已经从「第一轮结论」换成「第三轮复核」。只看条数会得出「没回我」,
> 然后重复派发 —— 我当时就这样把第三轮发了两遍(seq=7 成功、seq=9 多余)。


#### 读回:查 IDE 数据库,不要抓页面

```bash
# 一眼看出哪些评审还没收口(最近 12 小时有活动、含明确判定)
python skills/pair-crew/scripts/collect_review.py
python skills/pair-crew/scripts/collect_review.py --title 评审 --full
python skills/pair-crew/scripts/collect_review.py --session <session_id> --full
```

> **⚠ 判读陷阱:消息条数不变 ≠ 没有新结论。**
> 实测 Qoder 会在**同一条 assistant 消息**上原地更新内容:条数一直是 6,
> 但里面已经从「第一轮结论」换成了「第三轮复核」。
> 只看条数就会得出「它没回我」的错误结论,然后重复派发、白等。
> 正确做法是看**最后一条 assistant 消息的 `updated_at` 和正文**,
> `collect_review.py` 输出的就是这个。

> **⚠ 不要靠抓页面判断「还在不在跑」。**
> `document.body.innerText` 只反映当前活动视图,用户一切走你就看到别人的会话;
> 页面上任何「生成中」字样都可能来自别的任务。以数据库里的消息时间为准。

#### 【硬性】「盯着」= 阻塞轮询,不是跑一次

**跑一次没看到判定,不等于它没回。** 外部 agent 常常还要几分钟才写完结论。
真实踩过:19:52 查一次没有判定,19:54 人家就出了「可以开工」,
我却上报「它没回应」,被告知「明明已经执行完了」。

要等就用 `--wait`,它会轮询到出现判定词才返回:

```bash
python skills/pair-crew/scripts/collect_review.py --wait --session <session_id> \
  --timeout 1800 --interval 15
```

- 退出码 `0` = 拿到判定;`2` = 超时。**超时不等于失败** —— 它可能还在跑,
  过一会再 `--wait` 一次,不要据此断言「它没回我」
- 轮询比的是**正文内容哈希**,不是消息条数(Qoder 会原地更新同一条消息,条数不变)
- 判定词优先取正文开头 300 字(结论都在第一行,正文表格里可能引用别的轮次的词)

> **⚠ 读 IDE 数据库绝对不能加 `immutable=1`。**
> 那是「这个库保证不会变」的承诺,SQLite 会跳过 WAL,只返回打开那一刻的快照。
> IDE 的新消息全在新写入的 `-wal` 里,于是条数永远不变、结论永远读不到。
> 用 `mode=ro` + `PRAGMA query_only=1`:正常读 WAL,且仍然只读。



### 8. QA

- 例子表 + Layout 清单 + 主/异常 Journey

### 9. 集成

- SCOPE 门禁后合入

## 测试分层(UI 一等公民)

| 类 | 谁写/谁跑 | 要点 |
|---|---|---|
| 单测 | 测试者 / 自测 | 逻辑边界 |
| 契约/验收 | 测试者 / QA | examples.yaml 逐条 |
| 集成/接口 | QA | API 不破 |
| **UI 布局** | **多模态模型** | 截图目检:溢出/遮挡/断点/空错载入态 |
| **UI 流程** | 测试者(可文本模型) | Playwright 真点主路径 + 异常路径 |
| SCOPE | 脚本 + 评审 | 不越界 |
| 评审门禁 | 评审 | 无未处理 P0/P1 |

## 模型 / 运行时

- 见 `.agents/ROUTING.yaml` 与 `docs/multi-agent-pair-plan.md` §6
- **模型、思考档、上下文注入**由「指挥 agent 自己的机制」决定;本 skill 只规定:
  - 能力声明(`requires: [vision, image_read]` 等)
  - 上下文风格(`context_style: files`:契约路径 + 例子表,不灌全历史)
  - 开工前 `routing_check` 能过

## 状态机

`draft → ready_for_impl → in_impl → ready_for_review → in_review ⇄ ready_for_impl → ready_for_qa → in_qa → done`,`blocked` 可回。

## 人工介入

### 【硬性】需要用户亲自操作的环节

下面这些**agent 做不了**,必须明确要求用户动手,**禁止**假装自动化成功、
也**禁止**用「发进当前会话凑合」这类变通绕过。凡是走到这些环节,先停下来,
把「要你做什么」一句话说清楚。

| 环节 | 为什么 agent 做不了 | agent 能推进到哪 | 该怎么跟用户说 |
|---|---|---|---|
| **在 IDE 里新建项目 / 打开文件夹** | ZCode「新项目」、Qoder「打开文件夹」都弹**原生文件夹对话框**,CDP 只能操作渲染进程内的 DOM,碰不到系统对话框 | `ide_guard.py --ide <x> --path <路径>` 判断有没有绑定,没有就列出现有目录 | 「请在 ZCode 侧栏点『新项目』→ 选 `D:\...`,这一步是系统对话框我点不到;建好我马上重派」 |
| **授予「完全访问」** | 权限弹窗由安全机制拦截,模拟点击等于绕过用户授权 | 能检测当前是不是「完全访问」 | 「请在那个任务里点『完全访问』,否则它读不到目标目录」 |
| **点排队消息的「插话 / 立即」** | 只有在 agent 生成中才出现,文案还因 IDE 而异 | `send_followup.py` 会自己找并点(ZCode=`立即`,Qoder=`插话`) | 脚本点完仍失败才需要用户:「消息卡在队列里,请手动点气泡上的『插话』」 |
| **Story 需求确认与冻结** | 需求边界、任务拆分、测试用例必须由人拍板 | 只能拿证据出问题清单 + 倾向性建议 | 一次性呈报(读到的现状 / 目标 / 有锚点的问题 / 拆分草案 / 用例草案 / 风险) |
| **每次外部工具派发前的确认** | 花的是用户的额度、占的是用户的 IDE | 能准备好 prompt 和参数 | 「我要派给 Qoder CN(端口 9222),项目 `X`,路径 `Y`,新建任务,只读评审 —— 确认?」 |
| **评审超轮次 / 双方结论对立** | 属于裁决,不是技术问题 | 能并列两份结论和分歧点 | 「两轮下来 P0 还在,冲突点是 X,你来定」 |
| **合入 main / 对外发布** | 高风险且不可撤销 | 能准备 diff 和自检结果 | 「改动 N 个文件,自检通过,要不要合入 main」 |
| **改被审对象后重新派发** | 需要用户知道「上一轮作废」 | 能识别文件哈希变了 | 「我在评审期间改了文件,上一轮结论作废,要重派一轮」 |

**判断口诀**:凡是**系统级对话框、权限授予、花钱、不可撤销**的动作,都是人的。

### 其他需要人的场景(agent 可自愈的先自愈)

- 派发失败:`IDE_OFFLINE`(端口没起)、选不到工作空间、任务占用、选择器失效
  → 先用 `routing_check.py` / `ide_guard.py --list` 定位,定位不了再叫人
- CDP 只能读**当前活动视图**:读回内容和预期不符时,先怀疑「界面被切走了」,
  而不是「它在偷懒」

## 脚本索引

| 脚本 | 用途 |
|---|---|
| `scripts/routing_check.py` | 能力与 IDE 门禁 |
| `scripts/ide_guard.py` | **按绝对路径**核对 IDE 里的项目绑定(派发前必跑) |
| `scripts/send_qoder.py` | Qoder CN / 国际版派发(指定 CDP 端口,**新建任务**) |
| `scripts/send_zcode.py` | ZCode 派发(**新建任务**) |
| `scripts/send_followup.py` | **同一会话续写**;会话归属校验 + 自动点「插话/立即」把排队消息插队 |
| `scripts/collect_review.py` | 从 IDE 数据库读回判定;`--wait` 阻塞到判定出现(**收工前必跑**) |
| `templates/*` | HANDOFF / ROUTING / STORY_KICKOFF / DISPATCH_CHECKLIST / contracts |

Files in this skill

  • SKILL.md18.2 KB
  • scripts/collect_review.py13.8 KB
  • scripts/ide_guard.py12.4 KB
  • scripts/routing_check.py7 KB
  • scripts/send_followup.py16.4 KB
  • scripts/send_qoder.py5.3 KB
  • scripts/send_zcode.py5.8 KB
  • templates/DISPATCH_CHECKLIST.md6.8 KB
  • templates/HANDOFF.md923 B
  • templates/ROUTING.yaml1.6 KB
  • templates/STORY_KICKOFF.md1.3 KB
  • templates/contracts/API.md279 B
  • templates/contracts/SCOPE.md301 B
  • templates/contracts/SPEC.md394 B
  • templates/contracts/examples.yaml1009 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.