Commit f0cff74ca4a0874233c9dfb0533f48d6dae78490

Authored by zichun
1 parent cb2e2bf3

feat(lite): unify backend+frontend feature loops into one phase-parameterized 3-step chain

- Add feature-spec (brainstorm+plan merged, phase switch for backend/frontend)
- Overwrite feature-tdd with dual-phase support (path guards, test dispatch, commit trailers)
- Overwrite feature-review with verify+review merged, both reviewer agents, phase-driver callback, 5-round cap
- Delete 8 superseded skills: feature-{brainstorm,plan,verify} + fe-feature-{brainstorm,plan,tdd,verify,review}
skills/coding/fe-feature-brainstorm/SKILL.md deleted
1 ----  
2 -name: fe-feature-brainstorm  
3 -description: 前端功能循环第 1 步。针对单个 FE-NN 页面(prototype/*.html)做交互式 Q&A + 写前端规格,产出到 docs/superpowers/specs/,链入 fe-feature-plan。  
4 -user-invocable: false  
5 -allowed-tools: Read Write Skill AskUserQuestion Glob Grep  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# fe-feature-brainstorm  
11 -  
12 -## 阶段范围(前端)  
13 -  
14 -本 skill 服务于**前端阶段**。产出范围限定为:组件树 / 页面状态机 / 交互流程 / API 调用 / Design Tokens 引用 / 业务校验前端复刻。**不涉及** SQL / migration / controller / service / DTO(这些已在后端阶段完成)。  
15 -  
16 -一个 FE 是**业务功能**粒度,可能关联多个 prototype 文件区域和多个 REQ。  
17 -  
18 -## 占位符规则  
19 -  
20 -本 skill 写的 spec 是 CC 内部推理产物,不是用户审阅文档。**不允许** `【人工填写:...】` 占位符——A 阶段标记。需要具体值时:  
21 -  
22 -1. **先查** `.env.local` / `docs/07-环境配置.md` / `docs/04-技术规范.md` / `docs/06-UI交互规范.md` / `CLAUDE.md` / 现有代码 / 关联 prototype。值已落地某处 → 在 spec 中引用源  
23 -2. **再问**:查不到 → `AskUserQuestion` 问用户,记录答案到 spec  
24 -3. **绝不**留 `【人工填写:】` 占位符  
25 -  
26 -## 执行步骤  
27 -  
28 -1. **收集上下文**:确定本次 FE(由 `frontend-start` 派发时传入 `{ fe_id, name, associated_reqs[], associated_prototypes[] }`),读取证据:  
29 - - **页面骨架**:Read 所有 `associated_prototypes[]`(如 `prototype/dashboard.html` + `prototype/dashboard.html#metrics-section`;含 anchor 时聚焦相应区域),作为本 FE 涉及页面的布局权威  
30 - - **业务规则**:Read 所有 `associated_reqs[]` 对应的 `docs/01-需求清单/<module>/<REQ-id>.md`,提取业务校验规则、acceptance、UI 描述  
31 - - **API 契约**:Read `docs/05-API接口契约.md`,按 `associated_reqs[]` 过滤出本 FE 消费的端点  
32 - - **Design Tokens**:Read `docs/06-UI交互规范.md § 二`,作为色值/状态色的引用源  
33 - - **前端组件库**:Read `docs/04-技术规范.md § 零` 找 `frontend.ui_lib`(如 Ant Design / Element Plus),决定组件选型  
34 -  
35 -2. **交互式 Q&A**(参考下方"Q&A 原则",本次为**前端阶段**头脑风暴):  
36 - - 关注:组件树、页面状态机、交互流程、API 调用一致性、Design Tokens 引用、业务校验前端复刻  
37 - - **不要**讨论 SQL / migration / controller / service / DTO(后端阶段已定)  
38 - - **一次一问** `AskUserQuestion`,仅对真模糊点;多选题优先  
39 - - trade-off 直接内嵌 spec,**不设确认 gate**  
40 -  
41 -3. **写 spec 到 `docs/superpowers/specs/<YYYY-MM-DD>-<fe_id>.md`**:  
42 - - 按 `${CLAUDE_SKILL_DIR}/templates/fe-feature-spec-template.md` 渲染  
43 - - 规格至少含:  
44 - - 关联 REQ + 关联原型(来自 frontend-start 派发的入参)  
45 - - 组件树(多个 prototype 文件 / 区域则按页面分块;推导自 prototype DOM)  
46 - - 页面状态机(loading / empty / error / 正常 / 表单提交中 至少 5 态;多页则按页列出)  
47 - - 消费的后端端点(与 docs/05 对齐,按本 FE 的 `associated_reqs[]` 过滤)  
48 - - 业务规则前端复刻清单(逐条,每条标注:规则描述 / 触发时机 / 报错文案 / 来源 REQ)  
49 - - Design Tokens 引用清单(本 FE 用到的 `var(--color-*)` 名称)  
50 - - 文件已存在 → 征求用户确认后覆盖  
51 -  
52 -4. **Spec 自审**(inline 修,无须用户等待):  
53 - - 所有顶级节非空  
54 - - **全文不得出现** `TBD` / `@todo` / `controller` / `SQL` / `service` / `migration` 字样——前者代表 spec 未完成,后五者属于后端范畴不应出现。命中 → 修正后重渲染  
55 - - **内部一致性** / **范围检查** / **歧义检查**(按 Q&A 原则)  
56 -  
57 -5. **输出 + 链 fe-feature-plan**(**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号):  
58 - - 输出一行 `fe-feature-brainstorm: <fe_id> → <path>`  
59 - - **同一 turn 内立即** `Skill(fe-feature-plan)`  
60 -  
61 -## Q&A 原则  
62 -  
63 -- **一次一问** — 不堆问题  
64 -- **多选题优先** — 答更快  
65 -- **仅对真模糊点问** — 不造确认问题  
66 -- **YAGNI** — 删不必要的功能  
67 -- **渐进理解** — 不明白就问  
68 -- **无审批 gate** — 写 spec 即 commit  
69 -  
70 -## 参考  
71 -  
72 -- `${CLAUDE_SKILL_DIR}/templates/fe-feature-spec-template.md`  
73 -- 上游:`frontend-start`(每个未完成 FE 派发到此)  
74 -- 下游:`fe-feature-plan`  
skills/coding/fe-feature-brainstorm/templates/fe-feature-spec-template.md deleted
1 -# 前端功能规格 — {{fe_id}} {{name}}  
2 -  
3 -> 关联 REQ:{{associated_reqs}}  
4 -> 关联原型:{{associated_prototypes}}  
5 -> 日期:{{date}}  
6 -  
7 -## 一、功能概述  
8 -  
9 -{{feature_overview}}  
10 -  
11 -## 二、组件树  
12 -  
13 -<!-- 基于关联原型的 DOM 结构推导。多页则按页面分块;每层缩进表示嵌套关系。 -->  
14 -  
15 -```  
16 -{{component_tree}}  
17 -```  
18 -  
19 -## 三、页面状态机  
20 -  
21 -| # | 状态 | 触发条件 | 视觉表现 | 用户可执行操作 |  
22 -|---|------|---------|---------|--------------|  
23 -{{state_machine_rows}}  
24 -  
25 -至少包含:loading / empty / error / 正常 / 提交中 五态。  
26 -  
27 -## 四、消费的后端端点  
28 -  
29 -| # | 方法 | 路径 | 触发时机 | 关联 REQ |  
30 -|---|------|------|---------|---------|  
31 -{{endpoint_rows}}  
32 -  
33 -## 五、业务规则前端复刻清单  
34 -  
35 -| # | 规则描述 | 触发时机 | 报错文案 | 来源 REQ |  
36 -|---|---------|---------|---------|---------|  
37 -{{validation_rows}}  
38 -  
39 -> **要求**:每条规则必须在前端 form-level 校验中复刻,不仅依赖后端报错。文案与后端语义一致。  
40 -  
41 -## 六、Design Tokens 引用清单  
42 -  
43 -<!-- 列出本页面用到的 token 变量名(不写 hex),如 var(--color-primary) / var(--color-bg-card)。来源见 docs/06 § 二。 -->  
44 -  
45 -```  
46 -{{token_list}}  
47 -```  
48 -  
49 -## 七、交互流程关键路径  
50 -  
51 -{{interaction_flow}}  
52 -  
53 -## 八、备注与开放问题  
54 -  
55 -{{open_questions}}  
skills/coding/fe-feature-plan/SKILL.md deleted
1 ----  
2 -name: fe-feature-plan  
3 -description: 前端功能循环第 2 步。将 FE 规格转任务级实现计划(每任务 2-5 分钟,含组件路径、props 契约、测试意图),产出到 docs/superpowers/plans/,链入 fe-feature-tdd。  
4 -user-invocable: false  
5 -allowed-tools: Read Write Grep Skill AskUserQuestion  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# fe-feature-plan  
11 -  
12 -## 阶段范围(前端)  
13 -  
14 -把当前 FE 的规格转成任务级实现计划。任务粒度限定为:**组件文件 / 路由配置 / store hook / API client 包装函数**。**不允许**生成涉及后端文件(controller / service / repository / SQL)的任务。  
15 -  
16 -## 计划写作原则  
17 -  
18 -- Plan 告诉 TDD 执行者**做什么**,不是**怎么写代码**——执行者是 `fe-feature-tdd`(同一模型,全上下文)  
19 -- Plan 锁定**文件边界 + 测试意图 + props 契约 + 完成判据**;代码由 TDD 红绿循环产出  
20 -- **禁止 dump 整个文件内容**(vue/react 组件源码、config 文件)到 plan  
21 -- 每个任务标注"测试先行类型" = **jsdom 组件测试** OR **Playwright E2E**  
22 -- DRY、YAGNI、TDD、frequent commits  
23 -  
24 -## 占位符规则  
25 -  
26 -每个 step 必须写实际内容。以下绝不出现:  
27 -  
28 -- `TBD` / `TODO` / `implement later` / `fill in details`  
29 -- **`【人工填写:】`** — A 阶段标记。需要具体值时:先查 `.env.local` / `docs/07` / `docs/04` / `docs/09` / 现有代码并引用源;否则 `AskUserQuestion`  
30 -- 涉及后端文件(`backend/` / `sql/` / `scripts/`)的任务——**硬护栏**  
31 -- 未在任何 task 定义的组件 / hook / API client 函数  
32 -  
33 -## 执行步骤  
34 -  
35 -1. **收集输入**:  
36 - - 当前 FE 的规格 `docs/superpowers/specs/<YYYY-MM-DD>-<fe_id>.md`(不存在则报错)  
37 - - `docs/04-技术规范.md § 一前端架构`(路由 / 状态库 / 组件目录约定 / 测试栈)  
38 - - `docs/09-项目目录结构.md § 前端目录结构`(文件落盘位置规范)  
39 - - 相关代码指针(通过 `Grep` 在 `frontend/` 下定位现有前端文件)  
40 -  
41 -2. **范围检查**:spec 跨多页/多业务 → 提示拆分  
42 -  
43 -3. **文件结构推导**:  
44 - - 组件 / 路由 / hook / API client 各放哪里(依 docs/09 § 前端目录结构)  
45 - - 每个文件单一职责  
46 - - 同 feature 的相关文件放一起  
47 -  
48 -4. **任务粒度推导**(参考下方"任务原则"):  
49 - - 每个任务 = 一个 red-green-commit 单元  
50 - - 4 个 step:写失败测试 → 实现最小代码 → 子会话验证 PASS → commit  
51 - - 任务粒度 2-5 分钟  
52 - - 每个任务必须含:`test_file::test_name` + `impl_file` + 完成判据 + "测试先行类型"标注  
53 -  
54 -5. **写 plan 到 `docs/superpowers/plans/<YYYY-MM-DD>-<fe_id>.md`**:  
55 - - 按 `${CLAUDE_SKILL_DIR}/templates/fe-feature-plan-template.md` 渲染  
56 - - 文件已存在 → 征求用户确认后覆盖  
57 -  
58 -6. **Plan 自审**(inline 修,无须用户等待):  
59 - - 每个任务必须含 `test_file::test_name`、`impl_file`、完成标准  
60 - - **每个任务的 `impl_file` 路径必须以 `frontend/` 开头**(或 `docs/09` 声明的前端根目录);命中 `backend/` / `sql/` / `scripts/` → 修正后重渲染  
61 - - **占位符扫描**:`TBD` / `【人工填写:】` → 修  
62 - - **Spec coverage**:spec 每节能指向至少一个 task 吗  
63 - - **类型一致性**:组件 props 类型 / hook 签名跨 task 一致  
64 -  
65 -7. **输出 + 链 fe-feature-tdd**(**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号):  
66 - - 输出一行 `fe-feature-plan: <fe_id> → <path>`  
67 - - **同一 turn 内立即** `Skill(fe-feature-tdd)`  
68 -  
69 -## 任务原则  
70 -  
71 -### Plan 文件头  
72 -  
73 -每个 plan 必须以以下头部开始:  
74 -  
75 -```markdown  
76 -# [FE Feature Name] Implementation Plan  
77 -  
78 -> **Execution:** Parent skill `fe-feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.  
79 -  
80 -**Goal:** [一句话描述]  
81 -  
82 -**Architecture:** [2-3 句方法论]  
83 -  
84 -**Tech Stack:** [关键技术 / 库]  
85 -  
86 ----  
87 -```  
88 -  
89 -### Task 结构  
90 -  
91 -每个 task 是 red-green-commit 单元:  
92 -  
93 -````markdown  
94 -### Task N: [组件名]  
95 -  
96 -**Files:**  
97 -- Create: `frontend/src/components/LoginForm.tsx`  
98 -- Test: `frontend/src/components/LoginForm.test.tsx`  
99 -- 测试先行类型: jsdom 组件测试  
100 -  
101 -**Props/API shape**(只写需要约束实现的签名):  
102 -- `<LoginForm onSubmit={(username: string, password: string) => Promise<void>} loading={boolean} />`  
103 -  
104 -- [ ] **Step 1: 写失败测试**  
105 - - 测试名: `LoginForm renders username and password fields`  
106 - - 意图: 验证组件渲染 username / password input,submit button disabled when empty  
107 - - 子会话确认 FAIL(组件不存在)  
108 -  
109 -- [ ] **Step 2: 实现最小代码**  
110 - - 目标: 让 Step 1 测试通过;不多做  
111 - - 涉及文件: `frontend/src/components/LoginForm.tsx`  
112 -  
113 -- [ ] **Step 3: 子会话验证 PASS**  
114 -  
115 -- [ ] **Step 4: Commit**  
116 - - `git add <文件>`  
117 - - `git commit -m "feat(fe): LoginForm 组件 FE-01"`  
118 -````  
119 -  
120 -### 允许的代码块场景  
121 -  
122 -少数例外,需要写死而非让 TDD 自由发挥:  
123 -  
124 -- **路由配置**:`routes.ts` 中 path 注册(路径是契约级)  
125 -- **API client 契约**:fetch 包装函数签名 + headers + 错误码 mapping  
126 -- **Design Tokens 名称**:`var(--color-primary)` 列表(跨组件复用)  
127 -- **测试断言形状**(可选)  
128 -  
129 -除此之外一律散文 + 签名描述,**不贴完整组件源码**。  
130 -  
131 -### 记住  
132 -  
133 -- Exact file paths always(必须以 `frontend/` 开头)  
134 -- 测试先行类型必须明确(jsdom / Playwright)  
135 -- 组件 props / hook 签名 / API client 函数签名 — **必须写死**  
136 -- Internal implementation code — **不写**;留给 TDD 阶段  
137 -  
138 -## 参考  
139 -  
140 -- `${CLAUDE_SKILL_DIR}/templates/fe-feature-plan-template.md`  
141 -- 上游:`fe-feature-brainstorm`  
142 -- 下游:`fe-feature-tdd`  
skills/coding/fe-feature-plan/templates/fe-feature-plan-template.md deleted
1 -# 前端功能计划 — {{fe_id}} {{name}}  
2 -  
3 -> 规格:docs/superpowers/specs/{{date}}-{{fe_id}}.md  
4 -> 关联原型:{{associated_prototypes}}  
5 -> 关联 REQ:{{associated_reqs}}  
6 -> 日期:{{date}}  
7 -  
8 -## 一、依赖与前置条件  
9 -  
10 -- 前置 FE:{{prerequisite_fes}}  
11 -- 共享组件:{{shared_components}}  
12 -- 路由配置文件:{{router_file}}  
13 -  
14 -## 二、任务清单  
15 -  
16 -每行一个任务,2-5 分钟可完成。`test_file::test_name` 先行写失败测试,`impl_file` 写最小实现使其通过。  
17 -  
18 -| # | 任务 | 测试先行类型 | test_file::test_name | impl_file | 完成判据 |  
19 -|---|------|-------------|---------------------|-----------|---------|  
20 -{{task_rows}}  
21 -  
22 -> **路径约束**:所有 `impl_file` 必须以 `frontend/`(或 docs/09 声明的前端根目录)开头。  
23 -> **测试先行类型**:`jsdom`(组件单测,vitest/jest)或 `e2e`(Playwright)。  
24 -  
25 -## 三、组件 props 契约  
26 -  
27 -| 组件 | props | 类型 | 必填 | 说明 |  
28 -|------|-------|------|------|------|  
29 -{{props_rows}}  
30 -  
31 -## 四、状态管理  
32 -  
33 -<!-- store hook 名 / 持有的 state 字段 / 暴露的 actions。如本 FE 不引入新 store,写"复用 <既有 store>"。 -->  
34 -  
35 -{{state_management}}  
36 -  
37 -## 五、API client 包装  
38 -  
39 -| 函数名 | HTTP 方法 | 路径 | 入参 | 返回 |  
40 -|--------|----------|------|------|------|  
41 -{{api_client_rows}}  
42 -  
43 -> 函数实现必须基于项目统一 API client(见 docs/04 § 一),不允许直接 `fetch` / `axios` 拼路径。  
44 -  
45 -## 六、风险与回退  
46 -  
47 -{{risks}}  
skills/coding/fe-feature-review/SKILL.md deleted
1 ----  
2 -name: fe-feature-review  
3 -description: 前端功能循环第 5 步。AI 自审 FE 的 diff(专用前端 reviewer),approve 则回 frontend-start;request-changes 则自修复 + 重 verify,循环上限 5 轮。  
4 -user-invocable: false  
5 -allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *)  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# fe-feature-review  
11 -  
12 -委托 `fe-code-reviewer` agent(前端专用 reviewer,不复用 superpower-code-reviewer)对当前 FE 引入的代码改动做 AI 自审。`approve` 回 frontend-start 推进下一 FE;`request-changes` 自修复 must-fix 并重新 verify,最多 5 轮。  
13 -  
14 -## 执行步骤  
15 -  
16 -1. 派发 `Agent(subagent_type=fe-code-reviewer)`,把本 FE 引入的代码 diff、规格(`docs/superpowers/specs/<date>-<fe_id>.md`)、本 FE 关联的所有 prototype 文件(spec 顶部的 `关联原型` 列表)作为输入。  
17 -  
18 -2. 按 `${CLAUDE_SKILL_DIR}/templates/fe-feature-review-template.md` 渲染审阅报告,写入 `docs/superpowers/reviews/<YYYY-MM-DD>-<fe_id>.md`。`verdict` 取 `approve` 或 `request-changes`。  
19 -  
20 -3. 按 `verdict` 分派:  
21 -  
22 - **approve**  
23 - - `Edit docs/08-模块任务管理.md § 三`,把本 FE 下 `- [ ] <fe_id> ...` 改为 `- [x] <fe_id> ...`(仅 FE 级可视化;前端阶段完成仍以 `整体里程碑:` 字段 + 本地 `git tag -l` 为准)  
24 - - 输出 `fe-feature-review: <fe_id> round <N> 通过`,调用 `Skill(frontend-start)` 推进下一 FE 或进入 test-gate(phase=frontend)  
25 -  
26 - **request-changes(round < 5)**  
27 - - 逐项编辑 `must_fix[]` 指向的代码文件  
28 - - 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit:`fix(<scope>): 修复 review round <N> must-fix REQ_ID: <fe_id>`  
29 - - 调用 `Skill(fe-feature-verify)` 重新验证;verify 通过后会再次链回本 skill,round `<N+1>` 重审  
30 -  
31 - **request-changes(round == 5)**  
32 - - 停止并打印摘要,升级给用户手工介入;不再自动修复,不回调 frontend-start  
33 -  
34 -## 参考  
35 -  
36 -- `${CLAUDE_SKILL_DIR}/templates/fe-feature-review-template.md`  
37 -- `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md`  
38 -- 委托:`fe-code-reviewer` agent(本插件 `agents/fe-code-reviewer.md`,前端专用,硬编码 7 维 review checklist)  
39 -- 上游:`fe-feature-verify`  
40 -- 下游:`frontend-start`(approve)/ `fe-feature-verify`(request-changes 时重验)  
skills/coding/fe-feature-review/templates/fe-feature-review-template.md deleted
1 ----  
2 -fe_id: {{fe_id}}  
3 -date: {{date}}  
4 -round: {{round}}  
5 -reviewer: fe-code-reviewer  
6 ----  
7 -  
8 -# Review: {{fe_id}} — round {{round}}  
9 -  
10 -## 结论  
11 -{{verdict}} (approve / request-changes)  
12 -  
13 -## Must-fix  
14 -{{#each must_fix}}  
15 -- [{{severity}}] {{file}}:{{line}} — {{issue}}(建议:{{suggestion}})  
16 -{{/each}}  
17 -  
18 -## Nice-to-have  
19 -{{#each nice_to_have}}  
20 -- {{file}}:{{line}} — {{suggestion}}  
21 -{{/each}}  
22 -  
23 -## 维度核查(fe-code-reviewer 7 维)  
24 -  
25 -| # | 维度 | 状态 | 备注 |  
26 -|---|------|------|------|  
27 -| 1 | prototype 一致性 | {{dim_prototype}} | {{dim_prototype_note}} |  
28 -| 2 | Design Tokens | {{dim_tokens}} | {{dim_tokens_note}} |  
29 -| 3 | 无障碍 | {{dim_a11y}} | {{dim_a11y_note}} |  
30 -| 4 | 响应式 | {{dim_responsive}} | {{dim_responsive_note}} |  
31 -| 5 | 业务校验前端复刻 | {{dim_validation}} | {{dim_validation_note}} |  
32 -| 6 | API 调用一致性 | {{dim_api}} | {{dim_api_note}} |  
33 -| 7 | 状态机覆盖 | {{dim_state}} | {{dim_state_note}} |  
34 -  
35 -## 反例 / 测试覆盖缺口  
36 -  
37 -{{gaps}}  
skills/coding/fe-feature-tdd/SKILL.md deleted
1 ----  
2 -name: fe-feature-tdd  
3 -description: 前端功能循环第 3 步。按 plan 逐任务做 TDD(失败测试 → 实现 → 通过 → commit),组件测试用 jsdom,E2E 派子会话跑 Playwright。  
4 -user-invocable: false  
5 -allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *)  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# fe-feature-tdd  
11 -  
12 -按 plan 文件逐任务做 TDD:写失败测试 → 写最小实现 → 确认通过 → commit。**所有测试运行强制派发到 Agent 子会话**,主会话只接收 JSON 结果。  
13 -  
14 -## 路径护栏(前端阶段)  
15 -  
16 -- 任务的 `impl_file` 路径若**不以** `frontend/`(或项目实际前端根目录,从 `docs/09-项目目录结构.md § 前端目录结构` 取)开头 → 硬停并打印:`fe-feature-tdd 不允许写非前端文件:<impl_file>。前端阶段任务的 impl_file 必须落在前端目录下。`  
17 -- 命中 `backend/` / `sql/` / `scripts/` → 同上硬停  
18 -- 不允许在主会话直接 `pnpm playwright` / `pnpm test` / `pnpm e2e`,必须派发子会话  
19 -  
20 -## 执行步骤  
21 -  
22 -1. 加载计划文件 `docs/superpowers/plans/<YYYY-MM-DD>-<fe_id>.md`。  
23 -  
24 -2. 从 `docs/04-技术规范.md § 零 frontend` 取测试栈:  
25 - - `frontend.unit_test_runner`:vitest / jest(默认 vitest)  
26 - - `frontend.e2e_runner`:playwright(默认 playwright)  
27 - - `frontend.test_command` / `frontend.e2e_command`:执行命令(缺失则用 `pnpm test:ci` / `pnpm e2e:ci`)  
28 -  
29 -3. 按顺序处理每个任务:  
30 -  
31 - a. 在 `test_file::test_name` 处写**失败**测试:  
32 - - `测试先行类型 = jsdom`:在 jsdom 环境下用 vitest/jest 写组件单测(render + 断言 DOM / 交互后状态变化)  
33 - - `测试先行类型 = e2e`:在 `frontend/e2e/` 写 Playwright 测试(headless)  
34 -  
35 - b. 派发 Agent 子会话(general-purpose)运行该测试,子会话只返回 `{command, exit_code, failing_assertion}` JSON,确认失败。  
36 -  
37 - c. 在 `impl_file` 处写**最小**实现使测试通过。**严格遵守**:  
38 - - 路径必须以 `frontend/`(或 docs/09 声明的前端根)开头(违反 → 硬停,见护栏)  
39 - - 色值用 `var(--color-*)`(来自 spec § 六),不硬编码 hex  
40 - - 业务校验按 spec § 五 在 form-level 复刻  
41 -  
42 - d. 再次派发子会话确认通过。  
43 -  
44 - e. 同一测试 >10 次修复仍失败 → 调用 `Skill(interrupt-check)`(中断 #1:测试反复失败)。  
45 -  
46 - f. 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit:  
47 - - `scope` = 任务模块(如组件名 `dashboard` / `user-form`)  
48 - - `subject` ≤ 50 字符  
49 - - 必含 trailer `REQ_ID: <fe_id>`(如 `REQ_ID: FE-01`)  
50 -  
51 -4. 全部任务完成 → 调用 `Skill(fe-feature-verify)`。  
52 -  
53 -## 护栏  
54 -  
55 -- **绝不**在主会话直接跑 `pnpm test` / `pnpm e2e` / `pnpm playwright`,必须通过子会话  
56 -- **绝不**在 `impl_file` 中写非 `frontend/` 路径(路径护栏会硬停)  
57 -- 每次 commit 必须含 `REQ_ID: FE-NN` trailer;不混合无关改动到同一 commit  
58 -- 不硬编码颜色 hex;token 引用必须对齐 spec § 六  
59 -  
60 -## 参考  
61 -  
62 -- `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md`  
63 -- 守门:`interrupt-check`(仅在步骤 3.e 触发,条件 1)  
64 -- 上游:`fe-feature-plan`  
65 -- 下游:`fe-feature-verify`  
skills/coding/fe-feature-tdd/templates/commit-message-template.md deleted
1 -{{type}}({{scope}}): {{subject}} {{req_id}}  
skills/coding/fe-feature-verify/SKILL.md deleted
1 ----  
2 -name: fe-feature-verify  
3 -description: 前端功能循环第 4 步。把 FE 的组件测试 + E2E 派发到子会话执行,按模板渲染证据。无证据不声称完成。  
4 -user-invocable: false  
5 -allowed-tools: Skill Read Agent  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# fe-feature-verify  
11 -  
12 -把当前 FE 的测试派发到 Agent 子会话执行,按模板把结构化结果渲染成证据。**主会话从不直接跑测试**,也不自由编写证据。  
13 -  
14 -## 执行步骤  
15 -  
16 -1. 从 plan 文件确定本 FE 的测试目标:  
17 - - 单测目标:plan § 二中所有 `测试先行类型 = jsdom` 的 test_file 列表 → 拼成 vitest/jest 过滤模式  
18 - - E2E 目标:所有 `测试先行类型 = e2e` 的 test_file 列表 → 拼成 Playwright spec 过滤模式  
19 -  
20 -2. 派发 Agent 子会话(general-purpose)依次运行两个目标,子会话只返回结构化 JSON(不输出描述文字):  
21 -  
22 - ```json  
23 - {  
24 - "unit": {  
25 - "command": "<vitest/jest 命令>",  
26 - "exit_code": <int>,  
27 - "passed": <int>,  
28 - "failed": <int>,  
29 - "failed_list": ["<test>", ...],  
30 - "stdout_excerpt": "<最后 30 行或最相关的失败片段>"  
31 - },  
32 - "e2e": {  
33 - "command": "<playwright 命令>",  
34 - "exit_code": <int>,  
35 - "passed": <int>,  
36 - "failed": <int>,  
37 - "failed_list": ["<spec>", ...],  
38 - "stdout_excerpt": "<最后 30 行或最相关的失败片段>"  
39 - }  
40 - }  
41 - ```  
42 -  
43 - 命令从 `docs/04-技术规范.md § 零 frontend.test_command` / `frontend.e2e_command` 取,缺失则用默认 `pnpm test:ci` / `pnpm e2e:ci`。  
44 -  
45 -3. 按 `${CLAUDE_SKILL_DIR}/templates/fe-feature-verify-evidence-template.md` 渲染证据并打印到会话。  
46 -  
47 -4. **任一目标 `exit_code != 0` 或 `failed > 0`** → 停止,不进入 review。  
48 -  
49 -5. 全部通过 → 调用 `Skill(fe-feature-review)`。  
50 -  
51 -## 护栏  
52 -  
53 -- **绝不**在主会话直接跑测试,必须通过子会话  
54 -- **绝不**自由编写证据正文,必须从模板渲染  
55 -- 不要把原始 stdout 全文塞进主会话(`stdout_excerpt` ≤ 30 行)  
56 -  
57 -## 参考  
58 -  
59 -- `${CLAUDE_SKILL_DIR}/templates/fe-feature-verify-evidence-template.md`  
60 -- 上游:`fe-feature-tdd`  
61 -- 下游:`fe-feature-review`  
skills/coding/fe-feature-verify/templates/fe-feature-verify-evidence-template.md deleted
1 -## Verify evidence — {{fe_id}}  
2 -  
3 -### 单元测试(jsdom)  
4 -  
5 -- 命令: `{{unit.command}}`  
6 -- 子会话: {{unit.subagent_id}}  
7 -- 退出码: {{unit.exit_code}}  
8 -- 通过用例数: {{unit.passed}}  
9 -- 失败用例数: {{unit.failed}}  
10 -- 失败列表: {{unit.failed_list}}  
11 -  
12 -关键 stdout 片段 (≤30 行):  
13 -  
14 -```  
15 -{{unit.stdout_excerpt}}  
16 -```  
17 -  
18 -### E2E 测试(Playwright)  
19 -  
20 -- 命令: `{{e2e.command}}`  
21 -- 子会话: {{e2e.subagent_id}}  
22 -- 退出码: {{e2e.exit_code}}  
23 -- 通过用例数: {{e2e.passed}}  
24 -- 失败用例数: {{e2e.failed}}  
25 -- 失败列表: {{e2e.failed_list}}  
26 -  
27 -关键 stdout 片段 (≤30 行):  
28 -  
29 -```  
30 -{{e2e.stdout_excerpt}}  
31 -```  
32 -  
33 -结论: {{conclusion}} (pass = 两段都 pass / fail = 任一 fail)  
skills/coding/feature-brainstorm/SKILL.md deleted
1 ----  
2 -name: feature-brainstorm  
3 -description: 功能循环第 1 步。针对单个 REQ-XXX-NNN 做交互式 Q&A + 写规格,产出到 docs/superpowers/specs/,链入 feature-plan。  
4 -user-invocable: false  
5 -allowed-tools: Read Write Skill AskUserQuestion Bash(mysql *)  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# feature-brainstorm  
11 -  
12 -## 阶段范围(后端)  
13 -  
14 -本 skill 服务于**后端阶段**。产出范围限定为 controller / service / repository / DTO / 校验 / SQL migration / REST 契约。读 docs/01 REQ 卡片时**忽略 UI 描述**(输入控件类型、按钮位置、列表布局等),但**校验规则、业务规则**仍要落到后端 DTO + service。UI 实现统一推迟到前端阶段(fe-feature-*)。  
15 -  
16 -## 占位符规则  
17 -  
18 -本 skill 写的 spec 是 CC 内部推理产物,不是用户审阅文档。**不允许** `【人工填写:...】` 占位符——A 阶段 `docs/01~10` / `CLAUDE.md` / `.env.local` 才用那个标记。需要具体值时:  
19 -  
20 -1. **先查** `.env.local` / `docs/07-环境配置.md` / `CLAUDE.md` / 现有代码。值已落地某处 → 在 spec 中引用源(例 "JWT_SECRET 从 `.env.local` 读取,`application.yml` 用 `${JWT_SECRET}` 注入")  
21 -2. **再问**:查不到 → `AskUserQuestion` 问用户,记录答案到 spec  
22 -3. **绝不**留 `【人工填写:】` 占位符;若 1 + 2 都解决不了,spec 必须写出具体阻塞点(不是泛化的人工填写标记),Q&A 继续直到解决  
23 -  
24 -## 执行步骤  
25 -  
26 -1. **收集上下文**:确定本次 REQ-XXX-NNN(由 module-start 派发时指定),读取:  
27 - - REQ 卡片 `docs/01-需求清单/<module>/<req_id>.md`  
28 - - 涉及的数据表定义(取自 docs/03 或实时 mysql 查询)  
29 -  
30 -2. **交互式 Q&A**(参考下方"Q&A 原则"):  
31 - - **先评估 scope**:单 spec 容纳得下吗?跨多个独立子系统(如"含登录 + 文件存储 + 计费 + 分析")→ 先提示分解,每个子项目独立 brainstorm  
32 - - **一次一问** `AskUserQuestion`,仅对真模糊点;多选题优先  
33 - - 决策完成后挑一种 approach;trade-off 直接内嵌 spec,**不设确认 gate**  
34 -  
35 -3. **写 spec 到 `docs/superpowers/specs/<YYYY-MM-DD>-<REQ-id>.md`**:  
36 - - 按 `${CLAUDE_SKILL_DIR}/templates/feature-spec-template.md` 渲染  
37 - - 覆盖:goal / 输入输出 / 业务规则 / 约束 / schema / API 引用 / acceptance criteria  
38 - - 文件已存在 → 征求用户确认后覆盖  
39 -  
40 -4. **Spec 自审**(inline 修,无须用户等待):  
41 - - **占位符扫描**:`TBD` / `TODO` / `【人工填写:】` / 含糊段 → 修(按"占位符规则"流程解决)  
42 - - **内部一致性**:节与节是否矛盾?架构是否匹配功能描述?  
43 - - **范围检查**:单 plan 能消化吗?还是需要分解  
44 - - **歧义检查**:任何 requirement 两种解读?挑一个写明  
45 -  
46 - fix inline,无须 re-review。  
47 -  
48 -5. **输出 + 链 feature-plan**(**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号):  
49 - - 输出一行 `feature-brainstorm: <REQ> → <path>`  
50 - - **同一 turn 内立即** `Skill(feature-plan)`  
51 -  
52 -## Q&A 原则  
53 -  
54 -- **一次一问** — 不堆问题  
55 -- **多选题优先** — 答更快  
56 -- **仅对真模糊点问** — 不造确认问题  
57 -- **YAGNI** — 删 spec 中不必要的功能  
58 -- **渐进理解** — 不明白就问  
59 -- **无审批 gate** — 写 spec 即 commit;分歧落地为具体 Q&A 项,不靠"等用户确认"  
60 -  
61 -## 参考  
62 -  
63 -- `${CLAUDE_SKILL_DIR}/templates/feature-spec-template.md`  
64 -- 上游:`module-start`  
65 -- 下游:`feature-plan`  
skills/coding/feature-brainstorm/templates/feature-spec-template.md deleted
1 ----  
2 -req_id: {{req_id}}  
3 -date: {{date}}  
4 -module: {{module}}  
5 ----  
6 -  
7 -# Spec: {{req_id}} — {{title}}  
8 -  
9 -## 目标  
10 -{{goal}}  
11 -  
12 -## 输入 / 触发  
13 -{{input}}  
14 -  
15 -## 输出 / 结果  
16 -{{output}}  
17 -  
18 -## 业务规则  
19 -{{rules}}  
20 -  
21 -## 边界与约束  
22 -{{constraints}}  
23 -  
24 -## 依赖的 schema 表 / 字段  
25 -{{schema_refs}}  
26 -  
27 -## 依赖的接口  
28 -{{api_refs}}  
29 -  
30 -## 验收标准  
31 -{{acceptance}}  
skills/coding/feature-plan/SKILL.md deleted
1 ----  
2 -name: feature-plan  
3 -description: 功能循环第 2 步。将 spec 转任务级 TDD 计划(每任务 2-5 分钟),产出到 docs/superpowers/plans/,链入 feature-tdd。  
4 -user-invocable: false  
5 -allowed-tools: Read Write Grep Skill AskUserQuestion  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# feature-plan  
11 -  
12 -## 阶段范围(后端)  
13 -  
14 -本 skill 服务于**后端阶段**。任务粒度限定为后端模块文件:controller / service / repository / DTO / 校验 / SQL migration。**禁止**生成 `frontend/` 路径下的实现任务——UI 实现统一推迟到前端阶段(fe-feature-*)。  
15 -  
16 -## 计划写作原则  
17 -  
18 -- Plan 告诉 TDD 执行者**做什么**,不是**怎么写代码**——执行者是 `feature-tdd`(同一模型,全上下文),不是机械复制粘贴员  
19 -- Plan 锁定**文件边界 + 测试意图 + API 形状 + 完成判据**;代码由 TDD 红绿循环产出  
20 -- **禁止 dump 整个文件内容**(pom.xml / entity 类 / config 文件)到 plan——plan 和代码会成为两个 source of truth 并漂移;2000+ 行 plan 浪费上下文  
21 -- DRY、YAGNI、TDD、frequent commits  
22 -  
23 -## 占位符规则  
24 -  
25 -每个 step 必须写实际内容。以下属于 **plan failures**,绝不出现:  
26 -  
27 -- `TBD` / `TODO` / `implement later` / `fill in details`  
28 -- **`【人工填写:】`** — 这是 A 阶段标记(`docs/01~10` / `CLAUDE.md` / `.env.local`),B 阶段 plan **绝不能出现**。需要具体值时:  
29 - 1. 先查 `.env.local` / `docs/07-环境配置.md` / `CLAUDE.md` / 现有代码并在 plan 中引用源  
30 - 2. 否则 `AskUserQuestion` 问用户并记录答案  
31 -- "Add appropriate error handling" / "add validation"(要具体到哪些错误码 / 哪些字段)  
32 -- "Similar to Task N"(相似任务各自写清楚测试意图 + 完成判据,不互相链接)  
33 -- 未在任何 task 定义的 types / functions / methods(类/方法首次出现的 task 必须给出 API 签名)  
34 -  
35 -> 散文级"做什么"是 OK 的——执行器(`feature-tdd`)会在 TDD 循环里决定"怎么写"。plan 的义务是**约束范围**,不是**替 TDD 写代码**。  
36 -  
37 -## 执行步骤  
38 -  
39 -1. **收集输入**:  
40 - - spec 文件 `docs/superpowers/specs/<YYYY-MM-DD>-<REQ-id>.md`(不存在则报错)  
41 - - 相关代码指针(通过 `Grep` 在现有代码定位待修改文件)  
42 - - `docs/04-技术规范.md` 与 `docs/09-项目目录结构.md`(编码规范 + 目录规范)  
43 -  
44 -2. **范围检查**:spec 跨多个独立子系统 → 提示拆分,每个 plan 应能独立产出可工作、可测试的软件  
45 -  
46 -3. **文件结构推导**:  
47 - - 哪些文件 create / modify  
48 - - 每个文件单一职责,well-defined interface  
49 - - 一起变化的文件放一起;不按技术层切分  
50 -  
51 -4. **任务粒度推导**(参考下方"任务原则"):  
52 - - 每个任务 = 一个 red-green-commit 单元  
53 - - 4 个 step:写失败测试 → 实现最小代码 → 子会话验证 PASS → commit  
54 - - 任务粒度 2-5 分钟  
55 -  
56 -5. **写 plan 到 `docs/superpowers/plans/<YYYY-MM-DD>-<REQ-id>.md`**:  
57 - - 按 `${CLAUDE_SKILL_DIR}/templates/feature-plan-template.md` 渲染  
58 - - 文件已存在 → 征求用户确认后覆盖  
59 -  
60 -6. **Plan 自审**(inline 修,无须用户等待):  
61 - - **占位符扫描**:按"占位符规则"清单逐项 grep;命中即修  
62 - - **Spec coverage**:skim spec 每节,能指向至少一个 task 吗?list gaps 并补 task  
63 - - **类型一致性**:tasks 之间签名 / 方法名 / 属性名 / 错误码是否一致(Task 3 的 `clearLayers()` 和 Task 7 的 `clearFullLayers()` 是 bug)  
64 -  
65 -7. **输出 + 链 feature-tdd**(**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号):  
66 - - 输出一行 `feature-plan: <REQ> → <path>`  
67 - - **同一 turn 内立即** `Skill(feature-tdd)`  
68 -  
69 -## 任务原则  
70 -  
71 -### Plan 文件头  
72 -  
73 -每个 plan 必须以以下头部开始:  
74 -  
75 -```markdown  
76 -# [Feature Name] Implementation Plan  
77 -  
78 -> **Execution:** Parent skill `feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.  
79 -  
80 -**Goal:** [一句话描述]  
81 -  
82 -**Architecture:** [2-3 句方法论]  
83 -  
84 -**Tech Stack:** [关键技术 / 库]  
85 -  
86 ----  
87 -```  
88 -  
89 -### Task 结构  
90 -  
91 -每个 task 是 red-green-commit 单元。捕获意图和边界,代码留给 TDD:  
92 -  
93 -````markdown  
94 -### Task N: [组件名]  
95 -  
96 -**Files:**  
97 -- Create: `exact/path/to/File.java`  
98 -- Modify: `exact/path/to/Existing.java:123-145`  
99 -- Test: `tests/exact/path/to/FileTest.java`  
100 -  
101 -**API shape**(只写需要约束实现的签名;内部实现留给 TDD):  
102 -- `LoginService#login(LoginRequest req) : LoginResponse`  
103 -- `throws AccountLockedException when iLoginFailCount ≥ 5 within tLockUntil window`  
104 -  
105 -- [ ] **Step 1: 写失败测试**  
106 - - 测试名: `LoginServiceTest#loginWithBadPassword_incrementsFailCount_returns40101`  
107 - - 意图: 错误密码 → `iLoginFailCount += 1`;第 5 次 → 设置 `tLockUntil = now + 15min`;返回码 40101  
108 - - 子会话确认 FAIL(函数/类不存在)  
109 -  
110 -- [ ] **Step 2: 实现最小代码**  
111 - - 目标: 让 Step 1 测试通过;不多做  
112 - - 涉及文件: `LoginService.java`, `SftLoginInfoMapper.java`  
113 -  
114 -- [ ] **Step 3: 子会话验证 PASS**  
115 -  
116 -- [ ] **Step 4: Commit**  
117 - - `git add <文件>`  
118 - - `git commit -m "feat(sys): 登录失败计数 + 锁定 REQ-SYS-001"`  
119 -````  
120 -  
121 -### 允许的代码块场景  
122 -  
123 -少数例外,需要写死而非让 TDD 自由发挥:  
124 -  
125 -- **DDL / migration 文件**:`V_n__*.sql` 的 ALTER/CREATE 语句——schema 是事实源、不是 TDD 红绿产物  
126 -- **合同级常量**:API 错误码表、JWT claim 名、Redis key 模式——跨模块消费,必须在 plan 锁定  
127 -- **测试断言形状**(可选):一句话说不清"测什么"时,给个 3-5 行断言 sketch 是 OK 的  
128 -  
129 -除此之外一律散文 + 签名描述,**不贴完整文件**。  
130 -  
131 -### 记住  
132 -  
133 -- Exact file paths always  
134 -- Exact commands with expected output(测试运行 + git 操作)  
135 -- API signatures / class names / error codes / contract values — **必须写死**  
136 -- Internal implementation code — **不写**;留给 TDD 阶段  
137 -- DRY、YAGNI、TDD、frequent commits  
138 -  
139 -## 参考  
140 -  
141 -- `${CLAUDE_SKILL_DIR}/templates/feature-plan-template.md`  
142 -- 上游:`feature-brainstorm`  
143 -- 下游:`feature-tdd`  
skills/coding/feature-plan/templates/feature-plan-template.md deleted
1 ----  
2 -req_id: {{req_id}}  
3 -date: {{date}}  
4 -spec_ref: docs/superpowers/specs/{{date}}-{{req_id}}.md  
5 ----  
6 -  
7 -# Plan: {{req_id}}  
8 -  
9 -## Schema 改动  
10 -{{schema_change_decision}} <!-- "无" 或 "需要 migration:V<n>__<snake_case>.sql,作用:<一行描述>" -->  
11 -  
12 -## 文件变更清单  
13 -{{#each files}}  
14 -- `{{path}}` — {{action}}({{rationale}})  
15 -{{/each}}  
16 -  
17 -## 任务步骤  
18 -{{#each tasks}}  
19 -### Task {{index}}: {{title}}  
20 -- 失败测试: `{{test_file}}::{{test_name}}` — {{test_intent}}  
21 -- 实现路径: `{{impl_file}}`  
22 -- 完成判据: {{done_when}}  
23 -{{/each}}  
24 -  
25 -## 提交计划  
26 -{{#each commits}}  
27 -- `{{message}}`(覆盖 Task {{task_index}})  
28 -{{/each}}  
skills/coding/feature-review/SKILL.md
1 --- 1 ---
2 name: feature-review 2 name: feature-review
3 -description: 功能循环第 5 步。AI 自审 REQ 的 diff,approve 则回调 module-start;request-changes 则自修复 + 重 verify,循环上限 5 轮。 3 +description: 统一功能循环第 3 步(后端 REQ / 前端 FE 共用,由 phase 参数区分)。先派子会话跑验证测试(verify 阶段),通过后再派相应 reviewer agent 做 AI 自审(review 阶段),approve 回 phase-driver;request-changes 自修复 + 重验,最多 5 轮。
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *) 5 allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *)
6 --- 6 ---
@@ -9,29 +9,128 @@ allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *) @@ -9,29 +9,128 @@ allowed-tools: Read Write Edit Skill Agent Bash(git add *) Bash(git commit *)
9 9
10 # feature-review 10 # feature-review
11 11
12 -委托 `superpower-code-reviewer` agent 对当前 REQ 引入的代码改动做 AI 自审,渲染审阅报告。`approve` 回模块主循环;`request-changes` 则自修复 must-fix 并重新 verify,最多 5 轮。 12 +统一功能循环第 3 步(verify + review 合并)。先派子会话运行功能测试(verify 阶段),通过后再委托对应 reviewer agent 做 AI 自审(review 阶段),渲染合并报告。`approve` 回 `phase-driver` 推进;`request-changes` 自修复 must-fix 并从 verify 阶段重新开始,最多 5 轮。
  13 +
  14 +**入参(由 feature-tdd 传入):**
  15 +- `phase`:`backend` | `frontend`
  16 +- `id`:`REQ-XXX-NNN`(backend)或 `FE-NN`(frontend)
  17 +
  18 +内部维护 `round` 计数器(首次 = 1)。
  19 +
  20 +---
  21 +
  22 +## 阶段差异
  23 +
  24 +| 项目 | phase=backend | phase=frontend |
  25 +|------|-------------|----------------|
  26 +| 测试目标 | `./scripts/test.sh`(plan 确认)| vitest/jest 单测 + Playwright E2E(从 `docs/04 §零 frontend.test_command` / `frontend.e2e_command` 取;缺失用 `pnpm test:ci` / `pnpm e2e:ci`)|
  27 +| 测试 JSON 结构 | 单层 JSON(见"验证阶段")| 两层 JSON:`unit` + `e2e`(见"验证阶段")|
  28 +| Reviewer agent | `superpower-code-reviewer` | `fe-code-reviewer` |
  29 +| approve 写 docs/08 | §二 该 REQ 行 `[ ]`→`[x]` | §三 该 FE 行 `[ ]`→`[x]` |
  30 +| approve 输出 | `feature-review: <REQ> round <N> 通过` | `feature-review: <FE-NN> round <N> 通过` |
  31 +
  32 +---
13 33
14 ## 执行步骤 34 ## 执行步骤
15 35
16 -1. 派发 `Agent(subagent_type=superpower-code-reviewer)`,把本 REQ 引入的代码 diff 与规格作为输入。  
17 -2. 按 `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md` 渲染审阅报告,写入 `docs/superpowers/reviews/<YYYY-MM-DD>-<REQ-id>.md`。`verdict` 取 `approve` 或 `request-changes`。  
18 -3. 按 `verdict` 分派: 36 +### 阶段一:验证(Verify)
  37 +
  38 +1. **确定测试目标**:
  39 + - `phase=backend`:从 plan 文件或项目标准命令确定(如 Maven profile / `scripts/test.sh` path)
  40 + - `phase=frontend`:从 `docs/04-技术规范.md § 零 frontend` 取测试栈和测试命令;按 plan 中 task 的"测试先行类型"拆分单测目标(jsdom)和 E2E 目标(playwright)
  41 +
  42 +2. **派发 Agent 子会话(general-purpose)** 运行测试目标,子会话只返回结构化 JSON(不输出描述文字):
  43 +
  44 + `phase=backend`:
  45 + ```json
  46 + {
  47 + "command": "<cmd>",
  48 + "exit_code": <int>,
  49 + "passed": <int>,
  50 + "failed": <int>,
  51 + "failed_list": ["<test>", ...],
  52 + "stdout_excerpt": "<最后 30 行或最相关的失败片段>"
  53 + }
  54 + ```
  55 +
  56 + `phase=frontend`:
  57 + ```json
  58 + {
  59 + "unit": {
  60 + "command": "<vitest/jest 命令>",
  61 + "exit_code": <int>,
  62 + "passed": <int>,
  63 + "failed": <int>,
  64 + "failed_list": ["<test>", ...],
  65 + "stdout_excerpt": "<最后 30 行>"
  66 + },
  67 + "e2e": {
  68 + "command": "<playwright 命令>",
  69 + "exit_code": <int>,
  70 + "passed": <int>,
  71 + "failed": <int>,
  72 + "failed_list": ["<spec>", ...],
  73 + "stdout_excerpt": "<最后 30 行>"
  74 + }
  75 + }
  76 + ```
  77 +
  78 +3. 渲染 `## 验证证据` 节(填入 `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md` 的 verify 部分)。
  79 +
  80 +4. **`exit_code != 0` 或 `failed > 0`**(任一目标失败)→ **停止,不进入 review 阶段**。等待下轮或用户介入。
  81 +
  82 +5. 全部通过 → 进入 review 阶段。
  83 +
  84 +---
  85 +
  86 +### 阶段二:审阅(Review)
  87 +
  88 +6. **派发 reviewer agent**(把本 id 引入的代码 diff 与规格作为输入):
  89 + - `phase=backend` → `Agent(subagent_type=superpower-code-reviewer)`
  90 + - `phase=frontend` → `Agent(subagent_type=fe-code-reviewer)`(同时提供规格文件 + 关联 prototype 文件列表,见 spec 顶部 `关联原型`)
  91 +
  92 +7. 渲染 `## 自审结论` 节(填入 `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md` 的 review 部分),写入合并报告 `docs/superpowers/reviews/<YYYY-MM-DD>-<id>.md`。`verdict` 取 `approve` 或 `request-changes`。
  93 +
  94 +---
  95 +
  96 +### 阶段三:按 verdict 分派
  97 +
  98 +**approve**
19 99
20 - **approve**  
21 - - `Edit docs/08-模块任务管理.md § 二`,把本模块下 `- [ ] <REQ-id> ...` 改为 `- [x] <REQ-id> ...`(仅功能级可视化;模块完成仍以 `里程碑:` 字段 + 本地 `git tag -l` 为准,不依赖此勾选)  
22 - - 输出 `feature-review: <REQ> round <N> 通过`,调用 `Skill(module-start)` 100 +- `Edit docs/08-模块任务管理.md`:
  101 + - `phase=backend`:在 §二 找 `- [ ] <REQ-id> ...` 改为 `- [x] <REQ-id> ...`
  102 + - `phase=frontend`:在 §三 找 `- [ ] <fe_id> ...` 改为 `- [x] <fe_id> ...`
  103 + - (仅功能级可视化;模块 / 阶段完成仍以 `里程碑:` 字段 + 本地 `git tag -l` 为准,不依赖此勾选)
  104 +- 输出状态行(见上方阶段差异表),调用 `Skill(phase-driver)` 传入 `{ phase }`
23 105
24 - **request-changes(round < 5)**  
25 - - 逐项编辑 `must_fix[]` 指向的代码文件  
26 - - 按 `feature-tdd/templates/commit-message-template.md` 格式 commit:`fix(<module_id>): 修复 review round <N> must-fix <REQ-id>`  
27 - - 调用 `Skill(feature-verify)` 重新验证;verify 通过后会再次链回本 skill,round `<N+1>` 重审 106 +**request-changes(round < 5)**
28 107
29 - **request-changes(round == 5)**  
30 - - 停止并打印摘要,升级给用户手工介入;不再自动修复,不回调 module-start 108 +- 逐项编辑 `must_fix[]` 指向的代码文件
  109 +- 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit:
  110 + `fix(<module_id 或 scope>): 修复 review round <N> must-fix <id>`
  111 +- **重新执行本 skill 的验证阶段**(阶段一);通过后进入 round `<N+1>` 的 review 阶段
  112 +
  113 +**request-changes(round == 5)**
  114 +
  115 +- 停止并打印摘要(本 id、5 轮 must-fix 列表汇总),升级给用户手工介入
  116 +- 不再自动修复,不回调 `phase-driver`
  117 +
  118 +---
  119 +
  120 +## 护栏
  121 +
  122 +- **绝不**在主会话直接跑测试,必须通过子会话
  123 +- **绝不**自由编写证据正文,必须从模板渲染
  124 +- 不要把原始 stdout 全文塞进主会话(`stdout_excerpt` ≤ 30 行)
  125 +- verify 失败(exit_code≠0 或 failed>0)→ 硬停,不进 review
  126 +
  127 +---
31 128
32 ## 参考 129 ## 参考
33 130
34 -- `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md`  
35 -- 委托:`superpower-code-reviewer`(本插件 `agents/superpower-code-reviewer.md`)  
36 -- Fix commit 格式与 `feature-tdd/templates/commit-message-template.md` 一致  
37 -- 上游:`feature-verify`;下游:`module-start`(approve)/ `feature-verify`(request-changes) 131 +- `${CLAUDE_SKILL_DIR}/templates/feature-review-template.md`(verify 证据 + review 结论合并文档)
  132 +- `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md`(fix commit 格式)
  133 +- 委托:`superpower-code-reviewer`(backend,本插件 `agents/superpower-code-reviewer.md`)
  134 +- 委托:`fe-code-reviewer`(frontend,本插件 `agents/fe-code-reviewer.md`,前端专用,硬编码 7 维 review checklist)
  135 +- 上游:`feature-tdd`
  136 +- 下游:`phase-driver`(approve)/ 本 skill 验证阶段(request-changes 重验)
skills/coding/fe-feature-review/templates/commit-message-template.md renamed to skills/coding/feature-review/templates/commit-message-template.md
skills/coding/feature-review/templates/feature-review-template.md
1 --- 1 ---
2 req_id: {{req_id}} 2 req_id: {{req_id}}
3 date: {{date}} 3 date: {{date}}
  4 +phase: {{phase}}
4 round: {{round}} 5 round: {{round}}
5 -reviewer: superpower-code-reviewer  
6 --- 6 ---
7 7
8 -# Review: {{req_id}} — round {{round}} 8 +# 验证 + 审阅:{{req_id}} — round {{round}}
9 9
10 -## 结论 10 +## 验证证据
  11 +
  12 +- 命令: `{{command}}`
  13 +- 子会话: {{subagent_id}}
  14 +- 退出码: {{exit_code}}
  15 +- 通过用例数: {{passed}}
  16 +- 失败用例数: {{failed}}
  17 +- 失败列表: {{failed_list}}
  18 +
  19 +关键 stdout 片段 (≤30 行):
  20 +
  21 +```
  22 +{{stdout_excerpt}}
  23 +```
  24 +
  25 +结论: {{verify_conclusion}} (pass / fail)
  26 +
  27 +---
  28 +
  29 +## 自审结论
  30 +
  31 +审阅者: {{reviewer}} <!-- phase=backend → superpower-code-reviewer;phase=frontend → fe-code-reviewer -->
  32 +
  33 +### 结论
11 {{verdict}} (approve / request-changes) 34 {{verdict}} (approve / request-changes)
12 35
13 -## Must-fix 36 +### Must-fix
14 {{#each must_fix}} 37 {{#each must_fix}}
15 - [{{severity}}] {{file}}:{{line}} — {{issue}}(建议:{{suggestion}}) 38 - [{{severity}}] {{file}}:{{line}} — {{issue}}(建议:{{suggestion}})
16 {{/each}} 39 {{/each}}
17 40
18 -## Nice-to-have 41 +### Nice-to-have
19 {{#each nice_to_have}} 42 {{#each nice_to_have}}
20 - {{file}}:{{line}} — {{suggestion}} 43 - {{file}}:{{line}} — {{suggestion}}
21 {{/each}} 44 {{/each}}
22 45
23 -## 反例 / 测试覆盖缺口 46 +### 反例 / 测试覆盖缺口
24 {{gaps}} 47 {{gaps}}
skills/coding/feature-spec/SKILL.md 0 → 100644
  1 +---
  2 +name: feature-spec
  3 +description: 统一功能循环第 1 步(后端 REQ / 前端 FE 共用,由 phase 参数区分)。交互式 Q&A → 产出"规格 + 任务级 TDD 计划"合并文档到 docs/superpowers/specs/,链入 feature-tdd。
  4 +user-invocable: false
  5 +allowed-tools: Read Write Grep Glob Skill AskUserQuestion Bash(mysql *)
  6 +---
  7 +
  8 +**所有输出必须使用中文。**
  9 +
  10 +# feature-spec
  11 +
  12 +统一功能循环第 1 步,后端(REQ-XXX-NNN)和前端(FE-NN)共用,由 `phase` 参数区分范围与上下文。交互式 Q&A → 产出"规格 + 任务级 TDD 计划"合并文档 → 链入 `feature-tdd`。
  13 +
  14 +**入参(由上游 skill 传入):**
  15 +- `phase`:`backend` | `frontend`
  16 +- `id`:`REQ-XXX-NNN`(backend)或 `FE-NN`(frontend)
  17 +- `name`:功能名称
  18 +- `associated_reqs[]`:(仅 frontend)关联的 REQ 卡片 id 列表
  19 +- `associated_prototypes[]`:(仅 frontend)关联的 prototype 文件路径列表
  20 +
  21 +---
  22 +
  23 +## 占位符规则
  24 +
  25 +本 skill 写的 spec 是 CC 内部推理产物,不是用户审阅文档。**不允许** `【人工填写:...】` 占位符——A 阶段标记只在 `docs/01~10` / `CLAUDE.md` / `.env.local` 使用。需要具体值时:
  26 +
  27 +1. **先查** `.env.local` + `docs/04 §零环境` / `CLAUDE.md` / 现有代码 / 关联 prototype(frontend 时)。值已落地某处 → spec 中引用源(例 "JWT_SECRET 从 `.env.local` 读取,`application.yml` 用 `${JWT_SECRET}` 注入")
  28 +2. **再问**:查不到 → `AskUserQuestion` 问用户,记录答案到 spec
  29 +3. **绝不**留 `【人工填写:】` 占位符;若 1 + 2 都解决不了,spec 必须写出具体阻塞点(不是泛化占位符),Q&A 继续直到解决
  30 +
  31 +---
  32 +
  33 +## 阶段范围
  34 +
  35 +### phase=backend
  36 +
  37 +产出范围限定为:controller / service / repository / DTO / 校验 / SQL migration / REST 契约。
  38 +
  39 +读 `docs/01-需求清单/<module>/<req_id>.md` 时**忽略 UI 描述**(输入控件类型、按钮位置、列表布局等),但**校验规则、业务规则**仍要落到后端 DTO + service。UI 实现统一推迟到前端阶段(`phase=frontend`)。
  40 +
  41 +上下文来源:
  42 +- REQ 卡片 `docs/01-需求清单/<module>/<id>.md`
  43 +- 涉及的数据表定义(取自 `docs/03-数据库设计文档.md` 或实时 `mysql` 查询)
  44 +
  45 +### phase=frontend
  46 +
  47 +产出范围限定为:组件树 / 页面状态机 / 交互流程 / API 调用 / Design Tokens 引用 / 业务校验前端复刻。**不涉及** SQL / migration / controller / service / DTO(后端阶段已完成)。
  48 +
  49 +一个 FE 是**业务功能**粒度,可能关联多个 prototype 文件区域和多个 REQ。
  50 +
  51 +上下文来源:
  52 +- **页面骨架**:Read 所有 `associated_prototypes[]`(含 anchor 时聚焦相应区域),作为布局权威
  53 +- **业务规则**:Read 所有 `associated_reqs[]` 对应的 `docs/01-需求清单/<module>/<REQ-id>.md`,提取业务校验规则、acceptance、UI 描述
  54 +- **API 契约**:Read `docs/05-API接口契约.md`,按 `associated_reqs[]` 过滤出本 FE 消费的端点
  55 +- **Design Tokens**:Read `docs/06-UI交互规范.md § 二`,作为色值 / 状态色的引用源
  56 +- **前端组件库**:Read `docs/04-技术规范.md § 零` 找 `frontend.ui_lib`(如 Ant Design / Element Plus),决定组件选型
  57 +
  58 +---
  59 +
  60 +## 执行步骤
  61 +
  62 +### 步骤 1:收集上下文
  63 +
  64 +按上方"阶段范围"对应的上下文来源读取所有相关文档。
  65 +
  66 +### 步骤 2:评估 scope
  67 +
  68 +- 单 spec 容纳得下吗?
  69 +- `phase=backend`:跨多个独立子系统(如"含登录 + 文件存储 + 计费 + 分析")→ 先提示分解,每个子项目独立 brainstorm
  70 +- `phase=frontend`:跨多页 / 多业务 → 提示拆分,每个 FE 应独立可测试
  71 +
  72 +### 步骤 3:交互式 Q&A
  73 +
  74 +参考下方"Q&A 原则"进行交互式问答:
  75 +
  76 +- `phase=backend`:聚焦 goal / 输入输出 / 业务规则 / 约束 / schema / API 引用 / acceptance criteria
  77 +- `phase=frontend`:聚焦组件树、页面状态机、交互流程、API 调用一致性、Design Tokens 引用、业务校验前端复刻。**不要**讨论 SQL / migration / controller / service / DTO
  78 +
  79 +**一次一问** `AskUserQuestion`,仅对真模糊点;多选题优先。决策完成后挑一种 approach;trade-off 直接内嵌 spec,**不设确认 gate**。
  80 +
  81 +### 步骤 4:写合并文档
  82 +
  83 +写到 `docs/superpowers/specs/<YYYY-MM-DD>-<id>.md`(`id` = `REQ-XXX-NNN` 或 `FE-NN`):
  84 +
  85 +- 按 `${CLAUDE_SKILL_DIR}/templates/feature-spec-plan-template.md` 渲染
  86 +- **只填写当前 phase 对应的规格小节**(另一 phase 的小节留空或删除)
  87 +- 规格后紧接任务级计划(plan 部分)
  88 +- 计划粒度:每任务 2-5 分钟,= 一个 red-green-commit 单元
  89 +
  90 +**计划写作原则(两 phase 通用):**
  91 +- Plan 告诉 TDD 执行者**做什么**,不是**怎么写代码**
  92 +- Plan 锁定**文件边界 + 测试意图 + API / Props 形状 + 完成判据**;代码由 TDD 红绿循环产出
  93 +- **禁止 dump 整个文件内容**到 plan(pom.xml / entity 类 / vue 组件源码 / config 文件)
  94 +- `phase=backend` 任务:`impl_file` 禁止以 `frontend/` 开头;`phase=frontend` 任务:`impl_file` 必须以 `frontend/` 开头
  95 +- 每个任务含 4 步:写失败测试 → 实现最小代码 → 子会话验证 PASS → commit
  96 +- `phase=frontend` 每个任务必须标注"测试先行类型":`jsdom 组件测试` 或 `Playwright E2E`
  97 +
  98 +文件已存在 → 征求用户确认后覆盖。
  99 +
  100 +### 步骤 5:Spec + Plan 自审(inline 修,无须用户等待)
  101 +
  102 +**Spec 部分:**
  103 +- **占位符扫描**:`TBD` / `TODO` / `【人工填写:】` / 含糊段 → 修(按"占位符规则"流程解决)
  104 +- **内部一致性**:节与节是否矛盾?架构是否匹配功能描述?
  105 +- **范围检查**:单 plan 能消化吗?还是需要分解
  106 +- **歧义检查**:任何 requirement 两种解读?挑一个写明
  107 +- `phase=frontend` 额外检查:全文不得出现 `TBD` / `@todo` / `controller` / `SQL` / `service` / `migration` → 命中则修正后重渲染
  108 +
  109 +**Plan 部分:**
  110 +- **占位符扫描**:`TBD` / `TODO` / `implement later` / `fill in details` / `【人工填写:】` → 修
  111 +- **Spec coverage**:skim spec 每节,能指向至少一个 task 吗?list gaps 并补 task
  112 +- **类型一致性**:tasks 之间签名 / 方法名 / 属性名 / 错误码一致(Task 3 的 `clearLayers()` 和 Task 7 的 `clearFullLayers()` 是 bug)
  113 +- `phase=frontend`:每个任务的 `impl_file` 路径必须以 `frontend/` 开头;命中 `backend/` / `sql/` / `scripts/` → 修正后重渲染
  114 +
  115 +### 步骤 6:输出 + 链 feature-tdd
  116 +
  117 +(**直接做这两件事,不要输出"回交父 skill / 交给 caller / 等下一步 / 准备好了请检查"之类的桥接叙述**——那些会被解读为 turn 结束信号)
  118 +
  119 +- 输出一行 `feature-spec: <id> → <path>`
  120 +- **同一 turn 内立即** `Skill(feature-tdd)` 传入 `{ phase, id }`
  121 +
  122 +---
  123 +
  124 +## Q&A 原则
  125 +
  126 +- **一次一问** — 不堆问题
  127 +- **多选题优先** — 答更快
  128 +- **仅对真模糊点问** — 不造确认问题
  129 +- **YAGNI** — 删 spec 中不必要的功能
  130 +- **渐进理解** — 不明白就问
  131 +- **无审批 gate** — 写 spec 即 commit;分歧落地为具体 Q&A 项,不靠"等用户确认"
  132 +
  133 +---
  134 +
  135 +## 任务原则
  136 +
  137 +### Plan 文件头
  138 +
  139 +每个合并文档的 plan 部分必须以以下头部开始:
  140 +
  141 +```markdown
  142 +# [Feature Name] Implementation Plan
  143 +
  144 +> **Execution:** Parent skill `feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
  145 +
  146 +**Goal:** [一句话描述]
  147 +
  148 +**Architecture:** [2-3 句方法论]
  149 +
  150 +**Tech Stack:** [关键技术 / 库]
  151 +
  152 +---
  153 +```
  154 +
  155 +### Task 结构
  156 +
  157 +每个 task 是 red-green-commit 单元。捕获意图和边界,代码留给 TDD:
  158 +
  159 +````markdown
  160 +### Task N: [组件名 / 类名]
  161 +
  162 +**Files:**
  163 +- Create: `exact/path/to/File.java`(或 `frontend/src/...`)
  164 +- Modify: `exact/path/to/Existing.java:123-145`
  165 +- Test: `tests/exact/path/to/FileTest.java`
  166 +- 测试先行类型: jsdom 组件测试(仅 phase=frontend 需标注)
  167 +
  168 +**API shape / Props shape**(只写需要约束实现的签名;内部实现留给 TDD):
  169 +- `LoginService#login(LoginRequest req) : LoginResponse`
  170 +
  171 +- [ ] **Step 1: 写失败测试**
  172 + - 测试名: `LoginServiceTest#loginWithBadPassword_incrementsFailCount_returns40101`
  173 + - 意图: 错误密码 → `iLoginFailCount += 1`;第 5 次 → 设置 `tLockUntil = now + 15min`;返回码 40101
  174 + - 子会话确认 FAIL(函数/类不存在)
  175 +
  176 +- [ ] **Step 2: 实现最小代码**
  177 + - 目标: 让 Step 1 测试通过;不多做
  178 + - 涉及文件: `LoginService.java`, `SftLoginInfoMapper.java`
  179 +
  180 +- [ ] **Step 3: 子会话验证 PASS**
  181 +
  182 +- [ ] **Step 4: Commit**
  183 + - `git add <文件>`
  184 + - `git commit -m "feat(sys): 登录失败计数 + 锁定 REQ-SYS-001"`
  185 +````
  186 +
  187 +### 允许的代码块场景
  188 +
  189 +少数例外,需要写死而非让 TDD 自由发挥:
  190 +
  191 +- **DDL / migration 文件**(phase=backend):`V_n__*.sql` 的 ALTER/CREATE 语句——schema 是事实源
  192 +- **合同级常量**:API 错误码表、JWT claim 名、Redis key 模式——跨模块消费,必须锁定
  193 +- **路由配置**(phase=frontend):`routes.ts` 中 path 注册(路径是契约级)
  194 +- **API client 契约**(phase=frontend):fetch 包装函数签名 + headers + 错误码 mapping
  195 +- **Design Tokens 名称**(phase=frontend):`var(--color-primary)` 列表
  196 +- **测试断言形状**(可选):一句话说不清"测什么"时,给个 3-5 行断言 sketch
  197 +
  198 +除此之外一律散文 + 签名描述,**不贴完整文件**。
  199 +
  200 +### 记住
  201 +
  202 +- Exact file paths always
  203 +- Exact commands with expected output(测试运行 + git 操作)
  204 +- API signatures / class names / error codes / contract values — **必须写死**
  205 +- Internal implementation code — **不写**;留给 TDD 阶段
  206 +- DRY、YAGNI、TDD、frequent commits
  207 +
  208 +---
  209 +
  210 +## 参考
  211 +
  212 +- `${CLAUDE_SKILL_DIR}/templates/feature-spec-plan-template.md`
  213 +- 上游(backend):`module-start`
  214 +- 上游(frontend):`frontend-start`
  215 +- 下游:`feature-tdd`
skills/coding/feature-spec/templates/feature-spec-plan-template.md 0 → 100644
  1 +<!-- 填写说明:仅填写当前 phase 对应的规格小节;另一 phase 小节留空或删除。-->
  2 +阶段: {{phase}}
  3 +
  4 +---
  5 +
  6 +# 规格 + 计划:{{id}} — {{title}}
  7 +
  8 +> 日期:{{date}}
  9 +
  10 +---
  11 +
  12 +## 规格
  13 +
  14 +### (phase=backend 填写)后端规格
  15 +
  16 +---
  17 +req_id: {{req_id}}
  18 +date: {{date}}
  19 +module: {{module}}
  20 +---
  21 +
  22 +#### 目标
  23 +{{goal}}
  24 +
  25 +#### 输入 / 触发
  26 +{{input}}
  27 +
  28 +#### 输出 / 结果
  29 +{{output}}
  30 +
  31 +#### 业务规则
  32 +{{rules}}
  33 +
  34 +#### 边界与约束
  35 +{{constraints}}
  36 +
  37 +#### 依赖的 schema 表 / 字段
  38 +{{schema_refs}}
  39 +
  40 +#### 依赖的接口
  41 +{{api_refs}}
  42 +
  43 +#### 验收标准
  44 +{{acceptance}}
  45 +
  46 +---
  47 +
  48 +### (phase=frontend 填写)前端规格
  49 +
  50 +<!-- 仅 phase=frontend 时填写以下各节;phase=backend 时忽略。-->
  51 +
  52 +> 关联 REQ:{{associated_reqs}}
  53 +> 关联原型:{{associated_prototypes}}
  54 +
  55 +#### 功能概述
  56 +{{feature_overview}}
  57 +
  58 +#### 组件树
  59 +
  60 +<!-- 基于关联原型的 DOM 结构推导。多页则按页面分块;每层缩进表示嵌套关系。 -->
  61 +
  62 +```
  63 +{{component_tree}}
  64 +```
  65 +
  66 +#### 页面状态机
  67 +
  68 +| # | 状态 | 触发条件 | 视觉表现 | 用户可执行操作 |
  69 +|---|------|---------|---------|--------------|
  70 +{{state_machine_rows}}
  71 +
  72 +至少包含:loading / empty / error / 正常 / 提交中 五态。
  73 +
  74 +#### 消费的后端端点
  75 +
  76 +| # | 方法 | 路径 | 触发时机 | 关联 REQ |
  77 +|---|------|------|---------|---------|
  78 +{{endpoint_rows}}
  79 +
  80 +#### 业务规则前端复刻清单
  81 +
  82 +| # | 规则描述 | 触发时机 | 报错文案 | 来源 REQ |
  83 +|---|---------|---------|---------|---------|
  84 +{{validation_rows}}
  85 +
  86 +> **要求**:每条规则必须在前端 form-level 校验中复刻,不仅依赖后端报错。文案与后端语义一致。
  87 +
  88 +#### Design Tokens 引用清单
  89 +
  90 +<!-- 列出本页面用到的 token 变量名(不写 hex),如 var(--color-primary) / var(--color-bg-card)。来源见 docs/06 § 二。 -->
  91 +
  92 +```
  93 +{{token_list}}
  94 +```
  95 +
  96 +#### 交互流程关键路径
  97 +{{interaction_flow}}
  98 +
  99 +#### 备注与开放问题
  100 +{{open_questions}}
  101 +
  102 +---
  103 +
  104 +## 任务级计划
  105 +
  106 +> **Execution:** Parent skill `feature-tdd` executes this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
  107 +
  108 +**Goal:** {{plan_goal}}
  109 +
  110 +**Architecture:** {{plan_architecture}}
  111 +
  112 +**Tech Stack:** {{plan_tech_stack}}
  113 +
  114 +---
  115 +
  116 +### Schema 改动
  117 +{{schema_change_decision}} <!-- "无" 或 "需要 migration:V<n>__<snake_case>.sql,作用:<一行描述>" — 仅 phase=backend 适用 -->
  118 +
  119 +### 文件变更清单
  120 +{{#each files}}
  121 +- `{{path}}` — {{action}}({{rationale}})
  122 +{{/each}}
  123 +
  124 +### 任务步骤
  125 +{{#each tasks}}
  126 +#### Task {{index}}: {{title}}
  127 +
  128 +**Files:**
  129 +{{task_files}}
  130 +
  131 +**API shape / Props shape**(只写需要约束实现的签名):
  132 +{{api_shape}}
  133 +
  134 +- [ ] **Step 1: 写失败测试**
  135 + - 测试名: `{{test_file}}::{{test_name}}`
  136 + - 意图: {{test_intent}}
  137 + - 子会话确认 FAIL
  138 +
  139 +- [ ] **Step 2: 实现最小代码**
  140 + - 目标: 让 Step 1 测试通过;不多做
  141 + - 涉及文件: `{{impl_file}}`
  142 +
  143 +- [ ] **Step 3: 子会话验证 PASS**
  144 +
  145 +- [ ] **Step 4: Commit**
  146 + - `git add <文件>`
  147 + - `git commit -m "{{commit_message}}"`
  148 +{{/each}}
  149 +
  150 +### 提交计划
  151 +{{#each commits}}
  152 +- `{{message}}`(覆盖 Task {{task_index}})
  153 +{{/each}}
skills/coding/feature-tdd/SKILL.md
1 --- 1 ---
2 name: feature-tdd 2 name: feature-tdd
3 -description: 功能循环第 3 步。按 plan 逐任务做 TDD(失败测试 → 实现 → 通过 → commit),测试运行强制派发到子会话 3 +description: 统一功能循环第 2 步(后端 REQ / 前端 FE 共用,由 phase 参数区分)。按 plan 逐任务做 TDD(失败测试 → 实现 → 通过 → commit),所有测试运行强制派发到 Agent 子会话,主会话只接收 JSON 结果
4 user-invocable: false 4 user-invocable: false
5 allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) 5 allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *)
6 --- 6 ---
@@ -9,34 +9,92 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *) @@ -9,34 +9,92 @@ allowed-tools: Read Write Edit Agent Skill Bash(git add *) Bash(git commit *)
9 9
10 # feature-tdd 10 # feature-tdd
11 11
12 -按 plan 文件逐任务做 TDD:写失败测试 → 写最小实现 → 确认通过 → commit。**所有测试运行强制派发到 Agent 子会话**,主会话只接收 JSON 结果。 12 +按合并文档(spec + plan)的任务级计划逐任务做 TDD:写失败测试 → 写最小实现 → 确认通过 → commit。**所有测试运行强制派发到 Agent 子会话**,主会话只接收 JSON 结果。
  13 +
  14 +**入参(由 feature-spec 传入):**
  15 +- `phase`:`backend` | `frontend`
  16 +- `id`:`REQ-XXX-NNN`(backend)或 `FE-NN`(frontend)
  17 +
  18 +---
  19 +
  20 +## 阶段差异
  21 +
  22 +### phase=backend
  23 +
  24 +- 工作分支:`module-<module_id>`
  25 +- `impl_file` 不得以 `frontend/` 开头(见护栏)
  26 +- 测试命令:`./scripts/test.sh`(由子会话执行)
  27 +- Schema 改动前置:有 migration 需求时,第一个任务必须是写 migration + 同步 docs/03
  28 +- 提交 trailer:`REQ-XXX-NNN` 标签(内嵌在 commit subject 中)
  29 +
  30 +### phase=frontend
  31 +
  32 +- 工作分支:`frontend-phase`
  33 +- `impl_file` 必须以 `frontend/` 开头(见护栏)
  34 +- 测试命令:从 `docs/04-技术规范.md § 零 frontend` 取:
  35 + - `frontend.unit_test_runner`:vitest / jest(默认 vitest)
  36 + - `frontend.e2e_runner`:playwright(默认 playwright)
  37 + - `frontend.test_command` / `frontend.e2e_command`(缺失则用 `pnpm test:ci` / `pnpm e2e:ci`)
  38 +- **无** SQL migration 步骤
  39 +- 提交 trailer:`REQ_ID: FE-NN`(作为 commit trailer 行)
  40 +
  41 +---
13 42
14 ## 执行步骤 43 ## 执行步骤
15 44
16 -1. 加载计划文件 `docs/superpowers/plans/<YYYY-MM-DD>-<REQ-id>.md`。  
17 -2. **Schema 改动前置**(仅当 plan 声明需要):第一个任务必须是写 migration 文件 + 同步更新 docs/03,并一起 commit。 45 +1. **加载 spec + plan**:读取 `docs/superpowers/specs/<YYYY-MM-DD>-<id>.md`,定位 `## 任务级计划` 节。
  46 +
  47 +2. **Schema 改动前置**(仅 `phase=backend`,且 plan 声明需要时):第一个任务必须是写 migration 文件 + 同步更新 docs/03,并一起 commit。
18 - 文件命名 `V<n>__<snake_case>.sql`,`<n>` = 现有 `sql/migrations/V*.sql` 最大版本号 + 1;文件只含 DDL 48 - 文件命名 `V<n>__<snake_case>.sql`,`<n>` = 现有 `sql/migrations/V*.sql` 最大版本号 + 1;文件只含 DDL
19 - **同步**把新 CREATE / ALTER 反向更新到 `docs/03-数据库设计文档.md` 对应表小节,保持 docs/03 是 schema 的 SSoT;新增表按表小节模板追加 49 - **同步**把新 CREATE / ALTER 反向更新到 `docs/03-数据库设计文档.md` 对应表小节,保持 docs/03 是 schema 的 SSoT;新增表按表小节模板追加
20 - migration + docs/03 改动**同一 commit**,避免 SSoT 与 migration 分裂 50 - migration + docs/03 改动**同一 commit**,避免 SSoT 与 migration 分裂
21 - - 测试运行时 Spring Boot 启动 Flyway 会自动 apply 这个新 migration;`scripts/setup-test-db.sh` 只负责清库  
22 -3. 按顺序处理每个代码类任务:  
23 - a. 在 `test_file::test_name` 处写**失败**测试  
24 - b. 派发 Agent 子会话(general-purpose)运行测试确认失败,子会话只返回 `{command, exit_code, failing_assertion}` JSON  
25 - c. 在 `impl_file` 处写**最小**实现使测试通过 51 + - 测试运行时 Spring Boot 启动 Flyway 会自动 apply 新 migration
  52 +
  53 +3. **按顺序处理每个代码类任务**:
  54 +
  55 + a. 在 `test_file::test_name` 处写**失败**测试:
  56 + - `phase=backend`:JUnit / 框架测试
  57 + - `phase=frontend`,`测试先行类型=jsdom`:在 jsdom 环境下用 vitest/jest 写组件单测(render + 断言 DOM / 交互后状态变化)
  58 + - `phase=frontend`,`测试先行类型=e2e`:在 `frontend/e2e/` 写 Playwright 测试(headless)
  59 +
  60 + b. 派发 Agent 子会话(general-purpose)运行该测试,子会话只返回 `{command, exit_code, failing_assertion}` JSON,确认失败
  61 +
  62 + c. 在 `impl_file` 处写**最小**实现使测试通过。**严格遵守**:
  63 + - `phase=backend`:`impl_file` 不得以 `frontend/` 开头(违反 → 护栏硬停)
  64 + - `phase=frontend`:`impl_file` 必须以 `frontend/` 开头(违反 → 护栏硬停);色值用 `var(--color-*)`(来自 spec §六),不硬编码 hex;业务校验按 spec §五 在 form-level 复刻
  65 +
26 d. 再次派发子会话确认通过 66 d. 再次派发子会话确认通过
27 - e. 同一测试 >10 次修复仍失败 → 调用 `interrupt-check`(中断 #1:测试反复失败)  
28 - f. 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit(`scope` = 任务模块;`subject` ≤ 50 字符;`req_id` 必填)  
29 -4. 全部任务完成 → 调用 `Skill(feature-verify)`。 67 +
  68 + e. 同一测试 >10 次修复仍失败 → 调用 `Skill(interrupt-check)`(中断 #1:测试反复失败)
  69 +
  70 + f. 按 `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 格式 commit:
  71 + - `phase=backend`:`scope` = 任务模块;`subject` ≤ 50 字符;内含 `REQ-XXX-NNN` 标签
  72 + - `phase=frontend`:`scope` = 组件名(如 `dashboard` / `user-form`);`subject` ≤ 50 字符;必含 trailer `REQ_ID: FE-NN`
  73 +
  74 +4. **全部任务完成** → 调用 `Skill(feature-review)` 传入 `{ phase, id }`
  75 +
  76 +---
30 77
31 ## 护栏 78 ## 护栏
32 79
33 -- **绝不**在主会话直接跑 `mvn test` / `pnpm test` / `scripts/test.sh`,必须通过子会话 80 +- **绝不**在主会话直接跑任何测试命令(`mvn test` / `pnpm test` / `scripts/test.sh` / `pnpm playwright` / `vitest`),必须通过子会话
34 - **绝不**在主会话直接 `mysql -e "ALTER ..."`;业务 schema 改动一律走 `sql/migrations/V*.sql` 文件(只读查询 / 临时调试除外) 81 - **绝不**在主会话直接 `mysql -e "ALTER ..."`;业务 schema 改动一律走 `sql/migrations/V*.sql` 文件(只读查询 / 临时调试除外)
35 -- 每次 commit 必须含 `REQ-XXX-NNN` 标签;不混合无关改动到同一 commit  
36 -- **后端阶段路径硬护栏**:任务表里的 `impl_file` 路径以 `frontend/` 开头 → 硬停并打印 `feature-tdd 后端阶段不允许写前端代码:<impl_file>。请检查 plan 任务定义;UI 推迟到前端阶段(fe-feature-*)`,不再继续 TDD 循环 82 +- **后端阶段路径硬护栏(phase=backend)**:任务表里的 `impl_file` 路径以 `frontend/` 开头 → 硬停并打印:
  83 + ```
  84 + feature-tdd 后端阶段不允许写前端代码:<impl_file>。请检查 plan 任务定义;UI 推迟到前端阶段(phase=frontend)。
  85 + ```
  86 +- **前端阶段路径硬护栏(phase=frontend)**:`impl_file` 路径**不以** `frontend/` 开头,或命中 `backend/` / `sql/` / `scripts/` → 硬停并打印:
  87 + ```
  88 + feature-tdd 前端阶段不允许写非前端文件:<impl_file>。前端阶段任务的 impl_file 必须落在 frontend/ 目录下。
  89 + ```
  90 +- 不硬编码颜色 hex(`phase=frontend`);token 引用必须对齐 spec §六
  91 +
  92 +---
37 93
38 ## 参考 94 ## 参考
39 95
40 - `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md` 96 - `${CLAUDE_SKILL_DIR}/templates/commit-message-template.md`
41 - 守门:`interrupt-check`(仅在步骤 3.e 触发,条件 1) 97 - 守门:`interrupt-check`(仅在步骤 3.e 触发,条件 1)
42 - 原则参考:`superpowers:test-driven-development`(外部 TDD 原则手册,本 skill 已固化"子会话跑测试 + REQ-tagged commit"流程,不做运行时 invoke) 98 - 原则参考:`superpowers:test-driven-development`(外部 TDD 原则手册,本 skill 已固化"子会话跑测试 + REQ-tagged commit"流程,不做运行时 invoke)
  99 +- 上游:`feature-spec`
  100 +- 下游:`feature-review`
skills/coding/feature-verify/SKILL.md deleted
1 ----  
2 -name: feature-verify  
3 -description: 功能循环第 4 步。把功能测试派发到子会话跑,按模板渲染证据。无证据不声称完成。  
4 -user-invocable: false  
5 -allowed-tools: Skill Read Agent  
6 ----  
7 -  
8 -**所有输出必须使用中文。**  
9 -  
10 -# feature-verify  
11 -  
12 -把当前 REQ 的功能测试派发到 Agent 子会话执行,按模板把结构化结果渲染成证据。**主会话从不直接跑测试**,也不自由编写证据。  
13 -  
14 -## 执行步骤  
15 -  
16 -1. 从 plan 文件或项目标准命令中确定功能的测试目标(如 Maven profile / pnpm script / pytest path)。  
17 -2. 派发 Agent 子会话(general-purpose)运行该目标,子会话只返回结构化 JSON(不输出描述文字):  
18 - ```json  
19 - {  
20 - "command": "<cmd>",  
21 - "exit_code": <int>,  
22 - "passed": <int>,  
23 - "failed": <int>,  
24 - "failed_list": ["<test>", ...],  
25 - "stdout_excerpt": "<最后 30 行或最相关的失败片段>"  
26 - }  
27 - ```  
28 -3. 按 `${CLAUDE_SKILL_DIR}/templates/feature-verify-evidence-template.md` 渲染证据并打印到会话。  
29 -4. **`exit_code != 0` 或 `failed > 0`** → 停止,不进入 review。  
30 -5. 通过 → 调用 `Skill(feature-review)`。  
31 -  
32 -## 护栏  
33 -  
34 -- **绝不**在主会话直接跑测试,必须通过子会话  
35 -- **绝不**自由编写证据正文,必须从模板渲染  
36 -- 不要把原始 stdout 全文塞进主会话(`stdout_excerpt` ≤ 30 行)  
37 -  
38 -## 参考  
39 -  
40 -- `${CLAUDE_SKILL_DIR}/templates/feature-verify-evidence-template.md`  
41 -- 原则参考:`superpowers:verification-before-completion`(外部"证据先于断言"原则手册,本 skill 已固化子会话派发 + 模板渲染流程,不做运行时 invoke)  
skills/coding/feature-verify/templates/feature-verify-evidence-template.md deleted
1 -## Verify evidence — {{req_id}}  
2 -  
3 -- 命令: `{{command}}`  
4 -- 子会话: {{subagent_id}}  
5 -- 退出码: {{exit_code}}  
6 -- 通过用例数: {{passed}}  
7 -- 失败用例数: {{failed}}  
8 -- 失败列表: {{failed_list}}  
9 -  
10 -关键 stdout 片段 (≤30 行):  
11 -  
12 -```  
13 -{{stdout_excerpt}}  
14 -```  
15 -  
16 -结论: {{conclusion}} (pass / fail)