Commit 9e8db6d8d15bb2b1df65f96c92c62c21107ef2b5
1 parent
bbc8907e
feat(hooks): Stop 钩子自动续跑编码流程 + 去除 A 类人工停点
为实现「coding 阶段后端+前端连跑、无需手敲 continue」: - 新增 Stop 钩子 auto-continue.sh:回合中途结束自动续跑;命中 [ERP-HALT] 终止标记或连续空转上限/transcript 无增长时才放行停下, 自包含防循环(PostToolUse reset-stall-counter.sh 辅助清零)。 - 给所有真终止/硬护栏停点打 [ERP-HALT]:coding-start / test-gate / feature-tdd / fe-feature-tdd / module-start / module-report / frontend-start / interrupt-check / db-init / downstream-gen。 审阅停(scope-lock D、db-design-gen E)不打标记 → 钩子自动跨过。 - 删 A 类确认弹窗:scope-lock 技术栈检查、skeleton-gen .env 核对 → 自动放行。 - feature/fe-feature 的 spec/plan 覆盖确认 → 直接覆盖(CC 内部产物)。 注:钩子在会话启动时加载,已运行的会话需重启才生效。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Showing
19 changed files
with
134 additions
and
51 deletions
hooks/hooks.json
| @@ -6,6 +6,19 @@ | @@ -6,6 +6,19 @@ | ||
| 6 | "hooks": [ | 6 | "hooks": [ |
| 7 | { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/scripts/log-cross-module.sh" } | 7 | { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/scripts/log-cross-module.sh" } |
| 8 | ] | 8 | ] |
| 9 | + }, | ||
| 10 | + { | ||
| 11 | + "matcher": "", | ||
| 12 | + "hooks": [ | ||
| 13 | + { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/scripts/reset-stall-counter.sh" } | ||
| 14 | + ] | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "Stop": [ | ||
| 18 | + { | ||
| 19 | + "hooks": [ | ||
| 20 | + { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/scripts/auto-continue.sh" } | ||
| 21 | + ] | ||
| 9 | } | 22 | } |
| 10 | ] | 23 | ] |
| 11 | } | 24 | } |
hooks/scripts/auto-continue.sh
0 → 100755
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# Stop 钩子:让 ERP workflow 在回合中途结束时自动续跑,除非命中「终止标记」或「防循环上限」。 | ||
| 3 | +# | ||
| 4 | +# 设计: | ||
| 5 | +# 1. 终止标记 [ERP-HALT] —— 终止/硬护栏 skill(coding-start 全部完成、test-gate 红、 | ||
| 6 | +# feature-tdd 路径护栏、interrupt-check 中断)会打印它。出现即放行停下。 | ||
| 7 | +# 2. 防循环 —— 连续「无工具调用」的空转停止累加计数;达到上限放行停下。 | ||
| 8 | +# 正常推进时由 PostToolUse 的 reset-stall-counter.sh 清零,故真流程不受限。 | ||
| 9 | +# 3. 否则 —— block 并喂一句「继续推进」指令,用户无需手敲 continue。 | ||
| 10 | +set -u | ||
| 11 | + | ||
| 12 | +INPUT="$(cat)" | ||
| 13 | + | ||
| 14 | +SENTINEL='[ERP-HALT]' | ||
| 15 | +MAX_STALL=8 | ||
| 16 | + | ||
| 17 | +# —— 从 stdin JSON 取字段(不依赖 jq)—— | ||
| 18 | +get_str() { | ||
| 19 | + printf '%s' "$INPUT" \ | ||
| 20 | + | sed -n "s/.*\"$1\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" \ | ||
| 21 | + | head -n1 | ||
| 22 | +} | ||
| 23 | +TRANSCRIPT="$(get_str transcript_path)" | ||
| 24 | +# 反转义 Windows 路径里的 \\ 与 \/ | ||
| 25 | +TRANSCRIPT="${TRANSCRIPT//\\\\//}" | ||
| 26 | +TRANSCRIPT="${TRANSCRIPT//\\//}" | ||
| 27 | + | ||
| 28 | +# 计数器文件(按会话 transcript 路径派生 key,避免多会话互相干扰) | ||
| 29 | +KEY="$(printf '%s' "$TRANSCRIPT" | tr -cd 'A-Za-z0-9' | tail -c 40)" | ||
| 30 | +[ -z "$KEY" ] && KEY="default" | ||
| 31 | +CNT_FILE="${TMPDIR:-/tmp}/erp-autocont-$KEY" | ||
| 32 | +SIZE_FILE="${TMPDIR:-/tmp}/erp-autosize-$KEY" | ||
| 33 | + | ||
| 34 | +allow_stop() { rm -f "$CNT_FILE" "$SIZE_FILE" 2>/dev/null; exit 0; } | ||
| 35 | + | ||
| 36 | +# 1) 终止标记出现在最近的 transcript 尾部 → 放行停下 | ||
| 37 | +if [ -n "$TRANSCRIPT" ] && [ -f "$TRANSCRIPT" ]; then | ||
| 38 | + if tail -c 16000 "$TRANSCRIPT" 2>/dev/null | grep -qF "$SENTINEL"; then | ||
| 39 | + allow_stop | ||
| 40 | + fi | ||
| 41 | +fi | ||
| 42 | + | ||
| 43 | +# 2) 进展自复位(自包含,不依赖 PostToolUse):transcript 自上次停止以来显著增长 | ||
| 44 | +# → 说明这一轮做了实质工作(工具调用 + 结果),清零空转计数。 | ||
| 45 | +CUR_SIZE=0 | ||
| 46 | +[ -n "$TRANSCRIPT" ] && [ -f "$TRANSCRIPT" ] && CUR_SIZE="$(wc -c < "$TRANSCRIPT" 2>/dev/null | tr -d ' ')" | ||
| 47 | +case "$CUR_SIZE" in (''|*[!0-9]*) CUR_SIZE=0 ;; esac | ||
| 48 | +LAST_SIZE=0 | ||
| 49 | +[ -f "$SIZE_FILE" ] && LAST_SIZE="$(cat "$SIZE_FILE" 2>/dev/null || echo 0)" | ||
| 50 | +case "$LAST_SIZE" in (''|*[!0-9]*) LAST_SIZE=0 ;; esac | ||
| 51 | +echo "$CUR_SIZE" > "$SIZE_FILE" | ||
| 52 | +if [ $((CUR_SIZE - LAST_SIZE)) -gt 4000 ]; then | ||
| 53 | + rm -f "$CNT_FILE" 2>/dev/null | ||
| 54 | +fi | ||
| 55 | + | ||
| 56 | +# 3) 防循环:连续空转停止达到上限 → 放行停下 | ||
| 57 | +CNT=0 | ||
| 58 | +[ -f "$CNT_FILE" ] && CNT="$(cat "$CNT_FILE" 2>/dev/null || echo 0)" | ||
| 59 | +case "$CNT" in (''|*[!0-9]*) CNT=0 ;; esac | ||
| 60 | +if [ "$CNT" -ge "$MAX_STALL" ]; then | ||
| 61 | + allow_stop | ||
| 62 | +fi | ||
| 63 | +echo $((CNT + 1)) > "$CNT_FILE" | ||
| 64 | + | ||
| 65 | +# 3) 拦下停止 → 续跑 | ||
| 66 | +printf '%s' '{"decision":"block","reason":"继续推进 ERP workflow:直接执行流程的下一步——若当前 skill 已结束,立即用 Skill 工具调用对应派发器(A 阶段 plan-start / B 阶段 coding-start)或链中的下一个 skill;不要输出收尾叙述、不要停下等用户输入。只有打印了 [ERP-HALT] 的终止/硬护栏点才应停下。"}' | ||
| 67 | +exit 0 |
hooks/scripts/reset-stall-counter.sh
0 → 100755
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# PostToolUse 钩子:任何工具调用都视为「有进展」,清零 auto-continue.sh 的空转计数。 | ||
| 3 | +# 这样真正在推进的流程可无限续跑,只有「连续多次纯文字、零工具」的空转才会触发防循环上限。 | ||
| 4 | +set -u | ||
| 5 | + | ||
| 6 | +INPUT="$(cat)" | ||
| 7 | +TRANSCRIPT="$(printf '%s' "$INPUT" \ | ||
| 8 | + | sed -n 's/.*"transcript_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' \ | ||
| 9 | + | head -n1)" | ||
| 10 | +TRANSCRIPT="${TRANSCRIPT//\\\\//}" | ||
| 11 | +TRANSCRIPT="${TRANSCRIPT//\\//}" | ||
| 12 | + | ||
| 13 | +KEY="$(printf '%s' "$TRANSCRIPT" | tr -cd 'A-Za-z0-9' | tail -c 40)" | ||
| 14 | +[ -z "$KEY" ] && KEY="default" | ||
| 15 | +rm -f "${TMPDIR:-/tmp}/erp-autocont-$KEY" 2>/dev/null | ||
| 16 | +exit 0 |
skills/coding/fe-feature-brainstorm/SKILL.md
| @@ -55,7 +55,7 @@ allowed-tools: Read Write Skill AskUserQuestion Glob Grep | @@ -55,7 +55,7 @@ allowed-tools: Read Write Skill AskUserQuestion Glob Grep | ||
| 55 | - 消费的后端端点(与 docs/05 对齐,按本 FE 的 `associated_reqs[]` 过滤) | 55 | - 消费的后端端点(与 docs/05 对齐,按本 FE 的 `associated_reqs[]` 过滤) |
| 56 | - 业务规则前端复刻清单(逐条,每条标注:规则描述 / 触发时机 / 报错文案 / 来源 REQ) | 56 | - 业务规则前端复刻清单(逐条,每条标注:规则描述 / 触发时机 / 报错文案 / 来源 REQ) |
| 57 | - Design Tokens 引用清单(本 FE 用到的 `var(--color-*)` 名称) | 57 | - Design Tokens 引用清单(本 FE 用到的 `var(--color-*)` 名称) |
| 58 | - - 文件已存在 → 征求用户确认后覆盖 | 58 | + - 文件已存在 → 直接覆盖(spec 是 CC 内部产物,无需确认) |
| 59 | 59 | ||
| 60 | 4. **Spec 自审**(inline 修,无须用户等待): | 60 | 4. **Spec 自审**(inline 修,无须用户等待): |
| 61 | - 所有顶级节非空 | 61 | - 所有顶级节非空 |
skills/coding/fe-feature-plan/SKILL.md
| @@ -56,7 +56,7 @@ allowed-tools: Read Write Grep Skill AskUserQuestion | @@ -56,7 +56,7 @@ allowed-tools: Read Write Grep Skill AskUserQuestion | ||
| 56 | 56 | ||
| 57 | 5. **写 plan 到 `docs/superpowers/plans/<YYYY-MM-DD>-<fe_id>.md`**: | 57 | 5. **写 plan 到 `docs/superpowers/plans/<YYYY-MM-DD>-<fe_id>.md`**: |
| 58 | - 按 `${CLAUDE_SKILL_DIR}/templates/fe-feature-plan-template.md` 渲染 | 58 | - 按 `${CLAUDE_SKILL_DIR}/templates/fe-feature-plan-template.md` 渲染 |
| 59 | - - 文件已存在 → 征求用户确认后覆盖 | 59 | + - 文件已存在 → 直接覆盖(plan 是 CC 内部产物,无需确认) |
| 60 | 60 | ||
| 61 | 6. **Plan 自审**(inline 修,无须用户等待): | 61 | 6. **Plan 自审**(inline 修,无须用户等待): |
| 62 | - 每个任务必须含 `test_file::test_name`、`impl_file`、完成标准 | 62 | - 每个任务必须含 `test_file::test_name`、`impl_file`、完成标准 |
skills/coding/fe-feature-tdd/SKILL.md
| @@ -13,8 +13,8 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) | @@ -13,8 +13,8 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) | ||
| 13 | 13 | ||
| 14 | ## 路径护栏(前端阶段) | 14 | ## 路径护栏(前端阶段) |
| 15 | 15 | ||
| 16 | -- 任务的 `impl_file` 路径若**不以** `frontend/`(或项目实际前端根目录,从 `docs/09-项目目录结构.md § 前端目录结构` 取)开头 → 硬停并打印:`fe-feature-tdd 不允许写非前端文件:<impl_file>。前端阶段任务的 impl_file 必须落在前端目录下。` | ||
| 17 | -- 命中 `backend/` / `sql/` / `scripts/` → 同上硬停 | 16 | +- 任务的 `impl_file` 路径若**不以** `frontend/`(或项目实际前端根目录,从 `docs/09-项目目录结构.md § 前端目录结构` 取)开头 → 硬停并打印:`fe-feature-tdd 不允许写非前端文件:<impl_file>。前端阶段任务的 impl_file 必须落在前端目录下。 [ERP-HALT]` |
| 17 | +- 命中 `backend/` / `sql/` / `scripts/` → 同上硬停 `[ERP-HALT]` | ||
| 18 | - 不允许在主会话直接 `pnpm playwright` / `pnpm test` / `pnpm e2e`,必须派发子会话 | 18 | - 不允许在主会话直接 `pnpm playwright` / `pnpm test` / `pnpm e2e`,必须派发子会话 |
| 19 | 19 | ||
| 20 | ## 执行步骤 | 20 | ## 执行步骤 |
skills/coding/feature-brainstorm/SKILL.md
| @@ -43,7 +43,7 @@ allowed-tools: Read Write Skill AskUserQuestion Bash(mysql *) | @@ -43,7 +43,7 @@ allowed-tools: Read Write Skill AskUserQuestion Bash(mysql *) | ||
| 43 | 3. **写 spec 到 `docs/superpowers/specs/<YYYY-MM-DD>-<REQ-id>.md`**: | 43 | 3. **写 spec 到 `docs/superpowers/specs/<YYYY-MM-DD>-<REQ-id>.md`**: |
| 44 | - 按 `${CLAUDE_SKILL_DIR}/templates/feature-spec-template.md` 渲染 | 44 | - 按 `${CLAUDE_SKILL_DIR}/templates/feature-spec-template.md` 渲染 |
| 45 | - 覆盖:goal / 输入输出 / 业务规则 / 约束 / schema / API 引用 / acceptance criteria | 45 | - 覆盖:goal / 输入输出 / 业务规则 / 约束 / schema / API 引用 / acceptance criteria |
| 46 | - - 文件已存在 → 征求用户确认后覆盖 | 46 | + - 文件已存在 → 直接覆盖(spec 是 CC 内部产物,无需确认) |
| 47 | 47 | ||
| 48 | 4. **Spec 自审**(inline 修,无须用户等待): | 48 | 4. **Spec 自审**(inline 修,无须用户等待): |
| 49 | - **占位符扫描**:`TBD` / `TODO` / `【人工填写:】` / 含糊段 → 修(按"占位符规则"流程解决) | 49 | - **占位符扫描**:`TBD` / `TODO` / `【人工填写:】` / 含糊段 → 修(按"占位符规则"流程解决) |
skills/coding/feature-plan/SKILL.md
| @@ -56,7 +56,7 @@ allowed-tools: Read Write Grep Skill AskUserQuestion | @@ -56,7 +56,7 @@ allowed-tools: Read Write Grep Skill AskUserQuestion | ||
| 56 | 56 | ||
| 57 | 5. **写 plan 到 `docs/superpowers/plans/<YYYY-MM-DD>-<REQ-id>.md`**: | 57 | 5. **写 plan 到 `docs/superpowers/plans/<YYYY-MM-DD>-<REQ-id>.md`**: |
| 58 | - 按 `${CLAUDE_SKILL_DIR}/templates/feature-plan-template.md` 渲染 | 58 | - 按 `${CLAUDE_SKILL_DIR}/templates/feature-plan-template.md` 渲染 |
| 59 | - - 文件已存在 → 征求用户确认后覆盖 | 59 | + - 文件已存在 → 直接覆盖(plan 是 CC 内部产物,无需确认) |
| 60 | 60 | ||
| 61 | 6. **Plan 自审**(inline 修,无须用户等待): | 61 | 6. **Plan 自审**(inline 修,无须用户等待): |
| 62 | - **占位符扫描**:按"占位符规则"清单逐项 grep;命中即修 | 62 | - **占位符扫描**:按"占位符规则"清单逐项 grep;命中即修 |
skills/coding/feature-tdd/SKILL.md
| @@ -35,7 +35,7 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) | @@ -35,7 +35,7 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) | ||
| 35 | - **绝不**在主会话直接跑 `./gradlew test` / `pnpm test` / `scripts/test.sh`,必须通过子会话 | 35 | - **绝不**在主会话直接跑 `./gradlew test` / `pnpm test` / `scripts/test.sh`,必须通过子会话 |
| 36 | - **绝不**在主会话直接 `mysql -e "ALTER ..."`;业务 schema 改动一律走 `sql/migrations/V*.sql` 文件(只读查询 / 临时调试除外) | 36 | - **绝不**在主会话直接 `mysql -e "ALTER ..."`;业务 schema 改动一律走 `sql/migrations/V*.sql` 文件(只读查询 / 临时调试除外) |
| 37 | - 每次 commit 必须含 `REQ-XXX-NNN` 标签;不混合无关改动到同一 commit | 37 | - 每次 commit 必须含 `REQ-XXX-NNN` 标签;不混合无关改动到同一 commit |
| 38 | -- **后端阶段路径硬护栏**:任务表里的 `impl_file` 路径以 `frontend/` 开头 → 硬停并打印 `feature-tdd 后端阶段不允许写前端代码:<impl_file>。请检查 plan 任务定义;UI 推迟到前端阶段(fe-feature-*)`,不再继续 TDD 循环 | 38 | +- **后端阶段路径硬护栏**:任务表里的 `impl_file` 路径以 `frontend/` 开头 → 硬停并打印 `feature-tdd 后端阶段不允许写前端代码:<impl_file>。请检查 plan 任务定义;UI 推迟到前端阶段(fe-feature-*) [ERP-HALT]`,不再继续 TDD 循环 |
| 39 | 39 | ||
| 40 | ## 参考 | 40 | ## 参考 |
| 41 | 41 |
skills/coding/frontend-start/SKILL.md
| @@ -19,7 +19,7 @@ allowed-tools: Read Write Edit Skill Glob Grep AskUserQuestion Bash(git branch * | @@ -19,7 +19,7 @@ allowed-tools: Read Write Edit Skill Glob Grep AskUserQuestion Bash(git branch * | ||
| 19 | 19 | ||
| 20 | 读 docs/08 § 三 "功能:" 项: | 20 | 读 docs/08 § 三 "功能:" 项: |
| 21 | 21 | ||
| 22 | -- 已有 `- [ ] FE-NN ...` 或 `- [x] FE-NN ...` 行 → **加载**:逐行解析得 `fe_list[]`,每项 `{ fe_id, name, status, associated_reqs[], associated_prototypes[] }`。行格式不符 → 硬停打印问题行 | 22 | +- 已有 `- [ ] FE-NN ...` 或 `- [x] FE-NN ...` 行 → **加载**:逐行解析得 `fe_list[]`,每项 `{ fe_id, name, status, associated_reqs[], associated_prototypes[] }`。行格式不符 → 硬停打印问题行 `[ERP-HALT]` |
| 23 | - 仅有 HTML 注释占位(无 FE bullet)→ **推导**: | 23 | - 仅有 HTML 注释占位(无 FE bullet)→ **推导**: |
| 24 | 1. 读 `prototype/**/*.html` + `docs/01-需求清单/**/*.md` + `docs/05-API接口契约.md` | 24 | 1. 读 `prototype/**/*.html` + `docs/01-需求清单/**/*.md` + `docs/05-API接口契约.md` |
| 25 | 2. 以**业务功能**为单位拆分(同流程多屏可合 1 FE;一 HTML 多功能可拆多 FE;无 UI 的 REQ 不产生 FE)。每个 FE:`{ fe_id: FE-NN, name, associated_reqs[], associated_prototypes[] }`,prototype 路径可带 anchor 区分文件内多区域 | 25 | 2. 以**业务功能**为单位拆分(同流程多屏可合 1 FE;一 HTML 多功能可拆多 FE;无 UI 的 REQ 不产生 FE)。每个 FE:`{ fe_id: FE-NN, name, associated_reqs[], associated_prototypes[] }`,prototype 路径可带 anchor 区分文件内多区域 |
| @@ -35,12 +35,12 @@ allowed-tools: Read Write Edit Skill Glob Grep AskUserQuestion Bash(git branch * | @@ -35,12 +35,12 @@ allowed-tools: Read Write Edit Skill Glob Grep AskUserQuestion Bash(git branch * | ||
| 35 | 35 | ||
| 36 | 读 § 三 `整体里程碑:` 字段并 `git tag -l 'milestone/frontend-phase'` 校验: | 36 | 读 § 三 `整体里程碑:` 字段并 `git tag -l 'milestone/frontend-phase'` 校验: |
| 37 | 37 | ||
| 38 | -- 字段为 `milestone/frontend-phase` 且 tag 存在 → 打印"前端阶段已完成"并停(冗余保护,正常由 coding-start 拦掉) | 38 | +- 字段为 `milestone/frontend-phase` 且 tag 存在 → 打印"前端阶段已完成 `[ERP-HALT]`"并停(冗余保护,正常由 coding-start 拦掉) |
| 39 | - 否则(`—` 或 tag 不存在)→ 进入步骤 4 | 39 | - 否则(`—` 或 tag 不存在)→ 进入步骤 4 |
| 40 | 40 | ||
| 41 | ### 步骤 4:切到 frontend-phase 分支 | 41 | ### 步骤 4:切到 frontend-phase 分支 |
| 42 | 42 | ||
| 43 | -目标分支 `frontend-phase`,分支管理逻辑同 module-start 步骤 3:已在 → 继续;存在 → checkout;不存在 → 切本地默认分支后 `git checkout -b frontend-phase`。任何错误硬停 + 诊断,不自动 stash / 覆盖。 | 43 | +目标分支 `frontend-phase`,分支管理逻辑同 module-start 步骤 3:已在 → 继续;存在 → checkout;不存在 → 切本地默认分支后 `git checkout -b frontend-phase`。任何错误硬停 + 诊断,不自动 stash / 覆盖。`[ERP-HALT]` |
| 44 | 44 | ||
| 45 | ### 步骤 5:识别已完成的 FE | 45 | ### 步骤 5:识别已完成的 FE |
| 46 | 46 |
skills/coding/module-report/SKILL.md
| @@ -15,7 +15,7 @@ allowed-tools: Read Write Glob Grep Skill Bash(git diff *) Bash(git log *) Bash( | @@ -15,7 +15,7 @@ allowed-tools: Read Write Glob Grep Skill Bash(git diff *) Bash(git log *) Bash( | ||
| 15 | 15 | ||
| 16 | - `module-<id>` → `phase=backend`,`phase_id=<id>` | 16 | - `module-<id>` → `phase=backend`,`phase_id=<id>` |
| 17 | - `frontend-phase` → `phase=frontend`,`phase_id=frontend-phase` | 17 | - `frontend-phase` → `phase=frontend`,`phase_id=frontend-phase` |
| 18 | -- 其它分支 → 硬停 | 18 | +- 其它分支 → 硬停 `[ERP-HALT]` |
| 19 | 19 | ||
| 20 | ## 执行步骤 | 20 | ## 执行步骤 |
| 21 | 21 |
skills/coding/module-start/SKILL.md
| @@ -26,7 +26,7 @@ allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout * | @@ -26,7 +26,7 @@ allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout * | ||
| 26 | 约束: | 26 | 约束: |
| 27 | 27 | ||
| 28 | - 模块完成 = `docs/08 § 二` 该模块 `里程碑:` 字段为 `milestone/<module_id>` 且 `git tag -l` 能查到该 tag;二者任一缺失即视为未完成 | 28 | - 模块完成 = `docs/08 § 二` 该模块 `里程碑:` 字段为 `milestone/<module_id>` 且 `git tag -l` 能查到该 tag;二者任一缺失即视为未完成 |
| 29 | -- 任何文件读取或解析失败 → 打印错误并停止 | 29 | +- 任何文件读取或解析失败 → 打印错误并停止 `[ERP-HALT]` |
| 30 | 30 | ||
| 31 | ### 步骤 2:找不到未完成后端模块的处理 | 31 | ### 步骤 2:找不到未完成后端模块的处理 |
| 32 | 32 | ||
| @@ -43,7 +43,7 @@ allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout * | @@ -43,7 +43,7 @@ allowed-tools: Read Write Skill Glob Grep Bash(git branch *) Bash(git checkout * | ||
| 43 | - 该分支已存在但当前不在 → checkout 过去 | 43 | - 该分支已存在但当前不在 → checkout 过去 |
| 44 | - 该分支不存在 → 先把工作树切到本地默认分支(main 或 master,已由 milestone-tag 的本地 merge 累积所有已完成模块),作为新分支的干净 base,再 `git checkout -b` 创建模块分支 | 44 | - 该分支不存在 → 先把工作树切到本地默认分支(main 或 master,已由 milestone-tag 的本地 merge 累积所有已完成模块),作为新分支的干净 base,再 `git checkout -b` 创建模块分支 |
| 45 | 45 | ||
| 46 | -任何错误(定位不到默认分支 / 切换前工作树脏 / checkout 失败)一律停下并打印诊断信息,不自动 stash、不强制覆盖。 | 46 | +任何错误(定位不到默认分支 / 切换前工作树脏 / checkout 失败)一律停下并打印诊断信息,不自动 stash、不强制覆盖。`[ERP-HALT]` |
| 47 | 47 | ||
| 48 | ### 步骤 4:计算已完成 REQ 集合 `done_reqs[]` | 48 | ### 步骤 4:计算已完成 REQ 集合 `done_reqs[]` |
| 49 | 49 |
skills/coding/test-gate/SKILL.md
| @@ -24,7 +24,7 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *) Bash(gi | @@ -24,7 +24,7 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *) Bash(gi | ||
| 24 | 24 | ||
| 25 | - `module-<id>` → `phase=backend`,`phase_id=<id>`,`command=./scripts/test.sh` | 25 | - `module-<id>` → `phase=backend`,`phase_id=<id>`,`command=./scripts/test.sh` |
| 26 | - `frontend-phase` → `phase=frontend`,`phase_id=frontend-phase`;命令从 `docs/04-技术规范.md § 零 frontend.test_command` / `frontend.e2e_command` 拼接(缺失则 `pnpm test:ci && pnpm e2e:ci`) | 26 | - `frontend-phase` → `phase=frontend`,`phase_id=frontend-phase`;命令从 `docs/04-技术规范.md § 零 frontend.test_command` / `frontend.e2e_command` 拼接(缺失则 `pnpm test:ci && pnpm e2e:ci`) |
| 27 | -- 其它分支 → 硬停打印 `test-gate 仅在 module-* 或 frontend-phase 分支可调用,当前 <branch>` | 27 | +- 其它分支 → 硬停打印 `test-gate 仅在 module-* 或 frontend-phase 分支可调用,当前 <branch> [ERP-HALT]` |
| 28 | 28 | ||
| 29 | 1. 派发 Agent 子会话(general-purpose)运行上述 `command`,子会话只返回结构化 JSON(不输出描述文字): | 29 | 1. 派发 Agent 子会话(general-purpose)运行上述 `command`,子会话只返回结构化 JSON(不输出描述文字): |
| 30 | ```json | 30 | ```json |
| @@ -47,7 +47,7 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *) Bash(gi | @@ -47,7 +47,7 @@ allowed-tools: Read Write Skill Agent Bash(git add *) Bash(git commit *) Bash(gi | ||
| 47 | 47 | ||
| 48 | ``` | 48 | ``` |
| 49 | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | 49 | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
| 50 | - [test-gate] ⚠️ 未通过 (phase=<phase>) | 50 | + [test-gate] ⚠️ 未通过 (phase=<phase>) [ERP-HALT] |
| 51 | 失败清单: <子会话 JSON 的 failed 摘要> | 51 | 失败清单: <子会话 JSON 的 failed 摘要> |
| 52 | 详细证据: docs/superpowers/module-reports/<phase_id>-test-gate.md | 52 | 详细证据: docs/superpowers/module-reports/<phase_id>-test-gate.md |
| 53 | 53 |
skills/crosscut/coding-start/SKILL.md
| @@ -22,13 +22,13 @@ cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/coding-start/banners/flow-overview.tx | @@ -22,13 +22,13 @@ cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/coding-start/banners/flow-overview.tx | ||
| 22 | ### 步骤 1:确认 docs/08 存在 | 22 | ### 步骤 1:确认 docs/08 存在 |
| 23 | 23 | ||
| 24 | 检查 `docs/08-模块任务管理.md` 存在。 | 24 | 检查 `docs/08-模块任务管理.md` 存在。 |
| 25 | -- 不存在 → 打印"⚠️ 项目尚未初始化,请先运行 `/erp-workflow:plan-start`"并停下。 | 25 | +- 不存在 → 打印"⚠️ 项目尚未初始化,请先运行 `/erp-workflow:plan-start` `[ERP-HALT]`"并停下。 |
| 26 | 26 | ||
| 27 | ### 步骤 2:Plan 完成性检查 | 27 | ### 步骤 2:Plan 完成性检查 |
| 28 | 28 | ||
| 29 | 读取 `docs/08-模块任务管理.md § 一`,判断 A0~A5 是否全部勾选(含子项)。 | 29 | 读取 `docs/08-模块任务管理.md § 一`,判断 A0~A5 是否全部勾选(含子项)。 |
| 30 | 30 | ||
| 31 | -- 任一未勾选 → 提示用户先运行 `/erp-workflow:plan-start` 完成 A 阶段,并停下 | 31 | +- 任一未勾选 → 提示用户先运行 `/erp-workflow:plan-start` 完成 A 阶段并打印 `[ERP-HALT]`,停下 |
| 32 | - 全部勾选 → 进入步骤 3 | 32 | - 全部勾选 → 进入步骤 3 |
| 33 | 33 | ||
| 34 | ### 步骤 3:后端完成性检查 + 派发 | 34 | ### 步骤 3:后端完成性检查 + 派发 |
| @@ -43,7 +43,7 @@ cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/coding-start/banners/flow-overview.tx | @@ -43,7 +43,7 @@ cat "${CLAUDE_PLUGIN_ROOT}/skills/crosscut/coding-start/banners/flow-overview.tx | ||
| 43 | 43 | ||
| 44 | 读 `docs/08 § 三 整体里程碑:` 字段(并用 `git tag -l 'milestone/frontend-phase'` 校验): | 44 | 读 `docs/08 § 三 整体里程碑:` 字段(并用 `git tag -l 'milestone/frontend-phase'` 校验): |
| 45 | 45 | ||
| 46 | -- **`整体里程碑: milestone/frontend-phase` 且 tag 存在** → 前端已完成,打印 `所有阶段已完成(后端模块 + 前端阶段里程碑均已标记)`,结束本 skill。 | 46 | +- **`整体里程碑: milestone/frontend-phase` 且 tag 存在** → 前端已完成,打印 `所有阶段已完成(后端模块 + 前端阶段里程碑均已标记) [ERP-HALT]`,结束本 skill。 |
| 47 | 47 | ||
| 48 | - **`整体里程碑: —` 或 tag 不存在** → 前端未完成,打印 `[coding-start] 后端已完成、前端未完成 → 派发 frontend-start(写前端)`,立即用 Skill 工具调用 frontend-start(直接调用,**不要**先输出"已完成 / 接下来 / 请检查 / 等你确认"之类桥接叙述——会被解读为 turn 结束信号、害用户手敲 continue),本 skill 结束。 | 48 | - **`整体里程碑: —` 或 tag 不存在** → 前端未完成,打印 `[coding-start] 后端已完成、前端未完成 → 派发 frontend-start(写前端)`,立即用 Skill 工具调用 frontend-start(直接调用,**不要**先输出"已完成 / 接下来 / 请检查 / 等你确认"之类桥接叙述——会被解读为 turn 结束信号、害用户手敲 continue),本 skill 结束。 |
| 49 | 49 |
skills/crosscut/interrupt-check/SKILL.md
| @@ -30,7 +30,7 @@ allowed-tools: Read Write Bash(mysql *) | @@ -30,7 +30,7 @@ allowed-tools: Read Write Bash(mysql *) | ||
| 30 | 30 | ||
| 31 | 1. 逐项核对 3 个中断条件。**全部未触发** → 输出 `interrupt-check: 通过`,结束。 | 31 | 1. 逐项核对 3 个中断条件。**全部未触发** → 输出 `interrupt-check: 通过`,结束。 |
| 32 | 2. **触发任一** → 按 `${CLAUDE_SKILL_DIR}/templates/interrupt-block-template.md` 渲染 Blocker 块,追加到当前 plan 文件(典型路径 `docs/superpowers/plans/<YYYY-MM-DD>-<REQ-id>.md`;test-gate 场景下追加到本模块任一已有 plan 文件)。 | 32 | 2. **触发任一** → 按 `${CLAUDE_SKILL_DIR}/templates/interrupt-block-template.md` 渲染 Blocker 块,追加到当前 plan 文件(典型路径 `docs/superpowers/plans/<YYYY-MM-DD>-<REQ-id>.md`;test-gate 场景下追加到本模块任一已有 plan 文件)。 |
| 33 | -3. 向会话打印一句话摘要 + 指向 plan 文件路径,**停下**。 | 33 | +3. 向会话打印一句话摘要 + 指向 plan 文件路径 + `[ERP-HALT]`,**停下**。 |
| 34 | 34 | ||
| 35 | ## 参考 | 35 | ## 参考 |
| 36 | 36 |
skills/plan/db-init/SKILL.md
| @@ -66,8 +66,8 @@ bash "${CLAUDE_SKILL_DIR}/scripts/validate.sh" \ | @@ -66,8 +66,8 @@ bash "${CLAUDE_SKILL_DIR}/scripts/validate.sh" \ | ||
| 66 | - `1` → **自主修正循环**(最多 3 轮,docs/03 是 SSoT 不动): | 66 | - `1` → **自主修正循环**(最多 3 轮,docs/03 是 SSoT 不动): |
| 67 | 1. 解析 stderr 差异清单,修正 V1.sql | 67 | 1. 解析 stderr 差异清单,修正 V1.sql |
| 68 | 2. 重跑 validate.sh | 68 | 2. 重跑 validate.sh |
| 69 | - 3. 退出 0 → 进入 B;退出 1 且本轮 < 3 → 回步骤 1;本轮 ≥ 3 仍失败 → 停下,打印最终残留差异 + 已尝试的 3 轮修正摘要,让用户介入 | ||
| 70 | -- `2` → 用法错(V1 / docs 路径找不到),打印路径并停下 | 69 | + 3. 退出 0 → 进入 B;退出 1 且本轮 < 3 → 回步骤 1;本轮 ≥ 3 仍失败 → 停下,打印最终残留差异 + 已尝试的 3 轮修正摘要,让用户介入 `[ERP-HALT]` |
| 70 | +- `2` → 用法错(V1 / docs 路径找不到),打印路径并停下 `[ERP-HALT]` | ||
| 71 | 71 | ||
| 72 | 完成后(V1 写入并通过 validate.sh 校验),用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: | 72 | 完成后(V1 写入并通过 validate.sh 校验),用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: |
| 73 | - ` - [ ] sql/migrations/V1__initial_schema.sql 已生成` | 73 | - ` - [ ] sql/migrations/V1__initial_schema.sql 已生成` |
| @@ -77,7 +77,7 @@ bash "${CLAUDE_SKILL_DIR}/scripts/validate.sh" \ | @@ -77,7 +77,7 @@ bash "${CLAUDE_SKILL_DIR}/scripts/validate.sh" \ | ||
| 77 | 77 | ||
| 78 | #### B.1 检查 .env.local 凭据 | 78 | #### B.1 检查 .env.local 凭据 |
| 79 | 79 | ||
| 80 | -用 `Glob` 检查 `.env.local` 是否存在;不存在 → 提示用户重新运行 A2 `skeleton-gen` 重建并停下。 | 80 | +用 `Glob` 检查 `.env.local` 是否存在;不存在 → 提示用户重新运行 A2 `skeleton-gen` 重建并停下。`[ERP-HALT]` |
| 81 | 81 | ||
| 82 | 用 `Bash` 加载并校验 5 个必填字段非空: | 82 | 用 `Bash` 加载并校验 5 个必填字段非空: |
| 83 | 83 | ||
| @@ -89,7 +89,7 @@ for v in DB_HOST DB_PORT DB_USER DB_PASSWORD DB_SCHEMA; do | @@ -89,7 +89,7 @@ for v in DB_HOST DB_PORT DB_USER DB_PASSWORD DB_SCHEMA; do | ||
| 89 | done | 89 | done |
| 90 | ``` | 90 | ``` |
| 91 | 91 | ||
| 92 | -任一缺失 → 打印缺失字段名并停下,提示用户编辑 `.env.local` 后重跑。 | 92 | +任一缺失 → 打印缺失字段名并停下,提示用户编辑 `.env.local` 后重跑。`[ERP-HALT]` |
| 93 | 93 | ||
| 94 | #### B.2 验证 MySQL 连接 | 94 | #### B.2 验证 MySQL 连接 |
| 95 | 95 | ||
| @@ -99,7 +99,7 @@ mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" -e "SELECT 1;" | @@ -99,7 +99,7 @@ mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" -e "SELECT 1;" | ||
| 99 | ``` | 99 | ``` |
| 100 | 100 | ||
| 101 | - **成功** → 进入步骤 C | 101 | - **成功** → 进入步骤 C |
| 102 | -- **失败** → 打印具体错误(认证 / 主机不可达 / 端口拒接等),提示检查 `.env.local`,**停下**。 | 102 | +- **失败** → 打印具体错误(认证 / 主机不可达 / 端口拒接等),提示检查 `.env.local`,**停下**。`[ERP-HALT]` |
| 103 | 103 | ||
| 104 | 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: | 104 | 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: |
| 105 | - ` - [ ] .env.local 凭据已验证(mysql -e "SELECT 1" OK)` | 105 | - ` - [ ] .env.local 凭据已验证(mysql -e "SELECT 1" OK)` |
| @@ -120,7 +120,7 @@ mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" "$DB_SCHEMA" \ | @@ -120,7 +120,7 @@ mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASSWORD" "$DB_SCHEMA" \ | ||
| 120 | < sql/migrations/V1__initial_schema.sql | 120 | < sql/migrations/V1__initial_schema.sql |
| 121 | ``` | 121 | ``` |
| 122 | 122 | ||
| 123 | -非零退出 → 报错停下,打印 mysql stderr。 | 123 | +非零退出 → 报错停下,打印 mysql stderr。`[ERP-HALT]` |
| 124 | 124 | ||
| 125 | 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: | 125 | 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: |
| 126 | - ` - [ ] setup-test-db.sh 防护通过 + DROP+CREATE + apply V1 已执行` | 126 | - ` - [ ] setup-test-db.sh 防护通过 + DROP+CREATE + apply V1 已执行` |
| @@ -135,7 +135,7 @@ EXPECTED=$(grep -c '^## `' docs/03-数据库设计文档.md) | @@ -135,7 +135,7 @@ EXPECTED=$(grep -c '^## `' docs/03-数据库设计文档.md) | ||
| 135 | [ "$ACTUAL" = "$EXPECTED" ] || { echo "MISMATCH: actual=$ACTUAL expected=$EXPECTED"; exit 1; } | 135 | [ "$ACTUAL" = "$EXPECTED" ] || { echo "MISMATCH: actual=$ACTUAL expected=$EXPECTED"; exit 1; } |
| 136 | ``` | 136 | ``` |
| 137 | 137 | ||
| 138 | -行数不一致 → 报错停下;一致 → 进入步骤 D。 | 138 | +行数不一致 → 报错停下 `[ERP-HALT]`;一致 → 进入步骤 D。 |
| 139 | 139 | ||
| 140 | ### D. 勾选 docs/08 进度 + 进入 A5 | 140 | ### D. 勾选 docs/08 进度 + 进入 A5 |
| 141 | 141 |
skills/plan/downstream-gen/SKILL.md
| @@ -94,11 +94,11 @@ cp "${CLAUDE_SKILL_DIR}/templates/docs-10-header-template.md" docs/10-验收检æ | @@ -94,11 +94,11 @@ cp "${CLAUDE_SKILL_DIR}/templates/docs-10-header-template.md" docs/10-验收检æ | ||
| 94 | - **module_id 缺 docs/08 § 二** → 按æ¥éª¤ D è§„åˆ™æ¸²æŸ“è¯¥æ¨¡å— bulletï¼ˆå« REQ å项),按 `module_id` å—æ¯åºæ’å…¥æ£ç¡®ä½ç½® | 94 | - **module_id 缺 docs/08 § 二** → 按æ¥éª¤ D è§„åˆ™æ¸²æŸ“è¯¥æ¨¡å— bulletï¼ˆå« REQ å项),按 `module_id` å—æ¯åºæ’å…¥æ£ç¡®ä½ç½® |
| 95 | - **module_id 缺 docs/02 § 二** → é‡ç®—该模å—çš„ `req_order` 段(æ¥éª¤ A åæµç¨‹ï¼‰ï¼ŒæŒ‰æ‹“æ‰‘åºæ’å…¥ docs/02 § 二 | 95 | - **module_id 缺 docs/02 § 二** → é‡ç®—该模å—çš„ `req_order` 段(æ¥éª¤ A åæµç¨‹ï¼‰ï¼ŒæŒ‰æ‹“æ‰‘åºæ’å…¥ docs/02 § 二 |
| 96 | 96 | ||
| 97 | - ä¿®å¤åŽé‡è·‘检查;通过 → 进入 2ï¼›3 è½®ä»å¤±è´¥ → åœä¸‹ï¼Œæ‰“å°æœ€ç»ˆæ®‹ç•™å·®å¼‚ + å·²å°è¯•çš„ 3 è½®ä¿®å¤æ‘˜è¦è®©ç”¨æˆ·ä»‹å…¥ã€‚ | 97 | + ä¿®å¤åŽé‡è·‘检查;通过 → 进入 2ï¼›3 è½®ä»å¤±è´¥ → åœä¸‹ï¼Œæ‰“å°æœ€ç»ˆæ®‹ç•™å·®å¼‚ + å·²å°è¯•çš„ 3 è½®ä¿®å¤æ‘˜è¦è®©ç”¨æˆ·ä»‹å…¥ã€‚`[ERP-HALT]` |
| 98 | 98 | ||
| 99 | 2. **最终å ä½ç¬¦æ‰«æ**(覆盖 Plan 阶段全部产出): | 99 | 2. **最终å ä½ç¬¦æ‰«æ**(覆盖 Plan 阶段全部产出): |
| 100 | 100 | ||
| 101 | - a. **`TBD` → 自动补é½**:Grep æœç´¢ `TBD(A3 自动补)` å’Œ `TBD(A5 自动补)`。有命ä¸åˆ™å°±åœ°è¡¥å¡«ï¼ˆA3 残留 → 查 docs/03 å¡« `ä¾èµ–表`ï¼›A5 残留 → 查 docs/05 按 REQ-ID å¡« `ä¾èµ–接å£`ï¼‰ï¼Œå† Grep 确认 0 命ä¸ï¼›ä»æ®‹ç•™æŠ¥é”™åœä¸‹ã€‚ | 101 | + a. **`TBD` → 自动补é½**:Grep æœç´¢ `TBD(A3 自动补)` å’Œ `TBD(A5 自动补)`。有命ä¸åˆ™å°±åœ°è¡¥å¡«ï¼ˆA3 残留 → 查 docs/03 å¡« `ä¾èµ–表`ï¼›A5 残留 → 查 docs/05 按 REQ-ID å¡« `ä¾èµ–接å£`ï¼‰ï¼Œå† Grep 确认 0 命ä¸ï¼›ä»æ®‹ç•™æŠ¥é”™åœä¸‹ã€‚`[ERP-HALT]` |
| 102 | 102 | ||
| 103 | b. **`ã€äººå·¥å¡«å†™ï¼š...】` → QA 循环ç‰ç”¨æˆ·è¡¥**: | 103 | b. **`ã€äººå·¥å¡«å†™ï¼š...】` → QA 循环ç‰ç”¨æˆ·è¡¥**: |
| 104 | 104 |
skills/plan/scope-lock/SKILL.md
| @@ -47,7 +47,7 @@ cat "${CLAUDE_PLUGIN_ROOT}/skills/plan/scope-lock/banners/flow.txt" | @@ -47,7 +47,7 @@ cat "${CLAUDE_PLUGIN_ROOT}/skills/plan/scope-lock/banners/flow.txt" | ||
| 47 | 0 命中后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: | 47 | 0 命中后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: |
| 48 | - ` - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)` | 48 | - ` - [ ] 项目概述已填写(CLAUDE.md § 🎯 项目概述)` |
| 49 | 49 | ||
| 50 | -### B. 提示用户检查默认技术栈并等待 | 50 | +### B. 默认技术栈(自动,无停顿) |
| 51 | 51 | ||
| 52 | `docs/04-技术规范.md` 已由 A0 `project-init` 用模板复制(默认技术栈,见 `project-init/templates/docs-04-stack-template.md`)。本步骤让用户检查 / 调整 § 零。 | 52 | `docs/04-技术规范.md` 已由 A0 `project-init` 用模板复制(默认技术栈,见 `project-init/templates/docs-04-stack-template.md`)。本步骤让用户检查 / 调整 § 零。 |
| 53 | 53 | ||
| @@ -64,16 +64,11 @@ cat "${CLAUDE_PLUGIN_ROOT}/skills/plan/scope-lock/banners/flow.txt" | @@ -64,16 +64,11 @@ cat "${CLAUDE_PLUGIN_ROOT}/skills/plan/scope-lock/banners/flow.txt" | ||
| 64 | - 不需要的行直接删除(如纯后端项目删前端行) | 64 | - 不需要的行直接删除(如纯后端项目删前端行) |
| 65 | - 需要替换的技术直接改 | 65 | - 需要替换的技术直接改 |
| 66 | - 需要新增的条目直接加行 | 66 | - 需要新增的条目直接加行 |
| 67 | - 改完后回来选择「继续」。 | 67 | + (默认栈开箱即用;如需改,直接编辑该文件即可,流程不会在此等待。) |
| 68 | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | 68 | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
| 69 | ``` | 69 | ``` |
| 70 | 70 | ||
| 71 | -用 `AskUserQuestion` 询问: | ||
| 72 | -- **question**: `技术栈检查完毕了吗?` | ||
| 73 | - - 用户选择「继续」→ 进入步骤 C。 | ||
| 74 | - - 用户选择「有疑问想先沟通」→ 回答用户问题后,再次弹出同样的 QA。 | ||
| 75 | - | ||
| 76 | -完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: | 71 | +**不再弹窗等待。** 默认技术栈直接采用;若用户在本轮对话中已明确要求调整某项技术,就地用 `Edit` 改 docs/04 § 零,否则保持默认。随后用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选,并直接进入步骤 C: |
| 77 | - ` - [ ] 技术栈已确认(docs/04 § 零)` | 72 | - ` - [ ] 技术栈已确认(docs/04 § 零)` |
| 78 | 73 | ||
| 79 | ### C. 提示用户填写需求清单并等待 | 74 | ### C. 提示用户填写需求清单并等待 |
skills/plan/skeleton-gen/SKILL.md
| @@ -135,23 +135,15 @@ bash "${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh" "${CLAUDE_SKILL_DIR}/templ | @@ -135,23 +135,15 @@ bash "${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh" "${CLAUDE_SKILL_DIR}/templ | ||
| 135 | 135 | ||
| 136 | > `.env.local` 的 DB 连接核对**不在此处停**,统一放到 E.4 最终闸门——等所有产出(docs / scripts / .env.local / .gitignore)都初始化完成后再停一次,避免「一生成就停」。 | 136 | > `.env.local` 的 DB 连接核对**不在此处停**,统一放到 E.4 最终闸门——等所有产出(docs / scripts / .env.local / .gitignore)都初始化完成后再停一次,避免「一生成就停」。 |
| 137 | 137 | ||
| 138 | -#### E.4 验证 + QA 闸门(含 .env.local 连接核对) | 138 | +#### E.4 验证闸门(自动,无停顿) |
| 139 | 139 | ||
| 140 | -**这是 skeleton-gen 唯一的收尾停顿——所有产出(docs / scripts / .env.local / .gitignore)全部初始化完成后才在此停一次**,**严禁**在 `.env.local` 一生成(C.1)时就提前停。 | 140 | +所有产出(docs / scripts / .env.local / .gitignore)初始化完成后在此自动校验放行,**不再弹窗等待**: |
| 141 | 141 | ||
| 142 | -循环直到两条件**同时**满足: | ||
| 143 | -(a) `Grep` 重新扫 8 路径,0 命中 | ||
| 144 | -(b) 用户 `AskUserQuestion` 选「继续」 | ||
| 145 | - | ||
| 146 | -每次弹 QA 前重扫;有残留则打印残留位置清单(文件:行号 — 说明)+ 再弹 QA。 | ||
| 147 | - | ||
| 148 | -QA 横幅涵盖: | ||
| 149 | -- 产出文件清单(docs/04 / 06 / 07 / 09 + scripts/*.sh + .env.local + .gitignore) | ||
| 150 | -- 占位状态(N=0 或待填清单) | ||
| 151 | -- **`.env.local` DB 连接核对**:用 `Bash`(`set -a; . .env.local; set +a`)读出后列出当前 `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_SCHEMA` 的**值**;`DB_PASSWORD` / `JWT_SECRET` **只列字段名、不回显值**(凭据不进会话)。提示「默认连接开箱即用;若与本地 MySQL 不符,**现在直接编辑 `.env.local`** 再选『继续』(`cp -n` 不会覆盖你的修改,下一步 A4 db-init 会真正连库验证)」。 | ||
| 152 | -- 两选项:「继续」/「有疑问先沟通」 | ||
| 153 | - | ||
| 154 | -通过后(N=0 且用户选「继续」),用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: | 142 | +1. `Grep` 重扫 8 路径的占位符: |
| 143 | + - 0 命中 → 进入 2。 | ||
| 144 | + - 仍有残留 → 打印残留清单(文件:行号 — 说明)并停下 `[ERP-HALT]`(骨架产出不应残留占位符,属生成异常,修正后重跑)。 | ||
| 145 | +2. **`.env.local` DB 连接信息(仅供参考,无需在此确认)**:用 `Bash`(`set -a; . .env.local; set +a`)列出 `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_SCHEMA` 的**值**;`DB_PASSWORD` / `JWT_SECRET` **只列字段名、不回显**(凭据不进会话)。默认连接开箱即用;如与本地 MySQL 不符,可直接编辑 `.env.local`,下一步 A4 db-init 会真正连库验证(连不上会在 A4 报错停下)。 | ||
| 146 | +3. 用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选,并直接进入 F: | ||
| 155 | - `- [ ] A2 骨架生成 — skeleton-gen` | 147 | - `- [ ] A2 骨架生成 — skeleton-gen` |
| 156 | 148 | ||
| 157 | ### F. 进入 A3 | 149 | ### F. 进入 A3 |