--- name: erp-module-start description: 启动/恢复模块循环。按 docs/02 § 二 REQ 清单定位当前模块及其 REQ 序列,确保处于模块分支,扫描 docs/superpowers/reviews/ 计算已完成 REQ,驱动第一个未完成 REQ 的功能循环;全部完成则调用 erp-local-test-gate。幂等可重入。 user-invocable: false allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout *) Bash(git rev-parse *) Bash(curl *) Bash(jq *) Bash(mkdir -p .tmp) Bash(rm -f .tmp/*) --- **所有输出必须使用中文。** # erp-module-start ## 执行步骤 ### 步骤 1:按 `docs/02 § 二` REQ 序 + MR state 定位当前模块 + 本模块 REQ 列表 与 `erp-coding-start` 步骤 3 同构(完成判定以 `MR:` 字段 + GitLab API `state` 为准;curl 调用,凭据读 `.env.local` 的 `GITLAB_API_URL` / `GITLAB_TOKEN` / `GITLAB_PROJECT_ID`): - 用 `Read` 读取 `docs/02-开发计划.md`,用 `Grep`(pattern `^\|\s*[0-9]+\s*\|\s*\*\*(REQ-[A-Z0-9]+-[0-9]+)\*\*\s*\|\s*(module_\w+)`)抽取 § 二 表格数据行,按行号升序得 `req_order[]`。 - 若 `req_order` 为空 → 打印"⚠️ docs/02 § 二 REQ 开发顺序清单为空或无法解析,请检查"并停止。 - 初始化 `module_merged[module_id → bool]` 空缓存。按序遍历 `req_order[]`: - `module_merged[module_id]` 已缓存为 `true` → 跳过本 REQ。 - `module_merged[module_id]` 已缓存为 `false` → `current_module = module_id`,结束遍历。 - 未缓存 → 读取 docs/08 § 二 该模块条目的 ` - MR:` 字段: - `MR: —` → `module_merged[module_id] = false`,`current_module = module_id`,结束遍历。 - `MR: !` → 先 `Bash`: `set -a; . ./.env.local; set +a`,然后**分步校验 HTTP + 返回条数 + state 枚举**(语义与 `erp-coding-start` 步骤 3 严格一致): ```bash mkdir -p .tmp HTTP_CODE=$(curl -sS -o .tmp/mr.json -w '%{http_code}' \ --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \ "${GITLAB_API_URL}/projects/${GITLAB_PROJECT_ID}/merge_requests?iid=") ``` 硬停条件(任一命中 → 打印与 `erp-coding-start` 同款诊断横幅后**停下**,不进入下游 skill): 1. `HTTP_CODE != 200` 2. `HTTP_CODE == 200` 但 `jq 'length' .tmp/mr.json != 1` 3. state 不在 `{merged, opened, closed}` 里 通过后按 state 分派: - `merged` → 缓存 `true`,跳过本 REQ - `opened` / `closed` → 缓存 `false`,`current_module = module_id`,结束遍历 - **抽取本模块 REQ 序列 `req_list[]`**:从 `req_order[]` 取出所有 `module_id == current_module` 的项,按原序组成(同模块 REQ 必须连续,见 A5 约束)。 - 用 `Read` 读取 docs/08 § 二 该模块行 + 后续缩进行,提取 `module_name` / `depends_on`(REQ 列表以 docs/02 为准,不再读取 docs/08)。 ### 步骤 2:所有模块已完成短路 如果 `req_order[]` 全部遍历完 `current_module` 仍未赋值(即所有模块都 merged)→ 打印"所有模块已完成"摘要并停止。 ### 步骤 3:确保处于模块分支 - `target_branch = module-`(例 `module-module_sys`)。 - 用 `Bash` 执行 `git branch --show-current` 得 `current_branch`。 - `current_branch == target_branch` → 继续步骤 4。 - 否则用 `Bash` 执行 `git rev-parse --verify 2>/dev/null`: - 存在 → `git checkout ` - 不存在 → `git checkout -b ` - 若当前工作区有未提交改动且 checkout 失败 → 打印错误并停止(请用户手工处理 dirty state)。 ### 步骤 4:初始化跨模块日志(幂等) `docs/superpowers/module-reports/-cross-module.md` — 不存在则从 `${CLAUDE_SKILL_DIR}/templates/cross-module-log-template.md` 创建。 ### 步骤 5:计算已完成 REQ 集合 `done_reqs[]`(幂等断点恢复关键) - 对 `req_list[]` 每个 `req_id`,用 `Glob` 查 `docs/superpowers/reviews/*-.md`。 - 命中后用 `Grep`(pattern `^verdict:\s*approve`,`-i` 不敏感)检查首部 verdict。 - 两者都命中 → 加入 `done_reqs[]`。 ### 步骤 6:渲染并打印模块横幅 `Read ${CLAUDE_SKILL_DIR}/templates/module-start-banner-template.md`,填充槽位;`reqs[]` 每项的 `status` 字段根据 `done_reqs[]` 填 `x`(已完成)或空格(未完成)。 ### 步骤 7:推进主循环 - 从 `req_list[]` 取第一个不在 `done_reqs[]` 中的 REQ 作为 `next_req`。 - **没有 `next_req`**(全部完成)→ 调用 `Skill(erp-local-test-gate)` 进入模块闸门。 - **有 `next_req`** → 调用 `Skill(erp-feature-brainstorm)` 启动该 REQ 的功能循环。功能循环链(brainstorm → plan → tdd → verify → review)完成后,`erp-feature-review` 在 `verdict=approve` 分支会回调 `Skill(erp-module-start)` —— 再次进入本 skill 时,步骤 5 会把刚通过的 REQ 加入 `done_reqs[]`,步骤 7 自动取下一 REQ,形成可重入推进。 - 任何中断(红旗 / 测试持续失败 / review 5 轮仍 request-changes)→ 停止本模块,不要静默跳下一 REQ。 ## 参考 - `docs/02-开发计划.md § 二 开发顺序清单`(分发权威) - `docs/08-模块任务管理.md § 二`(模块元数据,含 `MR:` 字段;完成判定以 MR state 为准) - `docs/superpowers/reviews/*.md`(REQ 级进度事实——verdict=approve 即完成) - `${CLAUDE_SKILL_DIR}/templates/module-start-banner-template.md` - `${CLAUDE_SKILL_DIR}/templates/cross-module-log-template.md` - 下游:`erp-feature-*`、`erp-local-test-gate`