--- name: skeleton-gen description: A2 骨架生成——基于 docs/04 § 零 技术栈 + docs/01-需求清单/index.md 模块索引,生成项目专属的架构文档(docs/04 § 一+、docs/06、docs/07、docs/09)和工具脚本。固定工具文件走 cp,架构文档由 LLM 按大纲生成。 user-invocable: false allowed-tools: Read Write Edit Skill Grep Glob AskUserQuestion Bash(mkdir *) Bash(cp *) Bash(touch *) Bash(chmod *) Bash(cat *) Bash(bash *) --- **所有输出必须使用中文。** # skeleton-gen ## 执行步骤 ### 步骤 0:打印当前位置流程图 用 `Bash` 执行 `cat` 命令向用户展示当前位置流程图(stdout 即 ASCII 框图): ```bash cat "${CLAUDE_PLUGIN_ROOT}/skills/plan/skeleton-gen/banners/flow.txt" ``` ### A. 读取锁定的输入 用 `Read` 读取: - `docs/04-技术规范.md` § 零 技术栈表 - `docs/01-需求清单/index.md` 需求索引 - `docs/01-需求清单/` 需求卡片 后续所有内容都基于它们推导。 ### B.1 生成 3 个全新架构文档(docs/06 / 07 / 09) 对下表每个目标文件: 1. 读取对应的大纲模板 2. 基于步骤 A 的输入,按大纲生成项目专属内容 3. 剥掉 HTML 注释(注释是给 LLM 的提示,不应出现在最终文档里) 4. 写入目标路径 | 目标文件 | 大纲模板 | |---|---| | `docs/06-UI交互规范.md`(§ 一 ~ 四,§ 五 占位) | `${CLAUDE_SKILL_DIR}/templates/docs-06-static-template.md` | | `docs/07-环境配置.md` | `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md` | | `docs/09-项目目录结构.md` | `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md` | 项目专属标识:**根包名固定为 `com.xly.erp`(直接写入,不要占位、不要弹问)**;其余命名空间(如前端 namespace)若仍需要人工决定,可保留 `【人工填写:<说明>】` 占位,由步骤 E 处理。 ### B.2 追加 docs/04 § 一+(保留 § 零 不覆盖) docs/04 已由 scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。 1. 读取 `docs/04-技术规范.md`(现有 § 零 完整内容)。 2. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`。 3. 基于技术栈,按大纲生成 § 一 ~ 三 的项目专属内容,剥掉 HTML 注释。 4. 拼接原有内容和新生成内容,写回 `docs/04-技术规范.md`。 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: - ` - [ ] 架构文档已生成(docs/04 § 一+、docs/06、docs/07、docs/09)` ### C. 生成工具脚本 #### C.1 复制 ```bash mkdir -p scripts sql/migrations src/styles src/main/java/com/xly/erp/config touch sql/migrations/.gitkeep cp -n "${CLAUDE_SKILL_DIR}/templates/env-local-template" .env.local cp "${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh" scripts/setup-test-db.sh cp "${CLAUDE_SKILL_DIR}/templates/styles-tokens-template.css" src/styles/tokens.css cp -n "${CLAUDE_SKILL_DIR}/templates/CorsConfig.java.template" src/main/java/com/xly/erp/config/CorsConfig.java ``` > `cp -n` 保证 `.env.local` / `CorsConfig.java` 不会覆盖已有文件——用户在 E.3 核对时改过的凭据、B 阶段对 CORS 的收紧都不会被重跑冲掉(幂等可重跑)。 #### C.2 渲染 scripts/test.sh 读取 `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.sh`,基于步骤 A 的技术栈(docs/04 § 零)为 7 个占位推断命令后写到 `scripts/test.sh`: - `{{backend_build}}` / `{{backend_lint}}` / `{{backend_test}}` 后端各 stage 命令 - `{{frontend_build}}` / `{{frontend_lint}}` / `{{frontend_test}}` 前端各 stage 命令 - `{{e2e_cmd}}` E2E(无 E2E 工具则填 `echo "[test.sh] e2e 略"`) > 推断规则:根据 `docs/04 § 零` 。 > - 「后端*」存在 → 据后端技术栈推 backend 三槽(build / lint / test 命令) > - 「前端*」存在 → 据前端技术栈推 frontend 三槽 > - 缺席 stack → 三槽全填 `:`(运行期 `[ -d X ]` 守卫对接;语法合法即可) > - `{{e2e_cmd}}` 通常仅前端,按上述前端规则或填 `echo "[test.sh] e2e 略"` > > 表结构异常(列名变更 / 无中文前缀)时停下,用 `AskUserQuestion` 让用户显式确认每 stack 命令。 #### C.3 赋权 ```bash chmod +x scripts/*.sh ``` 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: - ` - [ ] 工具脚本已生成(scripts/*.sh、.env.local、src/main/java/com/xly/erp/config/CorsConfig.java)` - ` - [ ] 样式 token 骨架已生成(src/styles/tokens.css)` ### D. 追加 .gitignore 忽略项 调用脚本完成合并: ```bash bash "${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh" "${CLAUDE_SKILL_DIR}/templates/gitignore-append-template" ``` 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: - ` - [ ] .gitignore 已配置` ### E. 占位符补填 + QA 闸门 #### E.1 扫描 + 分组 用 `Grep` 在以下 8 个路径扫 `【人工填写:`,记录命中(文件 / 行号 / 说明): - `docs/04-技术规范.md` / `docs/06-UI交互规范.md` / `docs/07-环境配置.md` / `docs/09-项目目录结构.md` - `scripts/*.sh` / `.gitignore` - `.env.local` 分两组: - **敏感组**:`.env.local` 路径命中(凭据 / 密钥)。**不弹 QA**(凭据不进会话),E.3 提示用户自填。 - **非敏感组**:其余文件。按说明文字聚合为「根占位」(相同说明 = 同一值,多处共用)或「派生占位」(说明表达派生关系,如"后端 java 根包路径"派生自"根包名")。 非敏感组无命中 → 跳过 E.2/E.3,直接进 E.4(E.4 是收尾必停步,含 `.env.local` 连接核对,不可跳)。 #### E.2 问根占位 + 推派生 + 批量 Edit - **根包名例外(不问,静默补齐)**:凡说明涉及「根包名 / Java 包路径 / 包路径」的占位**一律不弹问**,CC 直接用固定值 `com.xly.erp`(派生目录路径 `com/xly/erp`)`Edit` 替换。这是兜底——正常情况下步骤 B 已写死、不该出现此类占位;若因旧项目残留或生成遗漏而出现,此处静默补齐,**绝不** `AskUserQuestion`。 - 其余每个根占位用 `AskUserQuestion` 问(给合理默认值 + 自由输入),用 `Edit` 批量替换所有命中位置 - 派生占位**不问**,CC 基于根占位值推断后 `Edit`;不能可靠推断则回退当独立根占位问 #### E.3 敏感占位提示(不弹 QA) 若敏感组非空:打印提示横幅,列出 `.env.local` 待填字段名 + 告诉用户"直接编辑文件,凭据不进会话"。 > `.env.local` 的 DB 连接核对**不在此处停**,统一放到 E.4 最终闸门——等所有产出(docs / scripts / .env.local / .gitignore)都初始化完成后再停一次,避免「一生成就停」。 #### E.4 验证闸门(自动,无停顿) 所有产出(docs / scripts / .env.local / .gitignore)初始化完成后在此自动校验放行,**不再弹窗等待**: 1. `Grep` 重扫 8 路径的占位符: - 0 命中 → 进入 2。 - 仍有残留 → 打印残留清单(文件:行号 — 说明)并停下 `[ERP-HALT]`(骨架产出不应残留占位符,属生成异常,修正后重跑)。 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 报错停下)。 3. 用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选,并直接进入 F: - `- [ ] A2 骨架生成 — skeleton-gen` ### F. 进入 A3 输出 `skeleton-gen: 完成`,立即调用 `Skill(db-design-gen)`(直接调用,**不要**先输出"已完成 / 接下来 / 请检查 / 等你确认"之类桥接叙述——会被解读为 turn 结束信号、害用户手敲 continue)。 ## 参考 - `docs/04-技术规范.md` § 零(技术栈输入) - `docs/01-需求清单/index.md`(模块索引输入) - `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`(大纲) - `${CLAUDE_SKILL_DIR}/templates/docs-06-static-template.md`(大纲) - `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md`(大纲) - `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md`(大纲) - `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.sh`(推断命令填充 7 槽:backend/frontend × build/lint/test + e2e;缺席 stack 填 `:`) - `${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.sh`(0 槽位) - `${CLAUDE_SKILL_DIR}/templates/env-local-template`(0 槽位) - `${CLAUDE_SKILL_DIR}/templates/gitignore-append-template`(0 槽位) - `${CLAUDE_SKILL_DIR}/templates/styles-tokens-template.css`(0 槽位,样式 token 骨架) - `${CLAUDE_SKILL_DIR}/templates/CorsConfig.java.template`(0 槽位,根包硬编码 com.xly.erp,全局 CORS Bean) - `${CLAUDE_SKILL_DIR}/scripts/merge-gitignore.sh`(.gitignore 逐行判重合并脚本)