diff --git a/skills/auto-tmux/AGENTS.md b/skills/auto-tmux/AGENTS.md index 72a2da4..e50a533 100644 --- a/skills/auto-tmux/AGENTS.md +++ b/skills/auto-tmux/AGENTS.md @@ -14,6 +14,7 @@ skills/auto-tmux/ ├── scripts/ # 安全封装的 tmux 自动化脚本 │ ├── auto-tmux.sh │ ├── swarm-state.sh +│ ├── swarm-brief.sh │ ├── render-swarm-prompt.sh │ ├── auto-tmux-smoke-test.sh │ ├── README.md @@ -36,6 +37,7 @@ skills/auto-tmux/ - `assets/tmux-src` 只暴露 tmux/tmux submodule,供需要查看源码或上游文档时定位。 - `scripts/auto-tmux.sh` 是技能执行层,封装 topology/capture/send/scan/rescue/record/snapshot/hub/wait。 - `scripts/swarm-state.sh` 是蜂群协作状态层,管理任务、锁、状态日志和结果报告。 +- `scripts/swarm-brief.sh` 是只读交接层,汇总 doctor/topology/scan/report 形成上下文快照。 - `scripts/render-swarm-prompt.sh` 是提示词渲染层,生成 commander/worker/reviewer 协议文本。 - 技能文档可以引用软链接入口;更新上游内容必须通过 `tools/external/` 下的 submodule 指针完成。 - 不在本目录直接修改 submodule 内容;如需改造,先 fork 上游并更新 submodule 来源。 @@ -45,4 +47,4 @@ skills/auto-tmux/ - 上游来源:`tools/external/.tmux` 与 `tools/external/tmux`。 - 下游使用:`SKILL.md` 和 `references/` 中的命令示例。 - 验证入口:`skills/auto-skill/scripts/validate-skill.sh skills/auto-tmux --strict`。 -- 脚本验证:`bash -n skills/auto-tmux/scripts/auto-tmux.sh`、`bash -n skills/auto-tmux/scripts/swarm-state.sh`、`bash -n skills/auto-tmux/scripts/render-swarm-prompt.sh`、`skills/auto-tmux/scripts/auto-tmux-smoke-test.sh`。 +- 脚本验证:`bash -n skills/auto-tmux/scripts/auto-tmux.sh`、`bash -n skills/auto-tmux/scripts/swarm-state.sh`、`bash -n skills/auto-tmux/scripts/swarm-brief.sh`、`bash -n skills/auto-tmux/scripts/render-swarm-prompt.sh`、`skills/auto-tmux/scripts/auto-tmux-smoke-test.sh`。 diff --git a/skills/auto-tmux/README.md b/skills/auto-tmux/README.md index 2e1a425..b4b17b2 100644 --- a/skills/auto-tmux/README.md +++ b/skills/auto-tmux/README.md @@ -21,9 +21,11 @@ ```bash bash -n skills/auto-tmux/scripts/auto-tmux.sh bash -n skills/auto-tmux/scripts/swarm-state.sh +bash -n skills/auto-tmux/scripts/swarm-brief.sh bash -n skills/auto-tmux/scripts/render-swarm-prompt.sh skills/auto-tmux/scripts/auto-tmux.sh help skills/auto-tmux/scripts/swarm-state.sh help +skills/auto-tmux/scripts/swarm-brief.sh --help skills/auto-tmux/scripts/render-swarm-prompt.sh commander --session ai-hub --task "smoke" skills/auto-tmux/scripts/auto-tmux-smoke-test.sh skills/auto-skill/scripts/validate-skill.sh skills/auto-tmux --strict diff --git a/skills/auto-tmux/SKILL.md b/skills/auto-tmux/SKILL.md index a7b0d91..86296b4 100644 --- a/skills/auto-tmux/SKILL.md +++ b/skills/auto-tmux/SKILL.md @@ -35,6 +35,7 @@ description: "tmux 自动化操控:用 scripts/auto-tmux.sh 安全读取、发 ```bash bash -n skills/auto-tmux/scripts/auto-tmux.sh bash -n skills/auto-tmux/scripts/swarm-state.sh +bash -n skills/auto-tmux/scripts/swarm-brief.sh bash -n skills/auto-tmux/scripts/render-swarm-prompt.sh skills/auto-tmux/scripts/auto-tmux.sh help skills/auto-tmux/scripts/swarm-state.sh help @@ -101,9 +102,10 @@ skills/auto-tmux/scripts/auto-tmux.sh scan --session ai-hub --pattern "ERROR|Tra skills/auto-tmux/scripts/auto-tmux.sh broadcast --session ai-hub --text "pwd" --enter --dry-run ``` -**生成证据快照** +**生成证据快照/交接报告** ```bash skills/auto-tmux/scripts/auto-tmux.sh snapshot --session ai-hub --dir /tmp/auto-tmux-snapshot -n 120 +skills/auto-tmux/scripts/swarm-brief.sh --session ai-hub --swarm-dir /tmp/ai_swarm --out /tmp/auto-tmux-brief ``` **远程救援:发现等待输入即发送 y** @@ -141,7 +143,10 @@ skills/auto-tmux/scripts/auto-tmux.sh wait -t :. --patter ```bash skills/auto-tmux/scripts/swarm-state.sh init --dir /tmp/ai_swarm skills/auto-tmux/scripts/swarm-state.sh task-add --id task-001 --text "检查 README 链接" +skills/auto-tmux/scripts/swarm-state.sh task-next --owner :. skills/auto-tmux/scripts/swarm-state.sh lock-acquire --name README.md --owner :. +skills/auto-tmux/scripts/swarm-state.sh task-block --id task-001 --owner :. --reason "等待输入" +skills/auto-tmux/scripts/swarm-state.sh task-fail --id task-001 --owner :. --reason "测试失败" skills/auto-tmux/scripts/swarm-state.sh report --dir /tmp/ai_swarm ``` @@ -226,6 +231,7 @@ skills/auto-tmux/scripts/render-swarm-prompt.sh reviewer --session ai-hub --task - `references/troubleshooting.md`: 典型故障到修复路径 - `scripts/auto-tmux.sh`: 安全封装的 tmux 自动化脚本入口 - `scripts/swarm-state.sh`: 蜂群任务、锁、状态和报告脚本 +- `scripts/swarm-brief.sh`: 只读生成 tmux 蜂群交接报告 - `scripts/render-swarm-prompt.sh`: commander/worker/reviewer 提示词渲染脚本 - `scripts/auto-tmux-smoke-test.sh`: tmux 自动化脚本端到端自测 - `assets/oh-my-tmux`: gpakosz/oh-my-tmux submodule 的相对软链接入口 @@ -246,6 +252,6 @@ skills/auto-tmux/scripts/render-swarm-prompt.sh reviewer --session ai-hub --task 4. ≥3 个端到端示例,含输入/步骤/验收。 5. 长文档放在 `references/` 并可导航;无文档堆砌。 6. 不确定项给出验证路径;禁止虚构 tmux 行为。 -7. `bash -n skills/auto-tmux/scripts/auto-tmux.sh`、`bash -n skills/auto-tmux/scripts/swarm-state.sh` 与 `bash -n skills/auto-tmux/scripts/render-swarm-prompt.sh` 通过。 +7. `bash -n skills/auto-tmux/scripts/auto-tmux.sh`、`bash -n skills/auto-tmux/scripts/swarm-state.sh`、`bash -n skills/auto-tmux/scripts/swarm-brief.sh` 与 `bash -n skills/auto-tmux/scripts/render-swarm-prompt.sh` 通过。 8. `skills/auto-tmux/scripts/auto-tmux-smoke-test.sh` 通过或在无 tmux 环境下明确跳过。 9. 运行 `skills/auto-skill/scripts/validate-skill.sh skills/auto-tmux --strict` 通过。 diff --git a/skills/auto-tmux/references/README.md b/skills/auto-tmux/references/README.md index 6fe2ae0..d7365f2 100644 --- a/skills/auto-tmux/references/README.md +++ b/skills/auto-tmux/references/README.md @@ -7,7 +7,7 @@ | [index.md](./index.md) | 参考资料索引 | | [getting_started.md](./getting_started.md) | 术语、最短路径和工作姿势 | | [api.md](./api.md) | tmux / oh-my-tmux 常用命令与配置速查 | -| [automation.md](./automation.md) | `auto-tmux.sh` 脚本子命令、安全模型和 AI 蜂群协作流程 | +| [automation.md](./automation.md) | `auto-tmux.sh` / `swarm-brief.sh` 脚本子命令、安全模型和 AI 蜂群协作流程 | | [swarm-state.md](./swarm-state.md) | 蜂群状态、任务、锁和报告协议 | | [prompt-templates.md](./prompt-templates.md) | commander/worker/reviewer 提示词模板和下发方式 | | [ai-swarm-collaboration.md](./ai-swarm-collaboration.md) | tmux 蜂群协作完整说明、架构模式、协议、案例和风险限制 | diff --git a/skills/auto-tmux/references/ai-swarm-collaboration.md b/skills/auto-tmux/references/ai-swarm-collaboration.md index 67ef921..893d56f 100644 --- a/skills/auto-tmux/references/ai-swarm-collaboration.md +++ b/skills/auto-tmux/references/ai-swarm-collaboration.md @@ -26,6 +26,7 @@ tmux 蜂群协作的核心是:让 AI 不再只是孤立会话,而是通过 t | 救援 | `auto-tmux.sh rescue` | 对等待确认、卡住或异常的 pane 做最小干预 | | 记录 | `pipe-pane` / `auto-tmux.sh record` | 保留长任务审计日志 | | 协调 | `swarm-state.sh` + 明确 target | 任务同步、分工、加锁、避免冲突 | +| 交接 | `swarm-brief.sh` | 导出只读状态报告,便于新会话或 reviewer 接手 | ```text 传统模式: 人 <-> AI1, 人 <-> AI2, 人 <-> AI3 @@ -120,7 +121,7 @@ skills/auto-tmux/scripts/swarm-state.sh init --dir /tmp/ai_swarm ```text /tmp/ai_swarm/ ├── status.log -├── tasks.json +├── tasks.tsv ├── locks/ └── results/ ``` @@ -136,6 +137,8 @@ skills/auto-tmux/scripts/swarm-state.sh init --dir /tmp/ai_swarm ```text [START] 开始任务 [DONE] 完成任务 +[BLOCKED] 阻塞,等待输入、依赖或权限 +[FAIL] 任务失败,需要 commander 处理 [WAIT] 等待依赖或确认 [ERROR] 出现错误 [HELP] 请求帮助 @@ -150,7 +153,8 @@ skills/auto-tmux/scripts/swarm-state.sh init --dir /tmp/ai_swarm 4. **避免冲突**:涉及同一文件、同一服务、同一配置时先加锁或等待。 5. **主动救援**:发现等待确认、卡死或明显错误时先 `capture`,再 `rescue --dry-run`。 6. **保留证据**:长任务开启 `record`,关键检查保存 scan 日志。 -7. **人工兜底**:危险操作、敏感凭证、生产环境变更必须人工确认。 +7. **交接可恢复**:阶段结束或上下文切换前生成 `swarm-brief.sh` 报告。 +8. **人工兜底**:危险操作、敏感凭证、生产环境变更必须人工确认。 ### 4.4 任务与锁 @@ -164,6 +168,7 @@ worker 认领任务: ```bash skills/auto-tmux/scripts/swarm-state.sh task-claim --id task-001 --owner "ai-hub:2.1" +skills/auto-tmux/scripts/swarm-state.sh task-next --owner "ai-hub:2.1" ``` 修改文件前获取锁: @@ -179,6 +184,19 @@ skills/auto-tmux/scripts/swarm-state.sh lock-release --name README.md --owner "a skills/auto-tmux/scripts/swarm-state.sh task-done --id task-001 --owner "ai-hub:2.1" --result "make test passed" ``` +阻塞或失败时显式记录: + +```bash +skills/auto-tmux/scripts/swarm-state.sh task-block --id task-001 --owner "ai-hub:2.1" --reason "等待用户确认" +skills/auto-tmux/scripts/swarm-state.sh task-fail --id task-001 --owner "ai-hub:2.1" --reason "make test failed" +``` + +生成交接报告: + +```bash +skills/auto-tmux/scripts/swarm-brief.sh --session ai-hub --swarm-dir /tmp/ai_swarm --out /tmp/auto-tmux-brief +``` + ## 5. 架构模式 ### 5.1 P2P 对等模式 @@ -396,7 +414,7 @@ window: - Web 面板:把 topology、scan、record 状态暴露为只读监控页面。 - 智能调度:根据 worker 空闲程度、任务类型和失败状态分配任务。 - CI 集成:让 GitHub Actions 或本地 gate 接收 worker 结果,统一决定是否通过。 -- 状态机治理:用 JSON schema 约束 `/tmp/ai_swarm/tasks.json` 与 `results/`。 +- 状态机治理:用 schema 或校验脚本约束 `/tmp/ai_swarm/tasks.tsv` 与 `results/`。 ## 11. 快速参考 diff --git a/skills/auto-tmux/references/automation.md b/skills/auto-tmux/references/automation.md index 2214865..5e7d781 100644 --- a/skills/auto-tmux/references/automation.md +++ b/skills/auto-tmux/references/automation.md @@ -8,6 +8,7 @@ - **默认脱敏**:读取 pane 输出时自动遮蔽常见 token、API key、password、Bearer token。 - **拒绝危险动作**:`rm -rf`、`git reset --hard`、`git clean -fd`、`tmux kill-server` 等命令默认拒绝,必须显式 `--force`。 - **批量动作可解释**:scan/rescue 都基于明确 session、pane、pattern 和 reply,不做无条件广播。 +- **交接报告只读**:brief 汇总 doctor、topology、scan 和 state report,不发送按键、不改变 tmux 状态。 - **不改用户配置**:脚本只操作 tmux server,不写 `~/.tmux.conf`;oh-my-tmux 配置仍走 `assets/oh-my-tmux` 参考入口。 ## 子命令总览 @@ -25,6 +26,7 @@ | `snapshot` | 导出拓扑和 pane 输出证据包 | 默认脱敏,写入显式目录 | | `hub` | 初始化 AI 多终端工作台 | 已存在 session 不覆盖 | | `wait` | 等待 pane 输出出现某个 pattern | 超时失败 | +| `swarm-brief.sh` | 生成只读交接报告 | 不发送按键,只汇总证据 | ## 典型流程 @@ -76,6 +78,12 @@ skills/auto-tmux/scripts/auto-tmux.sh broadcast --session ai-hub --text "pwd" -- skills/auto-tmux/scripts/auto-tmux.sh snapshot --session ai-hub --dir /tmp/auto-tmux-snapshot -n 120 ``` +生成可交接的蜂群报告: + +```bash +skills/auto-tmux/scripts/swarm-brief.sh --session ai-hub --swarm-dir /tmp/ai_swarm --out /tmp/auto-tmux-brief -n 80 +``` + ### 3. 安全发送命令 ```bash @@ -159,6 +167,14 @@ skills/auto-tmux/scripts/swarm-state.sh init --dir /tmp/ai_swarm ```bash skills/auto-tmux/scripts/swarm-state.sh task-add --id task-001 --text "检查 README 链接" skills/auto-tmux/scripts/swarm-state.sh task-claim --id task-001 --owner "ai-hub:2.1" +skills/auto-tmux/scripts/swarm-state.sh task-next --owner "ai-hub:2.1" +``` + +标记阻塞或失败: + +```bash +skills/auto-tmux/scripts/swarm-state.sh task-block --id task-001 --owner "ai-hub:2.1" --reason "等待用户确认" +skills/auto-tmux/scripts/swarm-state.sh task-fail --id task-001 --owner "ai-hub:2.1" --reason "make test failed" ``` 获取文件锁: @@ -179,9 +195,11 @@ skills/auto-tmux/scripts/swarm-state.sh report ```bash bash -n skills/auto-tmux/scripts/auto-tmux.sh bash -n skills/auto-tmux/scripts/swarm-state.sh +bash -n skills/auto-tmux/scripts/swarm-brief.sh bash -n skills/auto-tmux/scripts/render-swarm-prompt.sh skills/auto-tmux/scripts/auto-tmux.sh help skills/auto-tmux/scripts/swarm-state.sh help +skills/auto-tmux/scripts/swarm-brief.sh --help skills/auto-tmux/scripts/render-swarm-prompt.sh commander --session ai-hub --task "smoke" skills/auto-tmux/scripts/auto-tmux-smoke-test.sh skills/auto-skill/scripts/validate-skill.sh skills/auto-tmux --strict diff --git a/skills/auto-tmux/references/index.md b/skills/auto-tmux/references/index.md index 596b2bb..51e5dce 100644 --- a/skills/auto-tmux/references/index.md +++ b/skills/auto-tmux/references/index.md @@ -4,7 +4,7 @@ - `getting_started.md`:术语、最小安装、前缀说明 - `api.md`:tmux/oh-my-tmux 常用命令、同步广播、安全写法 -- `automation.md`:`scripts/auto-tmux.sh` 子命令、安全模型与 AI 蜂群协作流程 +- `automation.md`:`scripts/auto-tmux.sh` / `scripts/swarm-brief.sh` 子命令、安全模型与 AI 蜂群协作流程 - `swarm-state.md`:蜂群状态、任务、锁和报告协议 - `prompt-templates.md`:commander/worker/reviewer 提示词模板和下发方式 - `ai-swarm-collaboration.md`:tmux 蜂群协作完整说明、架构模式、协议、案例和风险限制 diff --git a/skills/auto-tmux/references/prompt-templates.md b/skills/auto-tmux/references/prompt-templates.md index 44cdd56..def62e5 100644 --- a/skills/auto-tmux/references/prompt-templates.md +++ b/skills/auto-tmux/references/prompt-templates.md @@ -88,5 +88,5 @@ skills/auto-tmux/scripts/auto-tmux.sh send \ - Prompt 只定义职责和边界,不替代测试、lint、diff、CI 等硬门禁。 - commander、worker、reviewer 应使用不同 pane,避免角色混淆。 -- 长任务必须配合 `record` 或 `snapshot` 保留证据。 +- 长任务必须配合 `record`、`snapshot` 或 `swarm-brief.sh` 保留证据。 - 多 worker 修改同一资源前必须配合 `swarm-state.sh lock-acquire`。 diff --git a/skills/auto-tmux/references/swarm-state.md b/skills/auto-tmux/references/swarm-state.md index fb5151f..40986bf 100644 --- a/skills/auto-tmux/references/swarm-state.md +++ b/skills/auto-tmux/references/swarm-state.md @@ -53,6 +53,8 @@ skills/auto-tmux/scripts/swarm-state.sh status -n 20 |:---|:---| | `START` | 开始任务 | | `DONE` | 完成任务 | +| `BLOCKED` | 阻塞,等待依赖、输入或权限 | +| `FAIL` | 任务失败,需要 commander 处理 | | `WAIT` | 等待依赖、输入或门禁 | | `ERROR` | 出现错误 | | `HELP` | 请求帮助 | @@ -74,6 +76,12 @@ skills/auto-tmux/scripts/swarm-state.sh task-add --id task-001 --text "检查 RE skills/auto-tmux/scripts/swarm-state.sh task-claim --id task-001 --owner "ai-hub:2.1" ``` +领取下一条 `TODO` 任务: + +```bash +skills/auto-tmux/scripts/swarm-state.sh task-next --owner "ai-hub:2.1" +``` + 完成任务: ```bash @@ -83,6 +91,24 @@ skills/auto-tmux/scripts/swarm-state.sh task-done \ --result "make test passed" ``` +标记阻塞: + +```bash +skills/auto-tmux/scripts/swarm-state.sh task-block \ + --id task-001 \ + --owner "ai-hub:2.1" \ + --reason "等待用户确认 API key 配置" +``` + +标记失败: + +```bash +skills/auto-tmux/scripts/swarm-state.sh task-fail \ + --id task-001 \ + --owner "ai-hub:2.1" \ + --reason "make test failed" +``` + 查看任务: ```bash @@ -136,9 +162,9 @@ skills/auto-tmux/scripts/swarm-state.sh report 1. commander 初始化状态目录。 2. commander 将任务写入 `tasks.tsv`。 3. worker 获取文件或服务锁。 -4. worker 认领任务并写入 `START`。 +4. worker 用 `task-next` 或 `task-claim` 认领任务并写入 `START`。 5. worker 执行任务,必要时用 `auto-tmux.sh record` 保留日志。 -6. worker 完成后写入 `DONE` 和结果。 +6. worker 完成后写入 `DONE` 和结果;无法继续时写入 `BLOCKED` 或 `FAIL`。 7. commander 用 `report` 汇总状态,再用测试、diff、日志做验收。 ## 安全边界 diff --git a/skills/auto-tmux/scripts/AGENTS.md b/skills/auto-tmux/scripts/AGENTS.md index b5b0f04..6c72757 100644 --- a/skills/auto-tmux/scripts/AGENTS.md +++ b/skills/auto-tmux/scripts/AGENTS.md @@ -10,6 +10,7 @@ scripts/ ├── README.md # 面向人类的脚本入口说明 ├── auto-tmux.sh # 统一 tmux 自动化命令入口 ├── swarm-state.sh # 蜂群状态、任务、锁和报告管理 +├── swarm-brief.sh # 只读生成蜂群交接报告 ├── render-swarm-prompt.sh # commander/worker/reviewer 提示词渲染 └── auto-tmux-smoke-test.sh # 临时 tmux 会话端到端自测 ``` @@ -22,6 +23,7 @@ scripts/ - 批量救援必须通过 pattern 匹配触发,不允许无条件向所有 pane 发送输入。 - 批量广播必须要求显式 session,并支持 `--dry-run`。 - Prompt 渲染脚本只输出文本,不直接控制 tmux。 +- 交接报告脚本只读调用 doctor/topology/scan/report,不直接发送按键。 - 状态脚本只能写入显式状态目录,不保存密钥、Token、密码或私密项目内容。 - 自测脚本必须创建独立临时 tmux session,并在退出时清理。 - 新增脚本后必须更新 `README.md`、`SKILL.md`、`references/index.md`,并运行 `bash -n` 与 skill strict 校验。 diff --git a/skills/auto-tmux/scripts/README.md b/skills/auto-tmux/scripts/README.md index bcd1a23..f796bfd 100644 --- a/skills/auto-tmux/scripts/README.md +++ b/skills/auto-tmux/scripts/README.md @@ -6,6 +6,7 @@ - [`auto-tmux.sh`](./auto-tmux.sh) - 统一命令入口,支持拓扑、读取、发送、巡检、救援、录制、等待和 AI 工作台初始化。 - [`swarm-state.sh`](./swarm-state.sh) - 蜂群状态、任务、锁和报告管理。 +- [`swarm-brief.sh`](./swarm-brief.sh) - 只读生成蜂群交接报告,汇总 doctor、topology、pane 输出和状态报告。 - [`render-swarm-prompt.sh`](./render-swarm-prompt.sh) - commander、worker、reviewer 提示词渲染。 - [`auto-tmux-smoke-test.sh`](./auto-tmux-smoke-test.sh) - 创建临时 tmux 会话,端到端验证脚本能力。 @@ -38,9 +39,15 @@ skills/auto-tmux/scripts/auto-tmux.sh broadcast --session ai-hub --text "pwd" -- # 生成证据快照 skills/auto-tmux/scripts/auto-tmux.sh snapshot --session ai-hub --dir /tmp/auto-tmux-snapshot +# 生成蜂群交接报告 +skills/auto-tmux/scripts/swarm-brief.sh --session ai-hub --swarm-dir /tmp/ai_swarm --out /tmp/auto-tmux-brief + # 初始化蜂群状态并添加任务 skills/auto-tmux/scripts/swarm-state.sh init --dir /tmp/ai_swarm skills/auto-tmux/scripts/swarm-state.sh task-add --id task-001 --text "检查 README 链接" +skills/auto-tmux/scripts/swarm-state.sh task-next --owner "$target" --dir /tmp/ai_swarm +skills/auto-tmux/scripts/swarm-state.sh task-block --id task-001 --owner "$target" --reason "等待输入" --dir /tmp/ai_swarm +skills/auto-tmux/scripts/swarm-state.sh task-fail --id task-001 --owner "$target" --reason "测试失败" --dir /tmp/ai_swarm skills/auto-tmux/scripts/swarm-state.sh report --dir /tmp/ai_swarm # 端到端自测 diff --git a/skills/auto-tmux/scripts/auto-tmux-smoke-test.sh b/skills/auto-tmux/scripts/auto-tmux-smoke-test.sh index eae385e..950e218 100755 --- a/skills/auto-tmux/scripts/auto-tmux-smoke-test.sh +++ b/skills/auto-tmux/scripts/auto-tmux-smoke-test.sh @@ -6,14 +6,16 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" AUTO_TMUX="$SCRIPT_DIR/auto-tmux.sh" SWARM_STATE="$SCRIPT_DIR/swarm-state.sh" RENDER_PROMPT="$SCRIPT_DIR/render-swarm-prompt.sh" +SWARM_BRIEF="$SCRIPT_DIR/swarm-brief.sh" SESSION="auto-tmux-smoke-$$" SWARM_DIR="/tmp/auto-tmux-smoke-swarm-$$" SNAPSHOT_DIR="/tmp/auto-tmux-smoke-snapshot-$$" RECORD_DIR="/tmp/auto-tmux-smoke-record-$$" +BRIEF_DIR="/tmp/auto-tmux-smoke-brief-$$" cleanup() { tmux kill-session -t "$SESSION" 2>/dev/null || true - rm -rf "$SWARM_DIR" "$SNAPSHOT_DIR" "$RECORD_DIR" + rm -rf "$SWARM_DIR" "$SNAPSHOT_DIR" "$RECORD_DIR" "$BRIEF_DIR" } trap cleanup EXIT @@ -25,6 +27,7 @@ command -v tmux >/dev/null 2>&1 || { bash -n "$AUTO_TMUX" bash -n "$SWARM_STATE" bash -n "$RENDER_PROMPT" +bash -n "$SWARM_BRIEF" "$AUTO_TMUX" hub --session "$SESSION" --workers 1 --cmd bash "$AUTO_TMUX" doctor --session "$SESSION" >/tmp/auto-tmux-smoke-doctor.txt @@ -49,8 +52,18 @@ test -s "$SNAPSHOT_DIR/topology.txt" "$SWARM_STATE" lock-acquire --dir "$SWARM_DIR" --name smoke-file --owner "$worker_target" >/tmp/auto-tmux-smoke-lock.txt "$SWARM_STATE" lock-release --dir "$SWARM_DIR" --name smoke-file --owner "$worker_target" >/tmp/auto-tmux-smoke-unlock.txt "$SWARM_STATE" task-done --dir "$SWARM_DIR" --id smoke-task --owner "$worker_target" --result "ok" +"$SWARM_STATE" task-add --dir "$SWARM_DIR" --id smoke-next --text "claim next task" >/tmp/auto-tmux-smoke-task-next-add.txt +"$SWARM_STATE" task-next --dir "$SWARM_DIR" --owner "$worker_target" >/tmp/auto-tmux-smoke-task-next.txt +grep -q 'smoke-next' /tmp/auto-tmux-smoke-task-next.txt +"$SWARM_STATE" task-block --dir "$SWARM_DIR" --id smoke-next --owner "$worker_target" --reason "waiting for input" +"$SWARM_STATE" task-add --dir "$SWARM_DIR" --id smoke-fail --text "fail task" >/tmp/auto-tmux-smoke-task-fail-add.txt +"$SWARM_STATE" task-fail --dir "$SWARM_DIR" --id smoke-fail --owner "$worker_target" --reason "expected failure" "$SWARM_STATE" report --dir "$SWARM_DIR" >/tmp/auto-tmux-smoke-report.txt grep -q 'smoke-task' /tmp/auto-tmux-smoke-report.txt +grep -q 'BLOCKED' /tmp/auto-tmux-smoke-report.txt +grep -q 'FAIL' /tmp/auto-tmux-smoke-report.txt +"$SWARM_BRIEF" --session "$SESSION" --swarm-dir "$SWARM_DIR" --out "$BRIEF_DIR" -n 10 >/tmp/auto-tmux-smoke-brief.txt +grep -q 'auto-tmux Swarm Brief' "$BRIEF_DIR/brief.md" "$RENDER_PROMPT" commander --session "$SESSION" --swarm-dir "$SWARM_DIR" --task "smoke" >/tmp/auto-tmux-smoke-commander-prompt.md "$RENDER_PROMPT" worker --session "$SESSION" --target "$worker_target" --swarm-dir "$SWARM_DIR" --task "smoke" >/tmp/auto-tmux-smoke-worker-prompt.md grep -q 'Commander Prompt' /tmp/auto-tmux-smoke-commander-prompt.md diff --git a/skills/auto-tmux/scripts/auto-tmux.sh b/skills/auto-tmux/scripts/auto-tmux.sh index 755dbe8..9c3800f 100755 --- a/skills/auto-tmux/scripts/auto-tmux.sh +++ b/skills/auto-tmux/scripts/auto-tmux.sh @@ -147,7 +147,7 @@ cmd_doctor() { status_line "WARN" "tmux server has no reachable session yet" fi - for script in auto-tmux.sh swarm-state.sh auto-tmux-smoke-test.sh render-swarm-prompt.sh; do + for script in auto-tmux.sh swarm-state.sh swarm-brief.sh auto-tmux-smoke-test.sh render-swarm-prompt.sh; do if [[ -x "$script_dir/$script" ]]; then status_line "OK" "script executable: $script" else diff --git a/skills/auto-tmux/scripts/render-swarm-prompt.sh b/skills/auto-tmux/scripts/render-swarm-prompt.sh index 518d5b4..d9c494c 100755 --- a/skills/auto-tmux/scripts/render-swarm-prompt.sh +++ b/skills/auto-tmux/scripts/render-swarm-prompt.sh @@ -66,7 +66,8 @@ case "$role" in 4. 给每个子任务创建 task,并在涉及同一文件、目录或服务时要求 worker 先加锁。 5. 用 scan/capture/snapshot 收集 worker 状态与证据。 6. 对卡住任务先 dry-run rescue,再做最小干预。 -7. 最终只用测试、diff、日志、报告和人工验收作为完成依据。 +7. 阶段结束时用 swarm-brief.sh 生成交接报告。 +8. 最终只用测试、diff、日志、报告和人工验收作为完成依据。 ## 禁止 @@ -92,10 +93,10 @@ EOF ## 你的职责 1. 只处理分配给你的单一任务。 -2. 开始前用 \`swarm-state.sh task-claim\` 认领任务。 +2. 开始前用 \`swarm-state.sh task-next\` 或 \`swarm-state.sh task-claim\` 认领任务。 3. 修改文件、目录或服务前,用 \`swarm-state.sh lock-acquire\` 获取锁。 4. 执行中保留关键命令、错误、测试结果和风险。 -5. 完成后用 \`swarm-state.sh task-done\` 写入结果。 +5. 完成后用 \`swarm-state.sh task-done\` 写入结果;无法继续时用 \`task-block\` 或 \`task-fail\` 写明原因。 6. 汇报格式必须包含:状态、修改文件、验证结果、风险、下一步。 ## 禁止 @@ -120,9 +121,10 @@ EOF ## 你的职责 1. 读取 commander 汇总、worker 结果、snapshot、record 日志和 git diff。 -2. 优先寻找 correctness、越界修改、缺失测试、风险遗漏和文档不同步。 -3. 对每个问题给出文件、证据、影响和最小修复建议。 -4. 如果没有阻塞问题,明确说明剩余风险和建议补充验证。 +2. 优先读取 \`swarm-brief.sh\` 生成的交接报告,恢复当前拓扑、状态和 pane 输出。 +3. 优先寻找 correctness、越界修改、缺失测试、风险遗漏和文档不同步。 +4. 对每个问题给出文件、证据、影响和最小修复建议。 +5. 如果没有阻塞问题,明确说明剩余风险和建议补充验证。 ## 禁止 diff --git a/skills/auto-tmux/scripts/swarm-brief.sh b/skills/auto-tmux/scripts/swarm-brief.sh new file mode 100755 index 0000000..9c7df54 --- /dev/null +++ b/skills/auto-tmux/scripts/swarm-brief.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +# Build a read-only handoff brief for a tmux AI swarm session. +set -euo pipefail + +usage() { + cat <<'EOF' +swarm-brief: export tmux AI swarm topology, pane output and state report into one brief + +Usage: + swarm-brief.sh [--session NAME] [--swarm-dir DIR] [--out DIR] [-n LINES] + +Examples: + swarm-brief.sh --session ai-hub --swarm-dir /tmp/ai_swarm + swarm-brief.sh --session ai-hub --out /tmp/auto-tmux-brief -n 80 +EOF +} + +die() { + printf 'error: %s\n' "$*" >&2 + exit 1 +} + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +auto_tmux="$script_dir/auto-tmux.sh" +swarm_state="$script_dir/swarm-state.sh" + +session="" +swarm_dir="${AUTO_TMUX_SWARM_DIR:-/tmp/ai_swarm}" +out_dir="/tmp/auto-tmux-brief-$(date +%Y%m%d-%H%M%S)" +lines=80 + +while [[ $# -gt 0 ]]; do + case "$1" in + --session) session="${2:-}"; shift 2 ;; + --swarm-dir) swarm_dir="${2:-}"; shift 2 ;; + --out) out_dir="${2:-}"; shift 2 ;; + -n|--lines) lines="${2:-}"; shift 2 ;; + -h|--help) usage; exit 0 ;; + *) die "unknown option: $1" ;; + esac +done + +mkdir -p "$out_dir" +brief="$out_dir/brief.md" + +run_block() { + local title="$1" + shift + { + printf '## %s\n\n' "$title" + printf '```text\n' + "$@" 2>&1 || printf '[command failed: %s]\n' "$*" + printf '```\n\n' + } >> "$brief" +} + +{ + printf '# auto-tmux Swarm Brief\n\n' + printf '%s\n' "- created_at: \`$(date -Is)\`" + printf '%s\n' "- session: \`${session:-}\`" + printf '%s\n' "- swarm_dir: \`$swarm_dir\`" + printf '%s\n\n' "- lines_per_pane: \`$lines\`" + printf '本报告是只读交接快照,用于让 commander、reviewer 或新会话快速恢复上下文。\n\n' +} > "$brief" + +doctor_args=(doctor) +topology_args=(topology) +scan_args=(scan -n "$lines") +if [[ -n "$session" ]]; then + doctor_args+=(--session "$session") + topology_args+=(--session "$session") + scan_args+=(--session "$session") +fi + +run_block "Doctor" "$auto_tmux" "${doctor_args[@]}" +run_block "Topology" "$auto_tmux" "${topology_args[@]}" +run_block "Recent Pane Output" "$auto_tmux" "${scan_args[@]}" + +if [[ -d "$swarm_dir" ]]; then + run_block "Swarm State Report" "$swarm_state" report --dir "$swarm_dir" +else + { + printf '## Swarm State Report\n\n' + printf '```text\n' + printf 'swarm state dir not found: %s\n' "$swarm_dir" + printf 'initialize with: %s init --dir %s\n' "$swarm_state" "$swarm_dir" + printf '```\n\n' + } >> "$brief" +fi + +printf 'brief written: %s\n' "$brief" diff --git a/skills/auto-tmux/scripts/swarm-state.sh b/skills/auto-tmux/scripts/swarm-state.sh index 4b13edc..f675270 100755 --- a/skills/auto-tmux/scripts/swarm-state.sh +++ b/skills/auto-tmux/scripts/swarm-state.sh @@ -7,6 +7,7 @@ STATUS_LOG="$SWARM_DIR/status.log" TASKS_TSV="$SWARM_DIR/tasks.tsv" LOCKS_DIR="$SWARM_DIR/locks" RESULTS_DIR="$SWARM_DIR/results" +STATE_LOCK_DIR="$SWARM_DIR/.state.lock.d" usage() { cat <<'EOF' @@ -18,8 +19,11 @@ Usage: swarm-state.sh status [--dir DIR] swarm-state.sh task-add --text TEXT [--id ID] [--dir DIR] swarm-state.sh task-list [--dir DIR] + swarm-state.sh task-next --owner TARGET [--dir DIR] swarm-state.sh task-claim --id ID --owner TARGET [--dir DIR] swarm-state.sh task-done --id ID --owner TARGET [--result TEXT] [--dir DIR] + swarm-state.sh task-block --id ID --owner TARGET --reason TEXT [--dir DIR] + swarm-state.sh task-fail --id ID --owner TARGET --reason TEXT [--dir DIR] swarm-state.sh lock-acquire --name NAME --owner TARGET [--dir DIR] swarm-state.sh lock-release --name NAME --owner TARGET [--dir DIR] [--force] swarm-state.sh lock-list [--dir DIR] @@ -46,6 +50,7 @@ set_dir() { TASKS_TSV="$SWARM_DIR/tasks.tsv" LOCKS_DIR="$SWARM_DIR/locks" RESULTS_DIR="$SWARM_DIR/results" + STATE_LOCK_DIR="$SWARM_DIR/.state.lock.d" } ensure_init() { @@ -56,6 +61,25 @@ ensure_init() { fi } +acquire_state_lock() { + local timeout="${1:-10}" + local start now + start="$(date +%s)" + while ! mkdir "$STATE_LOCK_DIR" 2>/dev/null; do + now="$(date +%s)" + if (( now - start >= timeout )); then + die "timeout waiting for swarm state lock: $STATE_LOCK_DIR" + fi + sleep 0.2 + done + printf '%s\n' "$$" > "$STATE_LOCK_DIR/pid" + printf '%s\n' "$(date -Is)" > "$STATE_LOCK_DIR/created_at" +} + +release_state_lock() { + rm -rf "$STATE_LOCK_DIR" +} + cmd_init() { while [[ $# -gt 0 ]]; do case "$1" in @@ -167,6 +191,40 @@ cmd_task_claim() { cmd_log --target "$owner" --status "START" --message "claimed $id" } +cmd_task_next() { + local owner="" + while [[ $# -gt 0 ]]; do + case "$1" in + --dir) set_dir "${2:-}"; shift 2 ;; + --owner) owner="${2:-}"; shift 2 ;; + *) die "unknown task-next option: $1" ;; + esac + done + [[ -n "$owner" ]] || die "missing --owner" + ensure_init + + acquire_state_lock + local id tmp + id="$(awk -F '\t' 'NR > 1 && $2 == "TODO" {print $1; exit}' "$TASKS_TSV")" + if [[ -z "$id" ]]; then + release_state_lock + printf 'no TODO task available\n' + return 1 + fi + + tmp="$(mktemp)" + awk -F '\t' -v OFS='\t' -v id="$id" -v owner="$owner" ' + NR == 1 {print; next} + $1 == id {$2 = "DOING"; $3 = owner} + {print} + ' "$TASKS_TSV" > "$tmp" + mv "$tmp" "$TASKS_TSV" + release_state_lock + + cmd_log --target "$owner" --status "START" --message "claimed next $id" + printf 'task claimed: %s\n' "$id" +} + cmd_task_done() { local id="" owner="" result="done" while [[ $# -gt 0 ]]; do @@ -187,6 +245,29 @@ cmd_task_done() { cmd_log --target "$owner" --status "DONE" --message "$id $result" } +cmd_task_terminal() { + local status="$1" + shift + local id="" owner="" reason="" + while [[ $# -gt 0 ]]; do + case "$1" in + --dir) set_dir "${2:-}"; shift 2 ;; + --id) id="${2:-}"; shift 2 ;; + --owner) owner="${2:-}"; shift 2 ;; + --reason) reason="${2:-}"; shift 2 ;; + *) die "unknown task-$status option: $1" ;; + esac + done + [[ -n "$id" ]] || die "missing --id" + [[ -n "$owner" ]] || die "missing --owner" + [[ -n "$reason" ]] || die "missing --reason" + ensure_init + reason="$(printf '%s' "$reason" | sanitize)" + update_task "$id" "$status" "$owner" "$reason" + printf '%s\n' "$reason" > "$RESULTS_DIR/$id.txt" + cmd_log --target "$owner" --status "$status" --message "$id $reason" +} + lock_path() { local name="$1" name="$(printf '%s' "$name" | sed -E 's#[^A-Za-z0-9_.-]+#_#g')" @@ -290,8 +371,11 @@ main() { status) cmd_status "$@" ;; task-add) cmd_task_add "$@" ;; task-list) cmd_task_list "$@" ;; + task-next) cmd_task_next "$@" ;; task-claim) cmd_task_claim "$@" ;; task-done) cmd_task_done "$@" ;; + task-block) cmd_task_terminal "BLOCKED" "$@" ;; + task-fail) cmd_task_terminal "FAIL" "$@" ;; lock-acquire) cmd_lock_acquire "$@" ;; lock-release) cmd_lock_release "$@" ;; lock-list) cmd_lock_list "$@" ;;