Commit a1f2447bfd8858864b4a14b282f421c2d1f0c675
1 parent
176a7926
remove docs/09 — fold dir layout into docs/04, module->path into docs/08 §二
- delete docs-09-structure-template.md (its § 二/§ 三 dir layout duplicated docs/04 § 1.2/2.1; § 四 docs-tree was a self-referential maintenance trap; § 五 overlapped docs/04) - skeleton-gen B.1 now generates only docs/07; B.2 captures backend/frontend dir layout into docs/04 § 1.2/2.1; frontmatter/checkbox/参考 drop docs/09 - coding.mjs (6 refs): file placement -> docs/04 § 1.2/2.1; frontend root -> frontend/ convention; cross-module path->module -> docs/08 § 二 路径: field - CLAUDE-template rule #2 -> docs/04 § 1.2/2.1; docs-08 checkbox + README A2/template-table drop docs/09
Showing
6 changed files
with
19 additions
and
54 deletions
README.md
| @@ -120,7 +120,7 @@ erp-workflow-plugin/ | @@ -120,7 +120,7 @@ erp-workflow-plugin/ | ||
| 120 | |---|---|---|---| | 120 | |---|---|---|---| |
| 121 | | A0 | `project-init` | • **依赖检查**:检测 git / mysql / node 是否在 PATH,缺失则按 OS 自动安装,装不上再停下提示用户<br>• 空目录初始化:用 Read/Write/Glob 工具拷模板创建 CLAUDE.md / docs/01/index.md / docs/08<br>• `git init` | `plan-start` | | 121 | | A0 | `project-init` | • **依赖检查**:检测 git / mysql / node 是否在 PATH,缺失则按 OS 自动安装,装不上再停下提示用户<br>• 空目录初始化:用 Read/Write/Glob 工具拷模板创建 CLAUDE.md / docs/01/index.md / docs/08<br>• `git init` | `plan-start` | |
| 122 | | A1 | `scope-lock` | • 引导填项目概述 / 技术栈 / 需求索引<br>• 按 `docs/01-需求清单/<module>/{_module.md, REQ-*.md}` 子目录结构生成 REQ 卡片(CC 据 index.md 填 `{{req_id/title/goal/rules/constraints/acceptance}}` 6 个占位,模板其余内容含输入/输出示例字段表原样复制)<br>• **A1 终结校验**:REQ 6 个占位均填真实数据、无 `{{` 残留、`config-vars.yaml` **全部配置**(包名 / 端口 / 初始账号 + DB 凭据 / 密钥占位)已锁、各 stack 的 build/lint/unit/e2e 命令写入 docs/04 § 零;缺失则在此(Plan 期)用 `AskUserQuestion` 问清(敏感凭据由用户自填,不进会话)<br>• 据模板直接 `Write` 生成 `_module.md` / `REQ-*.md`<br>• 终结校验通过后**自动**调用 `Skill(skeleton-gen)` 进入 A2(不停下) | A0 | | 122 | | A1 | `scope-lock` | • 引导填项目概述 / 技术栈 / 需求索引<br>• 按 `docs/01-需求清单/<module>/{_module.md, REQ-*.md}` 子目录结构生成 REQ 卡片(CC 据 index.md 填 `{{req_id/title/goal/rules/constraints/acceptance}}` 6 个占位,模板其余内容含输入/输出示例字段表原样复制)<br>• **A1 终结校验**:REQ 6 个占位均填真实数据、无 `{{` 残留、`config-vars.yaml` **全部配置**(包名 / 端口 / 初始账号 + DB 凭据 / 密钥占位)已锁、各 stack 的 build/lint/unit/e2e 命令写入 docs/04 § 零;缺失则在此(Plan 期)用 `AskUserQuestion` 问清(敏感凭据由用户自填,不进会话)<br>• 据模板直接 `Write` 生成 `_module.md` / `REQ-*.md`<br>• 终结校验通过后**自动**调用 `Skill(skeleton-gen)` 进入 A2(不停下) | A0 | |
| 123 | -| A2 | `skeleton-gen` | • 生成架构文档:docs/04 § 一+ / docs/07 / docs/09<br>• 生成跨平台工具脚本:`scripts/*.mjs`(**无 chmod**;凭据 / 配置统一在 A1 产出的 config-vars.yaml)<br>• 据 `gitignore-append-template` 用 Read/Write 并入项目 .gitignore | `plan-start` | | 123 | +| A2 | `skeleton-gen` | • 生成架构文档:docs/04 § 一+ / docs/07<br>• 生成跨平台工具脚本:`scripts/*.mjs`(**无 chmod**;凭据 / 配置统一在 A1 产出的 config-vars.yaml)<br>• 据 `gitignore-append-template` 用 Read/Write 并入项目 .gitignore | `plan-start` | |
| 124 | | A3 | `db-design-gen` | • A3 起始用 `AskUserQuestion` 确认 ERP 约定(主键策略 / 租户列 / 列前缀规则,默认值可覆盖),结果写 docs/04 + CLAUDE.md<br>• 从 docs/01 REQ 卡片正向设计 `docs/03-数据库设计文档.md`(schema SSoT)<br>• 回填 REQ 卡片依赖表(`TBD(A3 自动补)` → 实际表名)<br>• **停下**等人工审阅 docs/03,审阅完毕用 `/plan-start` 续进 A4 | A2 | | 124 | | A3 | `db-design-gen` | • A3 起始用 `AskUserQuestion` 确认 ERP 约定(主键策略 / 租户列 / 列前缀规则,默认值可覆盖),结果写 docs/04 + CLAUDE.md<br>• 从 docs/01 REQ 卡片正向设计 `docs/03-数据库设计文档.md`(schema SSoT)<br>• 回填 REQ 卡片依赖表(`TBD(A3 自动补)` → 实际表名)<br>• **停下**等人工审阅 docs/03,审阅完毕用 `/plan-start` 续进 A4 | A2 | |
| 125 | | A4 | `db-init` | • LLM 解析 docs/03 → `sql/migrations/V1__initial_schema.sql`(DDL only)<br>• `node ${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs` 校验 DDL ↔ docs/03(5 维:表/列名/列类型/索引/FK),fail-closed<br>• `node ${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs config-vars.yaml V1.sql`(解析 config-vars.yaml database: 段 + mysql2 apply,**无 shell-source**) | A3 | | 125 | | A4 | `db-init` | • LLM 解析 docs/03 → `sql/migrations/V1__initial_schema.sql`(DDL only)<br>• `node ${CLAUDE_PLUGIN_ROOT}/lib/validate-ddl.mjs` 校验 DDL ↔ docs/03(5 维:表/列名/列类型/索引/FK),fail-closed<br>• `node ${CLAUDE_PLUGIN_ROOT}/lib/apply-ddl.mjs config-vars.yaml V1.sql`(解析 config-vars.yaml database: 段 + mysql2 apply,**无 shell-source**) | A3 | |
| 126 | | A5 | `downstream-gen` | • 一次性生成 docs/02 / docs/05 / docs/10<br>• 回填 REQ 卡片依赖接口(`TBD(A5 自动补)` → 实际 endpoint)<br>• 追加模块清单到 docs/08 § 二<br>• **docs/05 + docs/02 评审闸**:用 `AskUserQuestion` 让用户确认 API 端点/字段无误 + 构建顺序可接受,未确认不勾 A5<br>• **prototype/ 门禁 + 推导 FE 清单写 docs/08 § 三**(原 A6 已并入;无 prototype 则问「无前端」→ § 三 留空)<br>• 最终占位符 + 结构残留扫描 | A4 | | 126 | | A5 | `downstream-gen` | • 一次性生成 docs/02 / docs/05 / docs/10<br>• 回填 REQ 卡片依赖接口(`TBD(A5 自动补)` → 实际 endpoint)<br>• 追加模块清单到 docs/08 § 二<br>• **docs/05 + docs/02 评审闸**:用 `AskUserQuestion` 让用户确认 API 端点/字段无误 + 构建顺序可接受,未确认不勾 A5<br>• **prototype/ 门禁 + 推导 FE 清单写 docs/08 § 三**(原 A6 已并入;无 prototype 则问「无前端」→ § 三 留空)<br>• 最终占位符 + 结构残留扫描 | A4 | |
| @@ -148,7 +148,6 @@ erp-workflow-plugin/ | @@ -148,7 +148,6 @@ erp-workflow-plugin/ | ||
| 148 | | scope-lock | `config-vars-template.yaml` | 仓库根 `config-vars.yaml` 骨架(跨栈中立):项目**全部配置**——非敏感(包名/端口/前端包名/初始账号)+ 敏感凭据(database / admin_init.password / secrets);A1 E.2 锁定,随项目提交 | | 148 | | scope-lock | `config-vars-template.yaml` | 仓库根 `config-vars.yaml` 骨架(跨栈中立):项目**全部配置**——非敏感(包名/端口/前端包名/初始账号)+ 敏感凭据(database / admin_init.password / secrets);A1 E.2 锁定,随项目提交 | |
| 149 | | skeleton-gen | `docs-04-skeleton-template.md` | docs/04 § 一+ 编码规范大纲(HTML 注释引导 LLM) | | 149 | | skeleton-gen | `docs-04-skeleton-template.md` | docs/04 § 一+ 编码规范大纲(HTML 注释引导 LLM) | |
| 150 | | skeleton-gen | `docs-07-env-template.md` | docs/07 环境配置大纲(只记规则/约定,不记具体值;配置值统一指向 config-vars.yaml) | | 150 | | skeleton-gen | `docs-07-env-template.md` | docs/07 环境配置大纲(只记规则/约定,不记具体值;配置值统一指向 config-vars.yaml) | |
| 151 | -| skeleton-gen | `docs-09-structure-template.md` | docs/09 目录结构大纲 | | ||
| 152 | | skeleton-gen | `scripts-setup-test-db-template.mjs` | 跨平台 drop + create 空库脚本(内联极简 YAML 读 config-vars.yaml database: 段,无 shell-source);schema apply 交给 Flyway | | 151 | | skeleton-gen | `scripts-setup-test-db-template.mjs` | 跨平台 drop + create 空库脚本(内联极简 YAML 读 config-vars.yaml database: 段,无 shell-source);schema apply 交给 Flyway | |
| 153 | | skeleton-gen | `scripts-test-template.mjs` | test.mjs 骨架(命令槽位按后端/前端/build/lint/test/e2e 分开,`spawnSync(shell:true)` 跨平台执行) | | 152 | | skeleton-gen | `scripts-test-template.mjs` | test.mjs 骨架(命令槽位按后端/前端/build/lint/test/e2e 分开,`spawnSync(shell:true)` 跨平台执行) | |
| 154 | | skeleton-gen | `gitignore-append-template` | 插件推荐忽略项(`.tmp/`、构建产物等;config-vars.yaml 随项目提交,不忽略) | | 153 | | skeleton-gen | `gitignore-append-template` | 插件推荐忽略项(`.tmp/`、构建产物等;config-vars.yaml 随项目提交,不忽略) | |
skills/plan/project-init/templates/CLAUDE-template.md
| @@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
| 18 | ### 你必须做的 ✅ | 18 | ### 你必须做的 ✅ |
| 19 | 19 | ||
| 20 | 1. **严格遵循** `docs/04-技术规范.md`——命名 / 编码 / 统一响应 / 异常处理 / 数据访问 / 配置与安全 等项目专属技术规约全部在此 | 20 | 1. **严格遵循** `docs/04-技术规范.md`——命名 / 编码 / 统一响应 / 异常处理 / 数据访问 / 配置与安全 等项目专属技术规约全部在此 |
| 21 | -2. **严格遵循** `docs/09-项目目录结构.md`——文件放对位置 | 21 | +2. **严格遵循** `docs/04-技术规范.md § 1.2 分层结构 / § 2.1 目录约定`——文件放对位置 |
| 22 | 3. **每个后端接口** 必须先在 `docs/05-API接口契约.md` 定义,再编码实现 | 22 | 3. **每个后端接口** 必须先在 `docs/05-API接口契约.md` 定义,再编码实现 |
| 23 | 4. **每个功能可追溯到 `REQ-XXX-NNN`**——commit tag + 代码注释(如 `// REQ-SYS-001: 用户登录`)+ plan/spec 文件名均用此 tag | 23 | 4. **每个功能可追溯到 `REQ-XXX-NNN`**——commit tag + 代码注释(如 `// REQ-SYS-001: 用户登录`)+ plan/spec 文件名均用此 tag |
| 24 | 5. **遇到跨模块改动**(动到非当前模块的代码)——允许改,但必须在《模块完成报告》记录原因 / 影响评估(留痕) | 24 | 5. **遇到跨模块改动**(动到非当前模块的代码)——允许改,但必须在《模块完成报告》记录原因 / 影响评估(留痕) |
skills/plan/project-init/templates/docs-08-initial-template.md
| @@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
| 16 | - [ ] REQ 卡片骨架已生成(docs/01-需求清单/<module>/REQ-*.md,业务内容留待人工填写) | 16 | - [ ] REQ 卡片骨架已生成(docs/01-需求清单/<module>/REQ-*.md,业务内容留待人工填写) |
| 17 | 17 | ||
| 18 | - [ ] A2 骨架生成 — skeleton-gen | 18 | - [ ] A2 骨架生成 — skeleton-gen |
| 19 | - - [ ] 架构文档已生成(docs/04 § 一+、docs/07、docs/09) | 19 | + - [ ] 架构文档已生成(docs/04 § 一+、docs/07) |
| 20 | - [ ] 工具脚本已生成(scripts/*.mjs) | 20 | - [ ] 工具脚本已生成(scripts/*.mjs) |
| 21 | - [ ] 样式 token 骨架已生成(src/styles/tokens.css) | 21 | - [ ] 样式 token 骨架已生成(src/styles/tokens.css) |
| 22 | - [ ] .gitignore 已配置 | 22 | - [ ] .gitignore 已配置 |
skills/plan/skeleton-gen/SKILL.md
| 1 | --- | 1 | --- |
| 2 | name: skeleton-gen | 2 | name: skeleton-gen |
| 3 | -description: A2 骨架生成——基于 docs/04 § 零 技术栈 + docs/01-需求清单/index.md 模块索引,生成项目专属的架构文档(docs/04 § 一+、docs/07、docs/09)和工具脚本(.mjs,跨平台)。固定工具文件用 Read/Write 落盘,架构文档由 LLM 按大纲生成。 | 3 | +description: A2 骨架生成——基于 docs/04 § 零 技术栈 + docs/01-需求清单/index.md 模块索引,生成项目专属的架构文档(docs/04 § 一+、docs/07)和工具脚本(.mjs,跨平台)。固定工具文件用 Read/Write 落盘,架构文档由 LLM 按大纲生成。 |
| 4 | user-invocable: false | 4 | user-invocable: false |
| 5 | allowed-tools: Read Write Edit Skill Grep Glob AskUserQuestion | 5 | allowed-tools: Read Write Edit Skill Grep Glob AskUserQuestion |
| 6 | --- | 6 | --- |
| @@ -18,20 +18,12 @@ allowed-tools: Read Write Edit Skill Grep Glob AskUserQuestion | @@ -18,20 +18,12 @@ allowed-tools: Read Write Edit Skill Grep Glob AskUserQuestion | ||
| 18 | 18 | ||
| 19 | 后续所有内容都基于它们推导。 | 19 | 后续所有内容都基于它们推导。 |
| 20 | 20 | ||
| 21 | -### B.1 生成 2 个全新架构文档(docs/07 / 09) | 21 | +### B.1 生成 docs/07 环境配置 |
| 22 | 22 | ||
| 23 | -对下表每个目标文件: | ||
| 24 | -1. 读取对应的大纲模板 | ||
| 25 | -2. 基于步骤 A 的输入,按大纲生成项目专属内容 | ||
| 26 | -3. 剥掉 HTML 注释(注释是给 LLM 的提示,不应出现在最终文档里) | ||
| 27 | -4. 写入目标路径 | 23 | +读取 `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md`,基于步骤 A 的输入按大纲生成项目专属内容(剥掉 HTML 注释——注释是给 LLM 的提示,不应出现在最终文档里),`Write` 到 `docs/07-环境配置.md`。 |
| 28 | 24 | ||
| 29 | -| 目标文件 | 大纲模板 | | ||
| 30 | -|---|---| | ||
| 31 | -| `docs/07-环境配置.md` | `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md` | | ||
| 32 | -| `docs/09-项目目录结构.md` | `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md` | | ||
| 33 | - | ||
| 34 | -> 前端 UI/交互/布局不再单独出文档:项目根 `prototype/` 是完整前端 demo(页面 + 布局 + 交互的权威);Design Tokens 在 `src/styles/tokens.css`;前端编码规范在 docs/04 § 二。**色值冲突时 `tokens.css` 优先于 prototype**(prototype 管结构/布局/交互,tokens.css 管色值)。 | 25 | +> **项目目录布局不单独出文档**(原 docs/09 已并入):后端/前端目录布局写进 **docs/04 § 1.2 分层结构 / § 2.1 目录约定**(见 B.2);跨模块「路径→模块」由 docs/08 § 二 模块行的 `路径:` 字段承担。 |
| 26 | +> **前端 UI/交互/布局不出文档**:项目根 `prototype/` 是完整前端 demo(页面 + 布局 + 交互的权威);Design Tokens 在 `src/styles/tokens.css`(**色值冲突时 tokens.css 优先于 prototype**);前端编码规范在 docs/04 § 二。 | ||
| 35 | 27 | ||
| 36 | ### B.2 追加 docs/04 § 一+(保留 § 零 不覆盖) | 28 | ### B.2 追加 docs/04 § 一+(保留 § 零 不覆盖) |
| 37 | 29 | ||
| @@ -39,11 +31,11 @@ docs/04 已由 scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。 | @@ -39,11 +31,11 @@ docs/04 已由 scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。 | ||
| 39 | 31 | ||
| 40 | 1. 读取 `docs/04-技术规范.md`(现有 § 零 完整内容)。 | 32 | 1. 读取 `docs/04-技术规范.md`(现有 § 零 完整内容)。 |
| 41 | 2. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`。 | 33 | 2. 读取 `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md`。 |
| 42 | -3. 基于技术栈,按大纲生成 § 一 ~ 三 的项目专属内容,剥掉 HTML 注释。 | 34 | +3. 基于技术栈,按大纲生成 § 一 ~ 三 的项目专属内容,剥掉 HTML 注释。**§ 1.2 分层结构 / § 2.1 目录约定要写清后端/前端的实际目录布局**(原 docs/09 内容并入此处,供 Coding 阶段落盘 + 跨模块判定参照)。 |
| 43 | 4. 拼接原有内容和新生成内容,写回 `docs/04-技术规范.md`。 | 35 | 4. 拼接原有内容和新生成内容,写回 `docs/04-技术规范.md`。 |
| 44 | 36 | ||
| 45 | 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: | 37 | 完成后,用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: |
| 46 | -- ` - [ ] 架构文档已生成(docs/04 § 一+、docs/07、docs/09)` | 38 | +- ` - [ ] 架构文档已生成(docs/04 § 一+、docs/07)` |
| 47 | 39 | ||
| 48 | ### C. 生成工具脚本 | 40 | ### C. 生成工具脚本 |
| 49 | 41 | ||
| @@ -89,7 +81,7 @@ docs/04 已由 scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。 | @@ -89,7 +81,7 @@ docs/04 已由 scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。 | ||
| 89 | #### E.1 扫描 + 分组 | 81 | #### E.1 扫描 + 分组 |
| 90 | 82 | ||
| 91 | 用 `Grep` 在以下路径扫 `【人工填写:`,记录命中(文件 / 行号 / 说明): | 83 | 用 `Grep` 在以下路径扫 `【人工填写:`,记录命中(文件 / 行号 / 说明): |
| 92 | -- `docs/04-技术规范.md` / `docs/07-环境配置.md` / `docs/09-项目目录结构.md` | 84 | +- `docs/04-技术规范.md` / `docs/07-环境配置.md` |
| 93 | - `config-vars.yaml`(A1 留下的未填字段) | 85 | - `config-vars.yaml`(A1 留下的未填字段) |
| 94 | - `scripts/*.mjs` / `.gitignore` | 86 | - `scripts/*.mjs` / `.gitignore` |
| 95 | 87 | ||
| @@ -116,7 +108,7 @@ docs/04 已由 scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。 | @@ -116,7 +108,7 @@ docs/04 已由 scope-lock 写入 § 零。本步骤追加 § 一 ~ 三。 | ||
| 116 | 108 | ||
| 117 | 每次弹 QA 前重扫;有残留则打印残留位置清单(文件:行号 — 说明)+ 再弹 QA。 | 109 | 每次弹 QA 前重扫;有残留则打印残留位置清单(文件:行号 — 说明)+ 再弹 QA。 |
| 118 | 110 | ||
| 119 | -QA 横幅涵盖:产出文件清单(docs/04 / 07 / 09 + scripts/*.mjs + .gitignore;config-vars.yaml 由 A1 产出,此处仅扫其待填项)、占位状态(N=0 或待填清单)、「继续」/「有疑问先沟通」两选项。 | 111 | +QA 横幅涵盖:产出文件清单(docs/04 / 07 + scripts/*.mjs + .gitignore;config-vars.yaml 由 A1 产出,此处仅扫其待填项)、占位状态(N=0 或待填清单)、「继续」/「有疑问先沟通」两选项。 |
| 120 | 112 | ||
| 121 | 通过后(N=0 且用户选「继续」),用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: | 113 | 通过后(N=0 且用户选「继续」),用 `Edit` 在 `docs/08-模块任务管理.md` 中勾选: |
| 122 | - `- [ ] A2 骨架生成 — skeleton-gen` | 114 | - `- [ ] A2 骨架生成 — skeleton-gen` |
| @@ -131,7 +123,6 @@ QA 横幅涵盖:产出文件清单(docs/04 / 07 / 09 + scripts/*.mjs + .giti | @@ -131,7 +123,6 @@ QA 横幅涵盖:产出文件清单(docs/04 / 07 / 09 + scripts/*.mjs + .giti | ||
| 131 | - `docs/01-需求清单/index.md` | 123 | - `docs/01-需求清单/index.md` |
| 132 | - `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md` | 124 | - `${CLAUDE_SKILL_DIR}/templates/docs-04-skeleton-template.md` |
| 133 | - `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md` | 125 | - `${CLAUDE_SKILL_DIR}/templates/docs-07-env-template.md` |
| 134 | -- `${CLAUDE_SKILL_DIR}/templates/docs-09-structure-template.md` | ||
| 135 | - `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.mjs` | 126 | - `${CLAUDE_SKILL_DIR}/templates/scripts-test-template.mjs` |
| 136 | - `${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.mjs` | 127 | - `${CLAUDE_SKILL_DIR}/templates/scripts-setup-test-db-template.mjs` |
| 137 | - `config-vars.yaml`(A1 产出,含 DB 凭据;setup-test-db.mjs 运行时读取) | 128 | - `config-vars.yaml`(A1 产出,含 DB 凭据;setup-test-db.mjs 运行时读取) |
skills/plan/skeleton-gen/templates/docs-09-structure-template.md deleted
| 1 | -# 09-项目目录结构 | ||
| 2 | - | ||
| 3 | -## 一、仓库顶层 | ||
| 4 | - | ||
| 5 | -## 二、后端目录 | ||
| 6 | - | ||
| 7 | -## 三、前端目录 | ||
| 8 | - | ||
| 9 | -## 四、docs/ 结构 | ||
| 10 | - | ||
| 11 | -``` | ||
| 12 | -docs/ | ||
| 13 | -├── 01-需求清单/ # 每模块一子目录(_module.md 模块头 + REQ-*.md 卡片) | ||
| 14 | -├── 02-开发计划.md | ||
| 15 | -├── 03-数据库设计文档.md | ||
| 16 | -├── 04-技术规范.md | ||
| 17 | -├── 05-API接口契约.md | ||
| 18 | -├── 07-环境配置.md | ||
| 19 | -├── 08-模块任务管理.md | ||
| 20 | -├── 09-项目目录结构.md | ||
| 21 | -├── 10-验收检查清单.md | ||
| 22 | -└── superpowers/ # CC 运行时产物 | ||
| 23 | -``` | ||
| 24 | - | ||
| 25 | -## 五、命名与放置约定 |
workflows/coding.mjs
| @@ -138,7 +138,7 @@ function featureStageContract(phase) { | @@ -138,7 +138,7 @@ function featureStageContract(phase) { | ||
| 138 | '- 然后让本步骤以非零结果 / 显式 throw 结束,由上层 Workflow 转为带诊断的 halt(fail-fast)。', | 138 | '- 然后让本步骤以非零结果 / 显式 throw 结束,由上层 Workflow 转为带诊断的 halt(fail-fast)。', |
| 139 | '- 全部输出文档**使用中文**。', | 139 | '- 全部输出文档**使用中文**。', |
| 140 | `- **阶段 = ${fe ? '前端(frontend)' : '后端(backend)'}**。路径作用域:${fe | 140 | `- **阶段 = ${fe ? '前端(frontend)' : '后端(backend)'}**。路径作用域:${fe |
| 141 | - ? '实现文件必须落在 `frontend/`(或 `docs/09-项目目录结构.md § 前端目录结构` 声明的前端根)下;命中 `backend/` / `sql/` / `scripts/` 即越界,硬停。' | 141 | + ? '实现文件必须落在 `frontend/` 下;命中 `backend/` / `sql/` / `scripts/` 即越界,硬停。' |
| 142 | : '产出范围限定 controller / service / repository / DTO / 校验 / SQL migration / REST 契约;**禁止**写 `frontend/` 路径下的实现(UI 推迟到前端阶段)。'}`, | 142 | : '产出范围限定 controller / service / repository / DTO / 校验 / SQL migration / REST 契约;**禁止**写 `frontend/` 路径下的实现(UI 推迟到前端阶段)。'}`, |
| 143 | `- id 形态:${fe ? '前端为 `FE-NN`(业务功能粒度,可关联多个 prototype 区域与多个 REQ)。' : '后端为 `REQ-XXX-NNN`。'}`, | 143 | `- id 形态:${fe ? '前端为 `FE-NN`(业务功能粒度,可关联多个 prototype 区域与多个 REQ)。' : '后端为 `REQ-XXX-NNN`。'}`, |
| 144 | ].join('\n') | 144 | ].join('\n') |
| @@ -247,8 +247,8 @@ function planPrompt(id, phase, specPath) { | @@ -247,8 +247,8 @@ function planPrompt(id, phase, specPath) { | ||
| 247 | '## 输入', | 247 | '## 输入', |
| 248 | `- 上游 spec:\`${specPath}\`(已由 spec stage 落盘;不存在则 halt)。**plan 文件名日期前缀必须与 spec 一致**:取 spec 文件名首段 \`YYYY-MM-DD\`,写到 plan 路径,不要重新解析"今天"。`, | 248 | `- 上游 spec:\`${specPath}\`(已由 spec stage 落盘;不存在则 halt)。**plan 文件名日期前缀必须与 spec 一致**:取 spec 文件名首段 \`YYYY-MM-DD\`,写到 plan 路径,不要重新解析"今天"。`, |
| 249 | fe | 249 | fe |
| 250 | - ? `- \`${ROOT}/docs/04-技术规范.md § 一 前端架构\`(路由 / 状态库 / 组件目录约定 / 测试栈);\`${ROOT}/docs/09-项目目录结构.md § 前端目录结构\`(落盘位置)。用 Grep 在 \`${ROOT}/frontend/\` 定位现有文件。` | ||
| 251 | - : `- \`${ROOT}/docs/04-技术规范.md\` 与 \`${ROOT}/docs/09-项目目录结构.md\`(编码规范 + 目录规范)。用 Grep 在现有代码定位待修改文件。`, | 250 | + ? `- \`${ROOT}/docs/04-技术规范.md § 一 前端架构\`(路由 / 状态库 / 组件目录约定 / 测试栈)+ \`§ 2.1 目录约定\`(落盘位置)。用 Grep 在 \`${ROOT}/frontend/\` 定位现有文件。` |
| 251 | + : `- \`${ROOT}/docs/04-技术规范.md\`(编码规范 + § 1.2 分层 / § 2.1 目录规范)。用 Grep 在现有代码定位待修改文件。`, | ||
| 252 | '', | 252 | '', |
| 253 | '## 计划写作原则', | 253 | '## 计划写作原则', |
| 254 | '- Plan 告诉 TDD 执行者**做什么**,不是**怎么写代码**(执行者是同模型、全上下文的 tdd stage)。', | 254 | '- Plan 告诉 TDD 执行者**做什么**,不是**怎么写代码**(执行者是同模型、全上下文的 tdd stage)。', |
| @@ -260,7 +260,7 @@ function planPrompt(id, phase, specPath) { | @@ -260,7 +260,7 @@ function planPrompt(id, phase, specPath) { | ||
| 260 | '## 任务结构(每个 task = 一个 red-green-commit 单元,4 step)', | 260 | '## 任务结构(每个 task = 一个 red-green-commit 单元,4 step)', |
| 261 | '1. 写失败测试(给 `test_file::test_name` + 测试意图);2. 实现最小代码(给 `impl_file`);3. 子会话验证 PASS;4. commit。任务粒度 2-5 分钟。', | 261 | '1. 写失败测试(给 `test_file::test_name` + 测试意图);2. 实现最小代码(给 `impl_file`);3. 子会话验证 PASS;4. commit。任务粒度 2-5 分钟。', |
| 262 | fe | 262 | fe |
| 263 | - ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\`(或 docs/09 声明的前端根)开头;命中 - ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\`(或 docs/09 声明的前端根)backend/- ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\`(或 docs/09 声明的前端根) / - ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\`(或 docs/09 声明的前端根)sql/- ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\`(或 docs/09 声明的前端根) / - ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\`(或 docs/09 声明的前端根)scripts/- ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\`(或 docs/09 声明的前端根) → 修正后重渲染。` | 263 | + ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\` 开头;命中 + ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\` backend/+ ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\` / + ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\` sql/+ ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\` / + ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\` scripts/+ ? `- **硬护栏**:每个任务 \`impl_file\` 必须以 \`frontend/\` → 修正后重渲染。` |
| 264 | : `- **硬护栏**:任务粒度限定后端文件(controller / service / repository / DTO / 校验 / SQL migration);**禁止**生成 \`frontend/\` 路径任务。`, | 264 | : `- **硬护栏**:任务粒度限定后端文件(controller / service / repository / DTO / 校验 / SQL migration);**禁止**生成 \`frontend/\` 路径任务。`, |
| 265 | '- 允许写死的少数场景:DDL / migration 语句、合同级常量(错误码 / JWT claim / Redis key / 路由 path / API client 签名 / Design Tokens 名)、可选的测试断言 sketch。其余一律散文 + 签名描述。', | 265 | '- 允许写死的少数场景:DDL / migration 语句、合同级常量(错误码 / JWT claim / Redis key / 路由 path / API client 签名 / Design Tokens 名)、可选的测试断言 sketch。其余一律散文 + 签名描述。', |
| 266 | '- 首次出现的类 / 方法 / 组件 / hook / API client 函数必须给出签名;跨 task 的签名 / 错误码 / props 类型必须一致。', | 266 | '- 首次出现的类 / 方法 / 组件 / hook / API client 函数必须给出签名;跨 task 的签名 / 错误码 / props 类型必须一致。', |
| @@ -303,7 +303,7 @@ function tddPrompt(id, phase, planPath) { | @@ -303,7 +303,7 @@ function tddPrompt(id, phase, planPath) { | ||
| 303 | '## 护栏', | 303 | '## 护栏', |
| 304 | '- **绝不**在主会话直接跑测试(mvn / pnpm / playwright / scripts/test.mjs)——必须通过 Agent 子会话。', | 304 | '- **绝不**在主会话直接跑测试(mvn / pnpm / playwright / scripts/test.mjs)——必须通过 Agent 子会话。', |
| 305 | fe | 305 | fe |
| 306 | - ? '- **绝不**写非 `frontend/`(或 docs/09 前端根)路径的 `impl_file`;命中 `backend/` / `sql/` / `scripts/` → 硬停并打印 `不允许写非前端文件:<impl_file>`。' | 306 | + ? '- **绝不**写非 `frontend/` 路径的 `impl_file`;命中 `backend/` / `sql/` / `scripts/` → 硬停并打印 `不允许写非前端文件:<impl_file>`。' |
| 307 | : '- **后端阶段路径硬护栏**:任意 `impl_file` 以 `frontend/` 开头 → 硬停并打印 `后端阶段不允许写前端代码:<impl_file>`,不再继续 TDD。', | 307 | : '- **后端阶段路径硬护栏**:任意 `impl_file` 以 `frontend/` 开头 → 硬停并打印 `后端阶段不允许写前端代码:<impl_file>`,不再继续 TDD。', |
| 308 | '- 每次 commit 含 REQ/FE 标签,不混合无关改同。', | 308 | '- 每次 commit 含 REQ/FE 标签,不混合无关改同。', |
| 309 | '', | 309 | '', |
| @@ -734,7 +734,7 @@ function classifyCrossModulePromptM(moduleId, files) { | @@ -734,7 +734,7 @@ function classifyCrossModulePromptM(moduleId, files) { | ||
| 734 | `# 把改动文件分类:哪些落在**非本模块 \`${moduleId}\`** 的目录下`, | 734 | `# 把改动文件分类:哪些落在**非本模块 \`${moduleId}\`** 的目录下`, |
| 735 | microStepContract(), | 735 | microStepContract(), |
| 736 | '', | 736 | '', |
| 737 | - `本模块目录归属请以 \`${ROOT}/docs/09-项目目录结构.md\` 与 \`${ROOT}/docs/08-模块任务管理.md § 二\` 中本模块 bullet 的 \`路径:\` 字段为准。Read 这两份文档以建立"路径 → 模块"映射。`, | 737 | + `本模块目录归属以 \`${ROOT}/docs/08-模块任务管理.md § 二\` 中本模块 bullet 的 \`路径:\` 字段为准。Read 它以建立"路径 → 模块"映射(粒度/分层约定见 docs/04 § 1.2/2.1)。`, |
| 738 | '', | 738 | '', |
| 739 | '## 改动文件清单', | 739 | '## 改动文件清单', |
| 740 | filesText, | 740 | filesText, |
| @@ -923,7 +923,7 @@ async function runMilestone(module) { | @@ -923,7 +923,7 @@ async function runMilestone(module) { | ||
| 923 | } | 923 | } |
| 924 | 924 | ||
| 925 | // ---- runCrossModule:原 crossModulePrompt 的"diff → 分类 → 写日志" → JS 编排 ---- | 925 | // ---- runCrossModule:原 crossModulePrompt 的"diff → 分类 → 写日志" → JS 编排 ---- |
| 926 | -// diff 和写文件是机械动作;"按 docs/09 路径归属判定哪些是跨模块"需要 LLM 判断,独立成一步。 | 926 | +// diff 和写文件是机械动作;"按 docs/08 § 二 路径归属判定哪些是跨模块"需要 LLM 判断,独立成一步。 |
| 927 | async function runCrossModule(module) { | 927 | async function runCrossModule(module) { |
| 928 | const id = module?.id ?? '<module>' | 928 | const id = module?.id ?? '<module>' |
| 929 | const lbl = (k) => `xmod:${k}:${id}` | 929 | const lbl = (k) => `xmod:${k}:${id}` |