用途
implement-tmux 是 mattpocock/skills /implement 的调度层,不替代单 ticket 的实现流程。它负责从规划文档生成候选执行计划、创建隔离的 tmux window、严格串行调度 worker、消费一次性终态消息、独立核验和清理。
共享工作区中任何时刻只有一个 ticket 处于 running 或 verifying;没有依赖关系的 ticket 也不能并行。运行时只使用原生 tmux CLI,不依赖 smux、tmux-bridge、daemon、MCP 或自定义服务。
主窗口只处理最终结构化消息和简短核验结果,不要持续读取 worker pane、思考过程或中间日志;只有终态缺失、失败/阻塞取证或用户明确要求时,才读取少量 pane 尾部输出。
输入与候选计划
接受的输入包括:/wayfinder 生成的 map.md;/to-tickets 生成的 spec.md;可选的、已确认过的持久化 manifest;用户提供的项目路径、tmux session 和显式 ticket 顺序(显式顺序可覆盖文档默认顺序)。manifest 可选,不要求用户重复填写文档中已有信息。
启动时在内存中生成候选计划:从 map/spec 读取 ticket id、顺序、依赖、tracker、范围和验收信息,从 tracker、项目结构、Git 状态和 package.json scripts 补充缺失信息;从 ticket 明确列出的文件、tracker 变更范围、spec 产物和对应测试文件推断 allowedPaths,不能可靠推断的路径保持不确定、不得猜测;从 ticket 验收命令和项目已有 scripts 推断 verify,命令必须在项目中可识别且可执行,无法识别的验收命令必须阻塞;maxRepairRounds 缺失时使用 2;不把 /implement 的 TDD、typecheck、测试、review 或 commit 规则复制到本 skill。
启动前必须展示完整候选计划并只请求一次确认,计划至少展示 project、session、mainPane 和 agent policy,ticket 顺序及依赖,每个 ticket 的 allowedPaths、verify、tracker 和不确定项,启动时 Git 基线中的 modified、untracked、staged 路径,额外 protected paths(coverage、lock、调度状态和用户声明项),maxRepairRounds,以及终态消息使用 tmux send-keys 回传、不创建 resultFile。在用户确认前禁止创建 ticket window、启动 worker 或修改工作区。显式顺序与 map/spec 不同时,计划必须同时展示两种顺序并在同一次确认中请求选择;用户未明确选择时才报告 TICKET_BLOCKED。项目/session 不明、tracker/范围/验收无法推断或候选范围与保护边界重叠时,直接报告 TICKET_BLOCKED 并列出具体缺口。
状态机
pending → running → verifying → done,并可从 running 转向 failed 或 blocked。done 表示终态消息、commit、文件范围、staging、验收和证据全部独立核验通过;failed 表示代码、断言、配置、测试或产物失败,只允许按 /implement 的结果和计划上限进行有依据的修复—重跑;blocked 表示 tmux、worker CLI、/implement、外部构建、DevTools 或其他环境/工具不可用。failed 和 blocked 都停止后续 ticket,blocked 不得报告为 passed,也不得自动重试、reset、rollback、stash、删除日志或覆盖用户改动。
执行步骤
-
建立启动基线:确认工具和 session 存在,在主窗口记录真实 pane、window、Git 工作区和暂存区,使用 tmux -V、tmux has-session、tmux display-message、tmux list-windows、git status、git diff --cached 等命令。把启动时所有 modified、untracked、staged 路径加入保护基线并保存内容/hash,coverage、lock 文件、调度状态和用户声明的 protectedPaths 也加入保护边界。若 ticket 候选范围与基线改动重叠,先阻塞。
-
确认候选计划并探测 worker:等待用户一次性明确确认后,按固定顺序探测 codebuddy、codebuddy-code、cbc、claude,claude 是唯一允许的 fallback,两类 CLI 都必须使用 --permission-mode bypassPermissions,不接受 manifest 中的任意 agent 命令,也不能回退到 Codex 或其他工具;同时确认目标 agent 会话可使用 /implement。四个 CLI 都不存在、tmux/session 不可用或 /implement 不可用,都必须在 window 创建前阻塞。
-
创建当前 ticket:按计划顺序选取第一个尚未独立核验为 done 的 ticket,确认依赖均已完成,只创建一个新 window,使用 tmux new-window 加 agent_command --permission-mode bypassPermissions,立即保存真实 window_id、pane_id。首次发送完整自包含 prompt 必须用 literal 输入后 Enter;prompt 需包含当前 ticket、tracker、allowedPaths、protectedPaths、verify、maxRepairRounds、项目约束、mainPane 和终态协议,并明确要求只处理当前 ticket、显式调用 /implement、完成后只发送一次终态消息、工具不可用标记 TICKET_BLOCKED、代码失败标记 TICKET_FAILED、终态通过 tmux send-keys 发往 mainPane。忙碌会话收到追加 prompt 时先 literal 输入再发送 Tab 排队,不要用 Enter 打断。
-
接收唯一终态消息:worker 完成后向 mainPane 发送一行 JSON,字段包括 event(TICKET_DONE/TICKET_FAILED/TICKET_BLOCKED)、status、ticket、commit、changedFiles、verification(command/result/evidence)、evidence、summary。主窗口在预期终态到达后只用一次 capture-pane 确认单行消息已出现,只解析匹配的终态 JSON,不把持续 pane 输出带回主上下文,不轮询中间输出。终态缺失、JSON 无法解析、ticket id 不匹配、字段缺失或 worker 异常退出,均为 TICKET_BLOCKED 并保留当前 window 和证据,不要把沉默视为成功。
-
独立核验:收到 TICKET_DONE 也不能直接解锁下一个 ticket。主窗口独立执行 git status、git diff --cached、git show --stat、git diff-tree 等,逐项确认 commit 存在且文件全部位于 allowedPaths;基线路径、protected paths、coverage、lock 和调度状态没有进入 staging 或 commit;changedFiles 与实际文件一致;tracker 状态与真实结果一致但不自动修改 tracker;每条 verification 的结果和 evidence 真实存在且可复核。任何一项不通过都不能标记 done,按原因分类为 TICKET_FAILED 或 TICKET_BLOCKED,保留 window 和证据并停止链路。
-
清理并推进:只有独立核验全部通过才用 tmux kill-window 关闭本次创建的 window,只操作本次运行记录的真实 window_id,保留启动前存在的所有窗口,然后启动下一个 pending ticket。失败或阻塞的 window 不关闭。
-
恢复和整组终态:恢复时重新建立 Git 基线并重新生成/确认计划,已独立核验的 done ticket 直接跳过,failed 或 blocked 只有用户明确批准重试才重置为 pending,不自动重放或循环重试。最终只输出 ticket 状态、commit、验证结论和 evidence。全部 ticket 都经独立核验为 done 才报告整体完成;存在 failed 或 blocked 时报告停止点、原因、保留的 window 和用户需要批准的恢复动作。
验证方式
发布或修改本 skill 后,优先使用可丢弃的 tmux fixture 和 fake CodeBuddy Code/Claude Code CLI,记录 window 创建、首次 Enter、忙碌会话 Tab 排队、终态消息到达、独立核验和清理。fixture 至少验证:CodeBuddy 检测优先级、Claude fallback、两者不可用时创建 window 前 blocked;map/spec 默认顺序、显式顺序冲突的一次确认门以及确认前没有 worker window;两个无依赖 ticket 仍严格串行且 worker prompt 明确调用 /implement;缺失/损坏终态、TICKET_FAILED、TICKET_BLOCKED 会停止链路并保留 window;TICKET_DONE 只有在 commit、文件范围、staging、基线保护、verification 和 evidence 全部独立通过后才启动下一个 ticket;成功时只关闭本次创建的 window,恢复时跳过已核验 ticket 并要求用户明确批准重试失败/阻塞 ticket。如果没有可用的真实 tmux fixture,使用确定性的命令转录测试覆盖同一组可观察状态转换;在未运行真实 fixture 前,不得声称真实 tmux 运行时已通过。