@devflow-tools/plugin-react 0.12.0 → 0.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/dist/analyzers/__tests__/diagnose-bug.test.d.ts +0 -2
- package/dist/analyzers/__tests__/diagnose-bug.test.d.ts.map +0 -1
- package/dist/analyzers/__tests__/diagnose-bug.test.js +0 -45
- package/dist/analyzers/__tests__/diagnose-bug.test.js.map +0 -1
- package/dist/analyzers/__tests__/file-scanner.test.d.ts +0 -2
- package/dist/analyzers/__tests__/file-scanner.test.d.ts.map +0 -1
- package/dist/analyzers/__tests__/file-scanner.test.js +0 -32
- package/dist/analyzers/__tests__/file-scanner.test.js.map +0 -1
- package/dist/analyzers/__tests__/hooks-review.test.d.ts +0 -2
- package/dist/analyzers/__tests__/hooks-review.test.d.ts.map +0 -1
- package/dist/analyzers/__tests__/hooks-review.test.js +0 -95
- package/dist/analyzers/__tests__/hooks-review.test.js.map +0 -1
- package/dist/analyzers/__tests__/new-component.test.d.ts +0 -2
- package/dist/analyzers/__tests__/new-component.test.d.ts.map +0 -1
- package/dist/analyzers/__tests__/new-component.test.js +0 -40
- package/dist/analyzers/__tests__/new-component.test.js.map +0 -1
- package/dist/analyzers/__tests__/performance-audit.test.d.ts +0 -2
- package/dist/analyzers/__tests__/performance-audit.test.d.ts.map +0 -1
- package/dist/analyzers/__tests__/performance-audit.test.js +0 -42
- package/dist/analyzers/__tests__/performance-audit.test.js.map +0 -1
- package/dist/analyzers/__tests__/refactor-component.test.d.ts +0 -2
- package/dist/analyzers/__tests__/refactor-component.test.d.ts.map +0 -1
- package/dist/analyzers/__tests__/refactor-component.test.js +0 -65
- package/dist/analyzers/__tests__/refactor-component.test.js.map +0 -1
- package/dist/analyzers/diagnose-bug.d.ts +0 -9
- package/dist/analyzers/diagnose-bug.d.ts.map +0 -1
- package/dist/analyzers/diagnose-bug.js +0 -108
- package/dist/analyzers/diagnose-bug.js.map +0 -1
- package/dist/analyzers/file-scanner.d.ts +0 -9
- package/dist/analyzers/file-scanner.d.ts.map +0 -1
- package/dist/analyzers/file-scanner.js +0 -35
- package/dist/analyzers/file-scanner.js.map +0 -1
- package/dist/analyzers/hooks-review.d.ts +0 -3
- package/dist/analyzers/hooks-review.d.ts.map +0 -1
- package/dist/analyzers/hooks-review.js +0 -162
- package/dist/analyzers/hooks-review.js.map +0 -1
- package/dist/analyzers/new-component.d.ts +0 -12
- package/dist/analyzers/new-component.d.ts.map +0 -1
- package/dist/analyzers/new-component.js +0 -59
- package/dist/analyzers/new-component.js.map +0 -1
- package/dist/analyzers/performance-audit.d.ts +0 -3
- package/dist/analyzers/performance-audit.d.ts.map +0 -1
- package/dist/analyzers/performance-audit.js +0 -100
- package/dist/analyzers/performance-audit.js.map +0 -1
- package/dist/analyzers/refactor-component.d.ts +0 -3
- package/dist/analyzers/refactor-component.d.ts.map +0 -1
- package/dist/analyzers/refactor-component.js +0 -90
- package/dist/analyzers/refactor-component.js.map +0 -1
- package/dist/analyzers/types.d.ts +0 -23
- package/dist/analyzers/types.d.ts.map +0 -1
- package/dist/analyzers/types.js +0 -2
- package/dist/analyzers/types.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -1781
- package/dist/index.js.map +0 -1
package/dist/index.js
DELETED
|
@@ -1,1781 +0,0 @@
|
|
|
1
|
-
export const reactPlugin = {
|
|
2
|
-
meta: {
|
|
3
|
-
name: "react",
|
|
4
|
-
version: "0.1.0",
|
|
5
|
-
description: "React 18 专家能力 — Bug 诊断、组件重构、性能优化、Hooks 审查",
|
|
6
|
-
icon: "⚛️",
|
|
7
|
-
tags: ["frontend", "react", "hooks", "jsx", "performance"],
|
|
8
|
-
},
|
|
9
|
-
knowledge: {
|
|
10
|
-
sources: [
|
|
11
|
-
{
|
|
12
|
-
name: "react-docs",
|
|
13
|
-
urls: [
|
|
14
|
-
"https://react.dev/reference/react",
|
|
15
|
-
"https://react.dev/reference/react/hooks",
|
|
16
|
-
"https://react.dev/learn",
|
|
17
|
-
],
|
|
18
|
-
pluginName: "react",
|
|
19
|
-
version: "18.3.1",
|
|
20
|
-
},
|
|
21
|
-
],
|
|
22
|
-
},
|
|
23
|
-
memory: {
|
|
24
|
-
project: {
|
|
25
|
-
stack: ["React 18", "React Router", "Zustand"],
|
|
26
|
-
conventions: [
|
|
27
|
-
{ key: "components", value: "使用函数组件 + Hooks", source: "manual", confidence: 0.9 },
|
|
28
|
-
{ key: "file-structure", value: "一个组件一个文件", source: "manual", confidence: 0.9 },
|
|
29
|
-
{ key: "props", value: "Props 使用 interface 定义", source: "manual", confidence: 0.8 },
|
|
30
|
-
{ key: "perf", value: "使用 React.memo 优化性能", source: "manual", confidence: 0.7 },
|
|
31
|
-
{ key: "hooks-naming", value: "自定义 Hooks 以 use 开头", source: "manual", confidence: 1.0 },
|
|
32
|
-
],
|
|
33
|
-
},
|
|
34
|
-
global: [
|
|
35
|
-
{
|
|
36
|
-
id: "react:hooks-rules",
|
|
37
|
-
source: "react",
|
|
38
|
-
title: "React Hooks 规则",
|
|
39
|
-
content: "只在最顶层调用 Hooks,不要在循环、条件或嵌套函数中调用。只在 React 函数组件或自定义 Hook 中调用 Hooks。",
|
|
40
|
-
embedding: [],
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
id: "react:useEffect-cleanup",
|
|
44
|
-
source: "react",
|
|
45
|
-
title: "useEffect 清理",
|
|
46
|
-
content: "useEffect 的返回值应为一个清理函数,用于取消订阅、清除定时器等副作用。React 18 在 Strict Mode 下会执行两次 useEffect 以帮助发现清理问题。",
|
|
47
|
-
embedding: [],
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: "react:rendering-optimization",
|
|
51
|
-
source: "react",
|
|
52
|
-
title: "渲染优化策略",
|
|
53
|
-
content: "使用 React.memo 避免不必要的重渲染。使用 useMemo 缓存计算结果,使用 useCallback 缓存回调函数。注意不要过早优化。",
|
|
54
|
-
embedding: [],
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
id: "react:error-boundary",
|
|
58
|
-
source: "react",
|
|
59
|
-
title: "错误边界模式",
|
|
60
|
-
content: "使用 ErrorBoundary 组件捕获渲染错误。配合 Suspense 处理异步加载。ErrorBoundary 只能捕获渲染期间的错误,不能捕获事件处理和异步代码中的错误。",
|
|
61
|
-
embedding: [],
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
id: "react:suspense-streaming",
|
|
65
|
-
source: "react",
|
|
66
|
-
title: "Suspense 与流式渲染",
|
|
67
|
-
content: "React 18 支持 Suspense 配合流式 SSR。使用 lazy() 动态导入组件。Suspense 的 fallback 在数据加载期间显示。结合 useDeferredValue 和 useTransition 优化用户体验。",
|
|
68
|
-
embedding: [],
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
},
|
|
72
|
-
workflow: {
|
|
73
|
-
steps: [],
|
|
74
|
-
templates: [
|
|
75
|
-
// ── Bug 诊断修复 ──
|
|
76
|
-
{
|
|
77
|
-
name: "bug-diagnosis",
|
|
78
|
-
description: "Bug 诊断修复流程:从报错到 PR 的完整链路",
|
|
79
|
-
version: "2.0.0",
|
|
80
|
-
steps: [
|
|
81
|
-
{
|
|
82
|
-
id: "capture-symptoms",
|
|
83
|
-
title: "收集错误症状",
|
|
84
|
-
instruction: [
|
|
85
|
-
"## 收集错误症状",
|
|
86
|
-
"",
|
|
87
|
-
"完整记录 Bug 的所有表象信息,这是后续诊断的基础。",
|
|
88
|
-
"",
|
|
89
|
-
"**执行动作**:",
|
|
90
|
-
"1. 复制完整的错误堆栈(包括 `message`、`stack`、组件栈)",
|
|
91
|
-
"2. 打开浏览器 DevTools → Console,记录所有红色 Error 和黄色 Warning",
|
|
92
|
-
"3. 查看 Network 面板,标记失败请求的 URL、状态码、响应体",
|
|
93
|
-
"4. 如有 UI 异常,截图并描述预期行为 vs 实际行为",
|
|
94
|
-
"5. 记录复现路径:从哪个页面、点击什么按钮、输入什么数据触发",
|
|
95
|
-
"",
|
|
96
|
-
"**产出格式**:",
|
|
97
|
-
"```",
|
|
98
|
-
"error_type: TypeError | ReferenceError | ...",
|
|
99
|
-
"error_message: <完整的错误消息>",
|
|
100
|
-
"stack_trace: <关键 3 帧>",
|
|
101
|
-
"affected_url: </dashboard/settings>",
|
|
102
|
-
"repro_steps: [1. 登录, 2. 进入设置页, 3. 点击保存]",
|
|
103
|
-
"console_warnings: [...]",
|
|
104
|
-
"failed_requests: [{ url, status, response }]",
|
|
105
|
-
"```",
|
|
106
|
-
].join("\n"),
|
|
107
|
-
suggestedTools: ["Read", "Bash"],
|
|
108
|
-
output: "结构化的错误症状清单(error_type, stack_trace, repro_steps)",
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
id: "locate-source",
|
|
112
|
-
title: "定位问题源文件",
|
|
113
|
-
instruction: [
|
|
114
|
-
"## 定位问题源文件",
|
|
115
|
-
"",
|
|
116
|
-
"根据上一步收集的堆栈信息,定位到具体的源文件和代码行。",
|
|
117
|
-
"",
|
|
118
|
-
"**执行动作**:",
|
|
119
|
-
"1. 从 `stack_trace` 中提取第一个属于本项目(非 `node_modules`)的帧",
|
|
120
|
-
"2. 解析出文件路径和行号,例如 `src/components/Dashboard.tsx:142`",
|
|
121
|
-
"3. 使用 Read 工具读取该文件,聚焦错误行附近的上下文(±30 行)",
|
|
122
|
-
"4. 如果堆栈指向编译产物(`dist/`、`.next/`),通过 sourcemap 或文件名反推源文件",
|
|
123
|
-
"5. 标记出问题函数 / 组件名",
|
|
124
|
-
"",
|
|
125
|
-
"**判定标准**:",
|
|
126
|
-
"- 找到包含 Bug 触发逻辑的具体函数 / 组件",
|
|
127
|
-
"- 能说出该函数在什么条件下走到错误分支",
|
|
128
|
-
"",
|
|
129
|
-
"**产出格式**:",
|
|
130
|
-
"```",
|
|
131
|
-
"source_file: src/components/Dashboard.tsx",
|
|
132
|
-
"line_range: 130-160",
|
|
133
|
-
"function_name: useDashboardData",
|
|
134
|
-
"suspected_cause: 解构了可能为 undefined 的 props.data",
|
|
135
|
-
"```",
|
|
136
|
-
].join("\n"),
|
|
137
|
-
suggestedTools: ["Read", "Bash"],
|
|
138
|
-
output: "问题源文件路径、函数名、可疑代码行",
|
|
139
|
-
depends: ["capture-symptoms"],
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
id: "git-recent-changes",
|
|
143
|
-
title: "查看近期 Git 变更",
|
|
144
|
-
instruction: [
|
|
145
|
-
"## 查看近期 Git 变更",
|
|
146
|
-
"",
|
|
147
|
-
"通过 Git 历史判断 Bug 是何时引入的,缩小排查范围。",
|
|
148
|
-
"",
|
|
149
|
-
"**执行动作**:",
|
|
150
|
-
"1. 运行 `git log -n 10 -- <source_file>` 查看该文件最近的 10 次提交",
|
|
151
|
-
"2. 对每个相关提交运行 `git show <commit> -- <source_file>` 查看具体改动",
|
|
152
|
-
"3. 重点关注:",
|
|
153
|
-
" - 是否新增了可能引入 Bug 的逻辑分支",
|
|
154
|
-
" - 是否修改了类型定义、接口字段",
|
|
155
|
-
" - 是否升级了依赖(`package.json` 变动)",
|
|
156
|
-
"4. 如果是回归 Bug,使用 `git bisect` 思路找到第一个坏版本",
|
|
157
|
-
"5. 记录引入 Bug 的 commit hash 和作者",
|
|
158
|
-
"",
|
|
159
|
-
"**产出格式**:",
|
|
160
|
-
"```",
|
|
161
|
-
"recent_commits: [{ hash, author, date, message }]",
|
|
162
|
-
"suspect_commit: abc1234",
|
|
163
|
-
"introduced_change: 将 data 从 required 改为 optional 但未处理 undefined",
|
|
164
|
-
"related_pr: #142",
|
|
165
|
-
"```",
|
|
166
|
-
].join("\n"),
|
|
167
|
-
suggestedTools: ["Bash"],
|
|
168
|
-
output: "引入 Bug 的 commit、变更内容、相关 PR",
|
|
169
|
-
depends: ["locate-source"],
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
id: "analyze-deps",
|
|
173
|
-
title: "分析依赖链路",
|
|
174
|
-
instruction: [
|
|
175
|
-
"## 分析依赖链路",
|
|
176
|
-
"",
|
|
177
|
-
"追溯问题文件的上游数据源和下游消费者,避免修复时引入新问题。",
|
|
178
|
-
"",
|
|
179
|
-
"**执行动作**:",
|
|
180
|
-
"1. 查找所有 `import` 了问题文件的文件(下游消费者):",
|
|
181
|
-
" ```bash",
|
|
182
|
-
" grep -rn \"from.*<source_file>\" src/",
|
|
183
|
-
" ```",
|
|
184
|
-
"2. 查看问题文件 `import` 了哪些模块(上游依赖)",
|
|
185
|
-
"3. 如果问题在 Props / Context 数据结构:",
|
|
186
|
-
" - 找到数据的源头(API 调用、Store、Context Provider)",
|
|
187
|
-
" - 追踪数据从源头到问题点的完整链路",
|
|
188
|
-
"4. 检查类型定义文件(`.d.ts` 或 `types.ts`),确认接口契约",
|
|
189
|
-
"5. 绘制简化依赖图:`A → B → C(问题点) → D`",
|
|
190
|
-
"",
|
|
191
|
-
"**产出格式**:",
|
|
192
|
-
"```",
|
|
193
|
-
"upstream: [src/api/dashboard.ts, src/store/useUserStore.ts]",
|
|
194
|
-
"downstream: [src/pages/DashboardPage.tsx, src/components/StatsCard.tsx]",
|
|
195
|
-
"data_flow: API.fetchDashboard → useDashboardData(hook) → Dashboard(component)",
|
|
196
|
-
"type_definition: src/types/dashboard.ts:DashboardData",
|
|
197
|
-
"```",
|
|
198
|
-
].join("\n"),
|
|
199
|
-
suggestedTools: ["Bash", "Read"],
|
|
200
|
-
output: "上下游依赖清单、数据流向、类型定义位置",
|
|
201
|
-
depends: ["locate-source"],
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
id: "search-knowledge",
|
|
205
|
-
title: "检索 React 知识库",
|
|
206
|
-
instruction: [
|
|
207
|
-
"## 检索 React 知识库",
|
|
208
|
-
"",
|
|
209
|
-
"查阅 React 官方文档和项目知识库,寻找类似问题的最佳实践。",
|
|
210
|
-
"",
|
|
211
|
-
"**执行动作**:",
|
|
212
|
-
"1. 根据错误类型提取关键词(如 `useEffect cleanup`、`key prop warning`、`stale closure`)",
|
|
213
|
-
"2. 调用 `devflow_knowledge_query` 查询项目知识库中的相关条目",
|
|
214
|
-
"3. 调用 `devflow_knowledge_search` 在 React 官方文档中搜索:",
|
|
215
|
-
" - 错误涉及的 Hook 用法(useEffect / useMemo / useCallback)",
|
|
216
|
-
" - 相关 React 模式(Error Boundary、Suspense、状态提升)",
|
|
217
|
-
" - 常见陷阱(闭包陈旧、依赖遗漏、无限渲染循环)",
|
|
218
|
-
"4. 检查项目 `memory` 中是否有类似 Bug 的历史修复记录",
|
|
219
|
-
"5. 整理出 2-3 条最相关的参考建议",
|
|
220
|
-
"",
|
|
221
|
-
"**产出格式**:",
|
|
222
|
-
"```",
|
|
223
|
-
"knowledge_hits: [",
|
|
224
|
-
" { source: react-docs, title: 'useEffect cleanup', url: '...', summary: '...' },",
|
|
225
|
-
" { source: project-memory, title: '历史类似问题', fix: '...' }",
|
|
226
|
-
"]",
|
|
227
|
-
"recommended_pattern: 使用 useRef 保存最新值以避免闭包陈旧",
|
|
228
|
-
"```",
|
|
229
|
-
].join("\n"),
|
|
230
|
-
suggestedTools: ["Bash", "Read"],
|
|
231
|
-
output: "相关文档条目、推荐修复模式、历史类似修复",
|
|
232
|
-
depends: ["capture-symptoms"],
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
id: "generate-fix",
|
|
236
|
-
title: "生成修复方案",
|
|
237
|
-
instruction: [
|
|
238
|
-
"## 生成修复方案",
|
|
239
|
-
"",
|
|
240
|
-
"综合所有诊断信息,生成最小化、精准的修复代码。",
|
|
241
|
-
"",
|
|
242
|
-
"**执行动作**:",
|
|
243
|
-
"1. 综合以下输入生成修复方案:",
|
|
244
|
-
" - `locate-source` 的可疑代码",
|
|
245
|
-
" - `git-recent-changes` 的引入原因",
|
|
246
|
-
" - `analyze-deps` 的依赖链路",
|
|
247
|
-
" - `search-knowledge` 的最佳实践",
|
|
248
|
-
"2. 使用 Edit 工具精准修改代码(不要整文件重写)",
|
|
249
|
-
"3. 修复原则:",
|
|
250
|
-
" - **最小改动**:只改必须改的代码,不做附带重构",
|
|
251
|
-
" - **类型安全**:修复后不能有 `any` 或 `@ts-ignore`",
|
|
252
|
-
" - **向后兼容**:不改变下游消费者的行为契约",
|
|
253
|
-
"4. 如果涉及多文件修改,按依赖顺序依次修改",
|
|
254
|
-
"5. 在代码中添加必要的注释解释修复原因",
|
|
255
|
-
"",
|
|
256
|
-
"**产出格式**:",
|
|
257
|
-
"```",
|
|
258
|
-
"fix_summary: 在 useDashboardData 中为 data 添加可选链和默认值",
|
|
259
|
-
"files_changed: [",
|
|
260
|
-
" { path: src/components/Dashboard.tsx, changes: '第 142 行添加 ?. 和 ?? 兜底' }",
|
|
261
|
-
"]",
|
|
262
|
-
"diff_preview: -const name = data.user.name",
|
|
263
|
-
" +const name = data?.user?.name ?? 'Guest'",
|
|
264
|
-
"```",
|
|
265
|
-
].join("\n"),
|
|
266
|
-
suggestedTools: ["Read", "Edit"],
|
|
267
|
-
output: "修复代码 diff、修改文件列表、修复说明",
|
|
268
|
-
depends: ["git-recent-changes", "analyze-deps", "search-knowledge"],
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
id: "type-check",
|
|
272
|
-
title: "运行类型检查",
|
|
273
|
-
instruction: [
|
|
274
|
-
"## 运行 TypeScript 类型检查",
|
|
275
|
-
"",
|
|
276
|
-
"验证修复后的代码在类型层面是正确的。",
|
|
277
|
-
"",
|
|
278
|
-
"**执行动作**:",
|
|
279
|
-
"1. 运行项目配置的 TypeScript 类型检查命令:",
|
|
280
|
-
" ```bash",
|
|
281
|
-
" npm run typecheck # 或 npx tsc --noEmit",
|
|
282
|
-
" ```",
|
|
283
|
-
"2. 如果项目有特定的 tsconfig(如 `tsconfig.app.json`),使用对应配置",
|
|
284
|
-
"3. 分析输出:",
|
|
285
|
-
" - **无错误**:✅ 类型检查通过,进入下一步",
|
|
286
|
-
" - **有错误**:记录错误位置,返回 `generate-fix` 步骤重新修复",
|
|
287
|
-
"4. 如果修复引入了新的类型错误,分析原因:",
|
|
288
|
-
" - 可能是类型定义需要更新",
|
|
289
|
-
" - 可能是下游消费者需要适配",
|
|
290
|
-
"5. 不要使用 `@ts-ignore` 或 `as any` 绕过类型错误",
|
|
291
|
-
"",
|
|
292
|
-
"**产出格式**:",
|
|
293
|
-
"```",
|
|
294
|
-
"type_check: passed | failed",
|
|
295
|
-
"errors_count: 0",
|
|
296
|
-
"errors: []",
|
|
297
|
-
"retry_needed: false",
|
|
298
|
-
"```",
|
|
299
|
-
].join("\n"),
|
|
300
|
-
suggestedTools: ["Bash"],
|
|
301
|
-
output: "类型检查结果(passed/failed)、错误清单",
|
|
302
|
-
depends: ["generate-fix"],
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
id: "run-tests",
|
|
306
|
-
title: "运行测试验证",
|
|
307
|
-
instruction: [
|
|
308
|
-
"## 运行测试验证修复",
|
|
309
|
-
"",
|
|
310
|
-
"执行测试套件确认修复有效且未引入回归。",
|
|
311
|
-
"",
|
|
312
|
-
"**执行动作**:",
|
|
313
|
-
"1. 优先运行与修改文件直接相关的测试:",
|
|
314
|
-
" ```bash",
|
|
315
|
-
" npx vitest run src/components/__tests__/Dashboard.test.tsx",
|
|
316
|
-
" ```",
|
|
317
|
-
"2. 如果项目有 `test:related` 脚本,优先使用(自动找到受影响的测试)",
|
|
318
|
-
"3. 相关测试通过后,运行完整测试套件确认无回归:",
|
|
319
|
-
" ```bash",
|
|
320
|
-
" npm test",
|
|
321
|
-
" ```",
|
|
322
|
-
"4. 分析测试结果:",
|
|
323
|
-
" - **全部通过**:✅ 进入人工审查",
|
|
324
|
-
" - **有失败**:区分是修复不彻底还是引入了新问题",
|
|
325
|
-
"5. 如果测试失败且与修复相关,回到 `generate-fix` 步骤调整方案",
|
|
326
|
-
"6. 如果原本就没有相关测试,在 `generate-fix` 步骤补充测试用例",
|
|
327
|
-
"",
|
|
328
|
-
"**产出格式**:",
|
|
329
|
-
"```",
|
|
330
|
-
"test_result: passed | failed",
|
|
331
|
-
"tests_run: 42",
|
|
332
|
-
"tests_passed: 42",
|
|
333
|
-
"tests_failed: 0",
|
|
334
|
-
"failed_tests: []",
|
|
335
|
-
"coverage_delta: +2.3%",
|
|
336
|
-
"```",
|
|
337
|
-
].join("\n"),
|
|
338
|
-
suggestedTools: ["Bash"],
|
|
339
|
-
output: "测试结果(passed/failed)、覆盖率变化、失败用例详情",
|
|
340
|
-
depends: ["type-check"],
|
|
341
|
-
},
|
|
342
|
-
{
|
|
343
|
-
id: "human-review",
|
|
344
|
-
title: "人工审查确认",
|
|
345
|
-
instruction: [
|
|
346
|
-
"## 人工审查修复方案",
|
|
347
|
-
"",
|
|
348
|
-
"将所有诊断结果和修复方案呈现给用户,等待人工确认。",
|
|
349
|
-
"",
|
|
350
|
-
"**呈现给用户的摘要**:",
|
|
351
|
-
"",
|
|
352
|
-
"### 🐛 Bug 诊断报告",
|
|
353
|
-
"",
|
|
354
|
-
"**问题**:<一句话描述 Bug>",
|
|
355
|
-
"**根因**:<引入原因,关联 commit>",
|
|
356
|
-
"**影响范围**:<受影响的页面 / 功能>",
|
|
357
|
-
"",
|
|
358
|
-
"### 🔧 修复方案",
|
|
359
|
-
"",
|
|
360
|
-
"**修改文件**:",
|
|
361
|
-
"- `src/components/Dashboard.tsx` — 添加可选链和默认值",
|
|
362
|
-
"",
|
|
363
|
-
"**关键 diff**:",
|
|
364
|
-
"```diff",
|
|
365
|
-
"- const name = data.user.name;",
|
|
366
|
-
"+ const name = data?.user?.name ?? 'Guest';",
|
|
367
|
-
"```",
|
|
368
|
-
"",
|
|
369
|
-
"### ✅ 验证结果",
|
|
370
|
-
"",
|
|
371
|
-
"- TypeScript 类型检查:✅ 通过",
|
|
372
|
-
"- 单元测试(42 个):✅ 全部通过",
|
|
373
|
-
"- 回归测试:✅ 无新问题",
|
|
374
|
-
"",
|
|
375
|
-
"**等待用户操作**:",
|
|
376
|
-
"- 审查修复代码是否符合业务预期",
|
|
377
|
-
"- 确认后执行 `git commit` 和 `git push`",
|
|
378
|
-
"- 如需创建 PR,使用 `gh pr create` 命令",
|
|
379
|
-
"",
|
|
380
|
-
"**注意**:此步骤必须等待用户明确确认后才能继续,不可自动跳过。",
|
|
381
|
-
].join("\n"),
|
|
382
|
-
suggestedTools: ["Read"],
|
|
383
|
-
output: "用户确认结果(approved / rejected / needs-changes)",
|
|
384
|
-
depends: ["run-tests"],
|
|
385
|
-
requiresUserConfirmation: true,
|
|
386
|
-
},
|
|
387
|
-
],
|
|
388
|
-
triggers: [
|
|
389
|
-
{ type: "cli", command: "bug" },
|
|
390
|
-
{ type: "mcp", tool: "diagnose_bug" },
|
|
391
|
-
],
|
|
392
|
-
},
|
|
393
|
-
// ── 新功能开发 ──
|
|
394
|
-
{
|
|
395
|
-
name: "new-feature",
|
|
396
|
-
description: "新功能开发流程:需求分析 → 代码 → 测试 → Review",
|
|
397
|
-
version: "2.0.0",
|
|
398
|
-
steps: [
|
|
399
|
-
{
|
|
400
|
-
id: "analyze-requirements",
|
|
401
|
-
title: "分析需求",
|
|
402
|
-
instruction: [
|
|
403
|
-
"## 分析需求",
|
|
404
|
-
"",
|
|
405
|
-
"理解用户描述的功能需求,将其拆解为可执行的任务清单。",
|
|
406
|
-
"",
|
|
407
|
-
"**执行动作**:",
|
|
408
|
-
"1. 理解用户描述的功能需求,提取核心目标和边界条件",
|
|
409
|
-
"2. 将需求拆解为 3-5 个可执行的子任务,每个子任务对应一个独立的代码变更",
|
|
410
|
-
"3. 识别技术约束(依赖版本、浏览器兼容性、性能要求)",
|
|
411
|
-
"4. 确认数据流向:该功能需要哪些 API、状态管理、路由配置",
|
|
412
|
-
"5. 使用 Read 工具读取项目的 `package.json` 和 `tsconfig.json` 确认技术栈版本",
|
|
413
|
-
"",
|
|
414
|
-
"**产出格式**:",
|
|
415
|
-
"```",
|
|
416
|
-
"feature_summary: <一句话描述>",
|
|
417
|
-
"subtasks: [",
|
|
418
|
-
" { id: 1, description: '...', files_to_touch: ['...'] },",
|
|
419
|
-
" ...",
|
|
420
|
-
"]",
|
|
421
|
-
"constraints: ['...']",
|
|
422
|
-
"data_flow: <数据从 API/Store → 组件 → UI 的完整链路>",
|
|
423
|
-
"```",
|
|
424
|
-
].join("\n"),
|
|
425
|
-
suggestedTools: ["Read", "Bash"],
|
|
426
|
-
output: "拆解后的任务清单、技术约束、数据流向",
|
|
427
|
-
},
|
|
428
|
-
{
|
|
429
|
-
id: "impact-analysis",
|
|
430
|
-
title: "评估变更影响范围",
|
|
431
|
-
instruction: [
|
|
432
|
-
"## 评估变更影响范围",
|
|
433
|
-
"",
|
|
434
|
-
"基于 `analyze-requirements` 的任务清单,分析每个变更对现有代码的影响。",
|
|
435
|
-
"",
|
|
436
|
-
"**执行动作**:",
|
|
437
|
-
"1. 对每个待修改 / 新增的文件,查找所有依赖它的下游文件:",
|
|
438
|
-
" ```bash",
|
|
439
|
-
" grep -rn \"from.*<file_path>\" src/ --include='*.tsx' --include='*.ts' --include='*.jsx' --include='*.js'",
|
|
440
|
-
" ```",
|
|
441
|
-
"2. 检查是否修改了共享的类型定义、Context、Store:",
|
|
442
|
-
" ```bash",
|
|
443
|
-
" find src/ -type f \\( -name 'types.ts' -o -name 'store.ts' -o -name 'context.ts' \\) | head -20",
|
|
444
|
-
" ```",
|
|
445
|
-
"3. 评估路由变更影响:",
|
|
446
|
-
" ```bash",
|
|
447
|
-
" grep -rn \"Route\\|path:\" src/ --include='*.tsx' --include='*.ts' | head -30",
|
|
448
|
-
" ```",
|
|
449
|
-
"4. 标记高风险变更(影响 >5 个下游文件的变更)",
|
|
450
|
-
"5. 检查是否需要同步更新 Storybook、文档或 E2E 测试",
|
|
451
|
-
"",
|
|
452
|
-
"**产出格式**:",
|
|
453
|
-
"```",
|
|
454
|
-
"affected_files: [{ path, downstream_count, risk: 'high'|'medium'|'low' }]",
|
|
455
|
-
"shared_changes: [{ type: 'type'|'context'|'store', path, downstream_files: [...] }]",
|
|
456
|
-
"risk_summary: <高风险变更概述>",
|
|
457
|
-
"```",
|
|
458
|
-
].join("\n"),
|
|
459
|
-
suggestedTools: ["Bash", "Read"],
|
|
460
|
-
output: "受影响文件清单、共享变更列表、风险评估",
|
|
461
|
-
depends: ["analyze-requirements"],
|
|
462
|
-
},
|
|
463
|
-
{
|
|
464
|
-
id: "check-existing-patterns",
|
|
465
|
-
title: "检查已有实现模式",
|
|
466
|
-
instruction: [
|
|
467
|
-
"## 检查项目中已有的类似实现模式",
|
|
468
|
-
"",
|
|
469
|
-
"避免重复造轮子,复用项目已有的组件、Hooks 和工具函数。",
|
|
470
|
-
"",
|
|
471
|
-
"**执行动作**:",
|
|
472
|
-
"1. 搜索项目中功能相似的现有组件:",
|
|
473
|
-
" ```bash",
|
|
474
|
-
" find src/components/ -type f -name '*.tsx' | head -50",
|
|
475
|
-
" ```",
|
|
476
|
-
"2. 查找已有的自定义 Hooks:",
|
|
477
|
-
" ```bash",
|
|
478
|
-
" find src/ -type f \\( -name 'use*.ts' -o -name 'use*.tsx' \\) | head -30",
|
|
479
|
-
" grep -rn '^export function use\\|^export const use' src/ --include='*.ts' --include='*.tsx'",
|
|
480
|
-
" ```",
|
|
481
|
-
"3. 查找已有的类型定义:",
|
|
482
|
-
" ```bash",
|
|
483
|
-
" find src/types/ -type f -name '*.ts' 2>/dev/null | head -20",
|
|
484
|
-
" grep -rn 'interface\\|type ' src/types/ --include='*.ts' 2>/dev/null | head -30",
|
|
485
|
-
" ```",
|
|
486
|
-
"4. 检查项目约定的文件组织方式和样式方案:",
|
|
487
|
-
" ```bash",
|
|
488
|
-
" ls -la src/",
|
|
489
|
-
" ls -la src/components/ 2>/dev/null",
|
|
490
|
-
" ```",
|
|
491
|
-
"5. 识别可复用的模式(组件结构、样式方案、测试模式)",
|
|
492
|
-
"",
|
|
493
|
-
"**产出格式**:",
|
|
494
|
-
"```",
|
|
495
|
-
"reusable_components: [{ name, path, description, reuse_approach: 'direct'|'extend'|'reference' }]",
|
|
496
|
-
"reusable_hooks: [{ name, path, description }]",
|
|
497
|
-
"existing_types: [{ name, path }]",
|
|
498
|
-
"project_patterns: { file_structure: '...', styling: '...', testing: '...' }",
|
|
499
|
-
"```",
|
|
500
|
-
].join("\n"),
|
|
501
|
-
suggestedTools: ["Bash", "Read"],
|
|
502
|
-
output: "可复用的组件、Hooks、类型清单和项目模式",
|
|
503
|
-
depends: ["analyze-requirements"],
|
|
504
|
-
},
|
|
505
|
-
{
|
|
506
|
-
id: "implement",
|
|
507
|
-
title: "实现功能代码",
|
|
508
|
-
instruction: [
|
|
509
|
-
"## 按照项目约定生成代码",
|
|
510
|
-
"",
|
|
511
|
-
"基于 `analyze-requirements`、`impact-analysis` 和 `check-existing-patterns` 的结果,实现功能代码。",
|
|
512
|
-
"",
|
|
513
|
-
"**执行动作**:",
|
|
514
|
-
"1. 按照项目文件结构约定创建新文件(参考 `check-existing-patterns` 发现的目录结构)",
|
|
515
|
-
"2. 优先复用已有的组件、Hooks 和工具函数",
|
|
516
|
-
"3. 遵循项目类型定义规范:",
|
|
517
|
-
" - Props 使用 `interface` 定义(不用 `type`)",
|
|
518
|
-
" - 事件处理器命名:`onXxx` 或 `handleXxx`",
|
|
519
|
-
"4. 确保所有新代码能通过 TypeScript 类型检查(无 `any`、无 `@ts-ignore`)",
|
|
520
|
-
"5. 使用 `React.memo` 包裹纯展示组件",
|
|
521
|
-
"6. 使用 `useMemo` / `useCallback` 避免不必要的重渲染(但不要过度优化)",
|
|
522
|
-
"7. 对关键逻辑添加注释",
|
|
523
|
-
"",
|
|
524
|
-
"**代码质量检查清单**:",
|
|
525
|
-
"- [ ] 所有函数组件(无 Class 组件)",
|
|
526
|
-
"- [ ] Props 有 TypeScript interface",
|
|
527
|
-
"- [ ] 无未使用的 import",
|
|
528
|
-
"- [ ] 无 `console.log` 残留",
|
|
529
|
-
"- [ ] 错误边界处理(try/catch 或 ErrorBoundary)",
|
|
530
|
-
"",
|
|
531
|
-
"**产出格式**:",
|
|
532
|
-
"```",
|
|
533
|
-
"files_created: [{ path, description }]",
|
|
534
|
-
"files_modified: [{ path, changes_summary }]",
|
|
535
|
-
"components: [{ name, path, is_memoized: true|false }]",
|
|
536
|
-
"hooks_used: ['useState', 'useEffect', ...]",
|
|
537
|
-
"```",
|
|
538
|
-
].join("\n"),
|
|
539
|
-
suggestedTools: ["Read", "Edit", "Write"],
|
|
540
|
-
output: "创建和修改的文件清单、组件列表",
|
|
541
|
-
depends: ["impact-analysis", "check-existing-patterns"],
|
|
542
|
-
},
|
|
543
|
-
{ id: "type-check", stepTemplate: "type-check", depends: ["implement"] },
|
|
544
|
-
{
|
|
545
|
-
id: "write-tests",
|
|
546
|
-
title: "编写测试",
|
|
547
|
-
instruction: [
|
|
548
|
-
"## 生成单元测试和集成测试",
|
|
549
|
-
"",
|
|
550
|
-
"为新功能编写充分的测试用例。",
|
|
551
|
-
"",
|
|
552
|
-
"**执行动作**:",
|
|
553
|
-
"1. 找到项目的测试目录约定:",
|
|
554
|
-
" ```bash",
|
|
555
|
-
" find src/ -type d -name '__tests__' -o -name '*.test.*' | head -20",
|
|
556
|
-
" ```",
|
|
557
|
-
"2. 为每个新组件 / Hook 创建对应的测试文件",
|
|
558
|
-
"3. 测试覆盖:",
|
|
559
|
-
" - **渲染测试**:组件能正确渲染(含默认 Props 和边界 Props)",
|
|
560
|
-
" - **交互测试**:用户操作(点击、输入、提交)触发正确行为",
|
|
561
|
-
" - **异步测试**:API 调用、数据加载、loading / error 状态",
|
|
562
|
-
" - **Hook 测试**:使用 `renderHook` 测试自定义 Hooks",
|
|
563
|
-
"4. 使用 `describe` / `it` 组织测试,命名清晰",
|
|
564
|
-
"5. Mock 策略:API 调用使用 `vi.mock`,Context 使用 wrapper",
|
|
565
|
-
"",
|
|
566
|
-
"**产出格式**:",
|
|
567
|
-
"```",
|
|
568
|
-
"test_files_created: [{ path, test_count: N }]",
|
|
569
|
-
"coverage_target: { statements: '>80%', branches: '>75%' }",
|
|
570
|
-
"test_cases: [{ describe: '...', it: '...', status: 'written' }]",
|
|
571
|
-
"```",
|
|
572
|
-
].join("\n"),
|
|
573
|
-
suggestedTools: ["Read", "Write", "Bash"],
|
|
574
|
-
output: "创建的测试文件清单、测试用例列表",
|
|
575
|
-
depends: ["implement"],
|
|
576
|
-
},
|
|
577
|
-
{ id: "run-tests", stepTemplate: "run-tests", depends: ["type-check", "write-tests"] },
|
|
578
|
-
{ id: "code-review", stepTemplate: "human-review", depends: ["run-tests"] },
|
|
579
|
-
],
|
|
580
|
-
triggers: [
|
|
581
|
-
{ type: "cli", command: "feature" },
|
|
582
|
-
{ type: "mcp", tool: "new_feature" },
|
|
583
|
-
],
|
|
584
|
-
},
|
|
585
|
-
// ── 性能审计优化 ──
|
|
586
|
-
{
|
|
587
|
-
name: "performance-audit",
|
|
588
|
-
description: "性能审计:渲染分析 → 优化方案 → 基准对比",
|
|
589
|
-
version: "2.0.0",
|
|
590
|
-
steps: [
|
|
591
|
-
{
|
|
592
|
-
id: "profile-renders",
|
|
593
|
-
title: "分析组件渲染性能",
|
|
594
|
-
instruction: [
|
|
595
|
-
"## 使用 React DevTools Profiler 分析组件渲染",
|
|
596
|
-
"",
|
|
597
|
-
"扫描项目源码,识别可能存在渲染性能问题的组件。",
|
|
598
|
-
"",
|
|
599
|
-
"**执行动作**:",
|
|
600
|
-
"1. 找出项目中所有 React 组件文件:",
|
|
601
|
-
" ```bash",
|
|
602
|
-
" find src/ -type f \\( -name '*.tsx' -o -name '*.jsx' \\) | head -100",
|
|
603
|
-
" ```",
|
|
604
|
-
"2. 检查每个组件的渲染复杂度:",
|
|
605
|
-
" - 组件 JSX 行数(>100 行的 JSX 为高风险)",
|
|
606
|
-
" - 嵌套层级(>3 层嵌套为高风险)",
|
|
607
|
-
" - 列表渲染(`.map` 调用次数)",
|
|
608
|
-
" ```bash",
|
|
609
|
-
" grep -rn '\\.map(' src/ --include='*.tsx' --include='*.jsx' | head -30",
|
|
610
|
-
" ```",
|
|
611
|
-
"3. 检查是否存在频繁渲染的嫌疑组件:",
|
|
612
|
-
" - 消费了全局 Context 的组件",
|
|
613
|
-
" - 使用了 `useState` / `useReducer` 且频繁更新的组件",
|
|
614
|
-
" ```bash",
|
|
615
|
-
" grep -rn 'useContext\\|useState\\|useReducer' src/ --include='*.tsx' --include='*.jsx' | wc -l",
|
|
616
|
-
" ```",
|
|
617
|
-
"4. 查看组件是否有 `React.memo` 包裹",
|
|
618
|
-
"",
|
|
619
|
-
"**产出格式**:",
|
|
620
|
-
"```",
|
|
621
|
-
"total_components: <N>",
|
|
622
|
-
"high_risk_components: [{ name, path, jsx_lines: N, map_calls: N, has_memo: false }]",
|
|
623
|
-
"context_consumers: [{ name, path, context_name: '...' }]",
|
|
624
|
-
"```",
|
|
625
|
-
].join("\n"),
|
|
626
|
-
suggestedTools: ["Bash", "Read"],
|
|
627
|
-
output: "渲染性能风险分析、高风险组件清单",
|
|
628
|
-
},
|
|
629
|
-
{
|
|
630
|
-
id: "audit-memoization",
|
|
631
|
-
title: "审查 Memoization 使用情况",
|
|
632
|
-
instruction: [
|
|
633
|
-
"## 检查 useMemo / useCallback / React.memo 使用情况",
|
|
634
|
-
"",
|
|
635
|
-
"**执行动作**:",
|
|
636
|
-
"1. 统计项目中 Memoization 的使用情况:",
|
|
637
|
-
" ```bash",
|
|
638
|
-
" echo '--- useMemo ---'",
|
|
639
|
-
" grep -rn 'useMemo' src/ --include='*.tsx' --include='*.ts' --include='*.jsx' | wc -l",
|
|
640
|
-
" echo '--- useCallback ---'",
|
|
641
|
-
" grep -rn 'useCallback' src/ --include='*.tsx' --include='*.ts' --include='*.jsx' | wc -l",
|
|
642
|
-
" echo '--- React.memo ---'",
|
|
643
|
-
" grep -rn 'React\\.memo\\|memo(' src/ --include='*.tsx' --include='*.jsx' | wc -l",
|
|
644
|
-
" ```",
|
|
645
|
-
"2. 检查缺失 memoization 的场景:",
|
|
646
|
-
" - 组件接收对象/数组/函数 props 但未被 `React.memo` 包裹",
|
|
647
|
-
" - 复杂计算(>5 行逻辑)未使用 `useMemo`",
|
|
648
|
-
" - 传递给子组件的回调函数未使用 `useCallback`",
|
|
649
|
-
"3. 检查过度 memoization 的场景:",
|
|
650
|
-
" - `useMemo` 包裹简单值(如常量、字面量)",
|
|
651
|
-
" - `useMemo` 的依赖数组每次渲染都变化",
|
|
652
|
-
" ```bash",
|
|
653
|
-
" grep -rn 'useMemo\\|useCallback' src/ --include='*.tsx' --include='*.ts' -A 3",
|
|
654
|
-
" ```",
|
|
655
|
-
"",
|
|
656
|
-
"**产出格式**:",
|
|
657
|
-
"```",
|
|
658
|
-
"memoization_stats: { useMemo: N, useCallback: N, React.memo: N }",
|
|
659
|
-
"missing_memoization: [{ file, line, issue: '函数 prop 未用 useCallback' }]",
|
|
660
|
-
"over_memoization: [{ file, line, issue: 'useMemo 包裹简单字面量' }]",
|
|
661
|
-
"```",
|
|
662
|
-
].join("\n"),
|
|
663
|
-
suggestedTools: ["Bash", "Read"],
|
|
664
|
-
output: "Memoization 使用统计、缺失和过度使用的清单",
|
|
665
|
-
},
|
|
666
|
-
{
|
|
667
|
-
id: "detect-rerenders",
|
|
668
|
-
title: "检测不必要的重渲染",
|
|
669
|
-
instruction: [
|
|
670
|
-
"## 检测不必要的重渲染",
|
|
671
|
-
"",
|
|
672
|
-
"**执行动作**:",
|
|
673
|
-
"1. 检查 Props 引用稳定性问题:",
|
|
674
|
-
" ```bash",
|
|
675
|
-
" # 查找内联对象/数组/函数作为 props 传递",
|
|
676
|
-
" grep -rn '<[A-Z][a-zA-Z]* [^>]*style={{' src/ --include='*.tsx' --include='*.jsx'",
|
|
677
|
-
" grep -rn '<[A-Z][a-zA-Z]* [^>]*onClick={() =>' src/ --include='*.tsx' --include='*.jsx'",
|
|
678
|
-
" grep -rn '<[A-Z][a-zA-Z]* [^>]*\\[.*\\]' src/ --include='*.tsx' --include='*.jsx'",
|
|
679
|
-
" ```",
|
|
680
|
-
"2. 检查 Context 过度更新问题:",
|
|
681
|
-
" ```bash",
|
|
682
|
-
" # 查找 Context Provider 中包含频繁变化的值",
|
|
683
|
-
" grep -rn 'Provider' src/ --include='*.tsx' --include='*.ts' -B 2 -A 5",
|
|
684
|
-
" ```",
|
|
685
|
-
"3. 检查 key 使用问题:",
|
|
686
|
-
" ```bash",
|
|
687
|
-
" # 检查列表渲染中的 key 是否稳定",
|
|
688
|
-
" grep -rn 'key={' src/ --include='*.tsx' --include='*.jsx' | head -30",
|
|
689
|
-
" ```",
|
|
690
|
-
"4. 检查 useEffect 依赖数组不稳定(每次渲染都触发)",
|
|
691
|
-
"5. 检查 state 提升是否合理(是否应该拆分 state)",
|
|
692
|
-
"",
|
|
693
|
-
"**产出格式**:",
|
|
694
|
-
"```",
|
|
695
|
-
"inline_object_props: [{ file, line, component: '...' }]",
|
|
696
|
-
"inline_function_props: [{ file, line, component: '...' }]",
|
|
697
|
-
"context_rerender_risks: [{ context_name, provider_file, consumer_count: N }]",
|
|
698
|
-
"unstable_keys: [{ file, line, issue: '...' }]",
|
|
699
|
-
"```",
|
|
700
|
-
].join("\n"),
|
|
701
|
-
suggestedTools: ["Bash", "Read"],
|
|
702
|
-
output: "不必要的重渲染原因清单",
|
|
703
|
-
},
|
|
704
|
-
{
|
|
705
|
-
id: "analyze-bundle",
|
|
706
|
-
title: "分析打包体积",
|
|
707
|
-
instruction: [
|
|
708
|
-
"## 分析打包体积",
|
|
709
|
-
"",
|
|
710
|
-
"**执行动作**:",
|
|
711
|
-
"1. 检查打包配置和产物:",
|
|
712
|
-
" ```bash",
|
|
713
|
-
" # 查看 package.json 的依赖大小",
|
|
714
|
-
" cat package.json | grep -A 50 '\"dependencies\"'",
|
|
715
|
-
" # 查看是否有 build 产物",
|
|
716
|
-
" ls -la dist/ 2>/dev/null || ls -la build/ 2>/dev/null || echo 'No build output found'",
|
|
717
|
-
" ```",
|
|
718
|
-
"2. 检查大依赖(常见的大包):",
|
|
719
|
-
" ```bash",
|
|
720
|
-
" # 检查 moment, lodash 全量导入等大依赖",
|
|
721
|
-
" grep -rn \"from 'moment'\\|from 'lodash'\\|from 'ramda'\" src/ --include='*.tsx' --include='*.ts'",
|
|
722
|
-
" # 检查是否有重复依赖",
|
|
723
|
-
" npm ls --depth=0 2>&1 | head -30",
|
|
724
|
-
" ```",
|
|
725
|
-
"3. 检查动态导入(懒加载)使用情况:",
|
|
726
|
-
" ```bash",
|
|
727
|
-
" grep -rn 'import(' src/ --include='*.tsx' --include='*.ts'",
|
|
728
|
-
" grep -rn 'React\\.lazy\\|lazy(' src/ --include='*.tsx' --include='*.ts'",
|
|
729
|
-
" ```",
|
|
730
|
-
"4. 检查 barrel file(index.ts)是否导致 tree-shaking 失效",
|
|
731
|
-
"5. 估算各依赖的体积占比",
|
|
732
|
-
"",
|
|
733
|
-
"**产出格式**:",
|
|
734
|
-
"```",
|
|
735
|
-
"large_dependencies: [{ name, estimated_size: 'N KB', reason: '全量导入 lodash' }]",
|
|
736
|
-
"lazy_loaded_components: [{ name, path }]",
|
|
737
|
-
"barrel_files: [{ path, exports_count: N, tree_shakeable: true|false }]",
|
|
738
|
-
"optimization_suggestions: ['...']",
|
|
739
|
-
"```",
|
|
740
|
-
].join("\n"),
|
|
741
|
-
suggestedTools: ["Bash", "Read"],
|
|
742
|
-
output: "打包体积分析报告、大依赖清单、优化建议",
|
|
743
|
-
},
|
|
744
|
-
{
|
|
745
|
-
id: "generate-report",
|
|
746
|
-
title: "生成性能分析报告",
|
|
747
|
-
instruction: [
|
|
748
|
-
"## 生成性能分析报告",
|
|
749
|
-
"",
|
|
750
|
-
"汇总所有分析结果,生成优先级排序的优化方案。",
|
|
751
|
-
"",
|
|
752
|
-
"**报告格式**:",
|
|
753
|
-
"```markdown",
|
|
754
|
-
"## React 性能审计报告",
|
|
755
|
-
"",
|
|
756
|
-
"### 概览",
|
|
757
|
-
"- 总组件数:<N>",
|
|
758
|
-
"- 高风险组件:<N>",
|
|
759
|
-
"- 缺失 memoization:<N> 处",
|
|
760
|
-
"- 不必要的重渲染:<N> 处",
|
|
761
|
-
"",
|
|
762
|
-
"### 优化建议(按优先级排序)",
|
|
763
|
-
"",
|
|
764
|
-
"#### P0 — 必须优化(影响用户感知性能)",
|
|
765
|
-
"| 问题 | 位置 | 预计收益 |",
|
|
766
|
-
"|------|------|----------|",
|
|
767
|
-
"",
|
|
768
|
-
"#### P1 — 建议优化(减少不必要计算)",
|
|
769
|
-
"| 问题 | 位置 | 预计收益 |",
|
|
770
|
-
"|------|------|----------|",
|
|
771
|
-
"",
|
|
772
|
-
"#### P2 — 可选优化(代码质量改善)",
|
|
773
|
-
"| 问题 | 位置 | 预计收益 |",
|
|
774
|
-
"|------|------|----------|",
|
|
775
|
-
"",
|
|
776
|
-
"### 打包优化",
|
|
777
|
-
"- 可替换的大依赖:[...]",
|
|
778
|
-
"- 可懒加载的组件:[...]",
|
|
779
|
-
"```",
|
|
780
|
-
].join("\n"),
|
|
781
|
-
suggestedTools: ["Read"],
|
|
782
|
-
output: "分优先级的完整性能审计报告",
|
|
783
|
-
depends: ["profile-renders", "audit-memoization", "detect-rerenders", "analyze-bundle"],
|
|
784
|
-
},
|
|
785
|
-
{
|
|
786
|
-
id: "apply-optimizations",
|
|
787
|
-
title: "应用性能优化",
|
|
788
|
-
instruction: [
|
|
789
|
-
"## 应用性能优化",
|
|
790
|
-
"",
|
|
791
|
-
"根据 `generate-report` 的优化建议,逐项应用代码变更。",
|
|
792
|
-
"",
|
|
793
|
-
"**执行动作**:",
|
|
794
|
-
"1. **P0 优化**(必须):",
|
|
795
|
-
" - 为大列表添加虚拟滚动(react-window / react-virtuoso)",
|
|
796
|
-
" - 为纯展示组件添加 `React.memo`",
|
|
797
|
-
" - 将内联对象/函数改为 `useMemo` / `useCallback`",
|
|
798
|
-
"2. **P1 优化**(建议):",
|
|
799
|
-
" - 拆分大型 Context(避免无关组件重渲染)",
|
|
800
|
-
" - 使用 `useDeferredValue` / `useTransition` 优化用户交互",
|
|
801
|
-
" - 组件懒加载:`React.lazy(() => import('./HeavyComponent'))`",
|
|
802
|
-
"3. **P2 优化**(可选):",
|
|
803
|
-
" - 替换大依赖(如 `moment` → `dayjs`、`lodash` → `lodash-es`)",
|
|
804
|
-
" - 优化 barrel file 以改善 tree-shaking",
|
|
805
|
-
"4. 每项优化后,使用 Edit 工具精准修改代码",
|
|
806
|
-
"5. 不做过度优化:简单组件不需要 memo",
|
|
807
|
-
"",
|
|
808
|
-
"**产出格式**:",
|
|
809
|
-
"```",
|
|
810
|
-
"optimizations_applied: [",
|
|
811
|
-
" { type: 'memo'|'useMemo'|'useCallback'|'lazy'|'virtual-list', file, changes_summary }",
|
|
812
|
-
"]",
|
|
813
|
-
"estimated_improvement: <预估渲染次数减少 / 体积减少>",
|
|
814
|
-
"```",
|
|
815
|
-
].join("\n"),
|
|
816
|
-
suggestedTools: ["Read", "Edit", "Bash"],
|
|
817
|
-
output: "应用的优化清单、预估收益",
|
|
818
|
-
depends: ["generate-report"],
|
|
819
|
-
},
|
|
820
|
-
{
|
|
821
|
-
id: "benchmark-compare",
|
|
822
|
-
title: "优化前后对比",
|
|
823
|
-
instruction: [
|
|
824
|
-
"## 优化前后渲染次数和打包体积对比",
|
|
825
|
-
"",
|
|
826
|
-
"**执行动作**:",
|
|
827
|
-
"1. 重新检查优化后的代码状态:",
|
|
828
|
-
" ```bash",
|
|
829
|
-
" echo '--- 优化后 memoization ---'",
|
|
830
|
-
" grep -rn 'useMemo\\|useCallback\\|React\\.memo' src/ --include='*.tsx' --include='*.ts' | wc -l",
|
|
831
|
-
" echo '--- 优化后内联 props ---'",
|
|
832
|
-
" grep -rn '<[A-Z][a-zA-Z]* [^>]*style={{' src/ --include='*.tsx' --include='*.jsx'",
|
|
833
|
-
" ```",
|
|
834
|
-
"2. 运行构建查看产物大小变化:",
|
|
835
|
-
" ```bash",
|
|
836
|
-
" npm run build 2>&1 | tail -20",
|
|
837
|
-
" ```",
|
|
838
|
-
"3. 运行测试确认无回归:",
|
|
839
|
-
" ```bash",
|
|
840
|
-
" npm test 2>&1",
|
|
841
|
-
" ```",
|
|
842
|
-
"4. 对比优化前后指标",
|
|
843
|
-
"",
|
|
844
|
-
"**产出格式**:",
|
|
845
|
-
"```",
|
|
846
|
-
"before: { components: N, memoization_count: N, inline_props: N, bundle_size: 'N KB' }",
|
|
847
|
-
"after: { components: N, memoization_count: N, inline_props: N, bundle_size: 'N KB' }",
|
|
848
|
-
"delta: { memoization: +N, inline_props: -N, bundle_size: '-N KB' }",
|
|
849
|
-
"tests: passed | failed",
|
|
850
|
-
"```",
|
|
851
|
-
].join("\n"),
|
|
852
|
-
suggestedTools: ["Bash", "Read"],
|
|
853
|
-
output: "优化前后指标对比",
|
|
854
|
-
depends: ["apply-optimizations"],
|
|
855
|
-
},
|
|
856
|
-
{
|
|
857
|
-
id: "approve-optimizations",
|
|
858
|
-
title: "人工确认优化方案",
|
|
859
|
-
instruction: [
|
|
860
|
-
"## 人工确认性能优化方案",
|
|
861
|
-
"",
|
|
862
|
-
"将所有优化结果和前后对比呈现给用户,等待确认。",
|
|
863
|
-
"",
|
|
864
|
-
"**呈现给用户的摘要**:",
|
|
865
|
-
"",
|
|
866
|
-
"### 📊 性能优化报告",
|
|
867
|
-
"",
|
|
868
|
-
"**优化项**:",
|
|
869
|
-
"- P0: <N> 项(必须优化)",
|
|
870
|
-
"- P1: <N> 项(建议优化)",
|
|
871
|
-
"- P2: <N> 项(可选优化)",
|
|
872
|
-
"",
|
|
873
|
-
"**指标变化**:",
|
|
874
|
-
"- 渲染性能:预计减少 <N> 次不必要的重渲染",
|
|
875
|
-
"- 打包体积:预计减少 <N> KB",
|
|
876
|
-
"",
|
|
877
|
-
"**修改文件**:<列出所有修改的文件>",
|
|
878
|
-
"",
|
|
879
|
-
"**等待用户操作**:",
|
|
880
|
-
"- 审查优化方案是否影响业务逻辑",
|
|
881
|
-
"- 确认后执行 `git commit`",
|
|
882
|
-
"",
|
|
883
|
-
"**注意**:此步骤必须等待用户明确确认后才能继续。",
|
|
884
|
-
].join("\n"),
|
|
885
|
-
suggestedTools: ["Read"],
|
|
886
|
-
output: "用户确认结果",
|
|
887
|
-
depends: ["benchmark-compare"],
|
|
888
|
-
requiresUserConfirmation: true,
|
|
889
|
-
},
|
|
890
|
-
],
|
|
891
|
-
triggers: [
|
|
892
|
-
{ type: "cli", command: "perf" },
|
|
893
|
-
{ type: "mcp", tool: "audit_performance" },
|
|
894
|
-
],
|
|
895
|
-
},
|
|
896
|
-
// ── Hooks 审查修复 ──
|
|
897
|
-
{
|
|
898
|
-
name: "hook-review",
|
|
899
|
-
description: "Hooks 审查:规则检查 → 依赖分析 → 自动修复",
|
|
900
|
-
version: "2.0.0",
|
|
901
|
-
steps: [
|
|
902
|
-
{
|
|
903
|
-
id: "scan-all-hooks",
|
|
904
|
-
title: "全量扫描项目中所有 Hooks 调用位置",
|
|
905
|
-
instruction: [
|
|
906
|
-
"## 全量扫描所有 Hooks 调用位置",
|
|
907
|
-
"",
|
|
908
|
-
"必须遍历项目中**所有**源代码目录,不能只扫描部分目录。",
|
|
909
|
-
"",
|
|
910
|
-
"**第一步:发现所有源码目录**",
|
|
911
|
-
"```bash",
|
|
912
|
-
"# 找到所有包含 .tsx/.ts/.jsx/.js 文件的目录",
|
|
913
|
-
"find src/ -type f \\( -name '*.tsx' -o -name '*.ts' -o -name '*.jsx' -o -name '*.js' \\) | head -200",
|
|
914
|
-
"",
|
|
915
|
-
"# 特别列出所有 pages 子目录(如果有)",
|
|
916
|
-
"find src/pages/ -type d 2>/dev/null || echo 'No src/pages/ directory'",
|
|
917
|
-
"",
|
|
918
|
-
"# 列出所有 components 子目录",
|
|
919
|
-
"find src/components/ -type d 2>/dev/null || echo 'No src/components/ directory'",
|
|
920
|
-
"",
|
|
921
|
-
"# 列出所有 hooks 目录",
|
|
922
|
-
"find src/ -type d -name 'hooks' 2>/dev/null",
|
|
923
|
-
"```",
|
|
924
|
-
"",
|
|
925
|
-
"**第二步:全量 grep 所有 Hooks 调用**",
|
|
926
|
-
"```bash",
|
|
927
|
-
"# 搜索所有 React 内置 Hooks",
|
|
928
|
-
"grep -rn 'useState\\|useEffect\\|useMemo\\|useCallback\\|useRef\\|useContext\\|useReducer\\|useLayoutEffect\\|useImperativeHandle\\|useDebugValue\\|useTransition\\|useDeferredValue\\|useId' src/ --include='*.tsx' --include='*.ts' --include='*.jsx' --include='*.js'",
|
|
929
|
-
"",
|
|
930
|
-
"# 搜索自定义 Hooks(以 use 开头的函数调用)",
|
|
931
|
-
"grep -rn 'use[A-Z][a-zA-Z]*\\s*(' src/ --include='*.tsx' --include='*.ts' --include='*.jsx' --include='*.js' | grep -v 'node_modules'",
|
|
932
|
-
"```",
|
|
933
|
-
"",
|
|
934
|
-
"**第三步:统计覆盖范围**",
|
|
935
|
-
"```bash",
|
|
936
|
-
"# 统计包含 Hooks 的文件总数",
|
|
937
|
-
"grep -rl 'use[A-Z]' src/ --include='*.tsx' --include='*.ts' | wc -l",
|
|
938
|
-
"",
|
|
939
|
-
"# 按目录统计 Hooks 文件分布",
|
|
940
|
-
"grep -rl 'use[A-Z]' src/ --include='*.tsx' --include='*.ts' | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn",
|
|
941
|
-
"```",
|
|
942
|
-
"",
|
|
943
|
-
"**产出格式**:",
|
|
944
|
-
"```",
|
|
945
|
-
"total_files_with_hooks: <数量>",
|
|
946
|
-
"directories_scanned: [<列出所有扫描的目录>]",
|
|
947
|
-
"hooks_files_by_dir: { 'src/pages/xxx': N, 'src/components/xxx': N, ... }",
|
|
948
|
-
"custom_hooks_found: [<列出所有自定义 Hook 名称>]",
|
|
949
|
-
"```",
|
|
950
|
-
].join("\n"),
|
|
951
|
-
suggestedTools: ["Bash", "Read"],
|
|
952
|
-
output: "所有 Hooks 调用位置的完整清单,按目录分组",
|
|
953
|
-
timeout: 30000,
|
|
954
|
-
},
|
|
955
|
-
{
|
|
956
|
-
id: "check-top-level",
|
|
957
|
-
title: "检查 Hooks 顶层调用规则",
|
|
958
|
-
instruction: [
|
|
959
|
-
"## 检查 Hooks 是否在顶层调用",
|
|
960
|
-
"",
|
|
961
|
-
"基于 `scan-all-hooks` 的结果,逐个检查每个 Hooks 调用是否违反顶层调用规则。",
|
|
962
|
-
"",
|
|
963
|
-
"**检查项**:",
|
|
964
|
-
"1. Hooks 不在 `if/else` 条件分支中调用",
|
|
965
|
-
"2. Hooks 不在 `for/while` 循环中调用",
|
|
966
|
-
"3. Hooks 不在嵌套函数(回调、事件处理器内部)中调用",
|
|
967
|
-
"4. Hooks 不在 `try/catch` 块中调用",
|
|
968
|
-
"",
|
|
969
|
-
"**执行方式**:",
|
|
970
|
-
"```bash",
|
|
971
|
-
"# 对每个包含 Hooks 的文件,用 Read 工具读取并人工检查上下文",
|
|
972
|
-
"# 重点检查 Hooks 调用是否在条件/循环/嵌套函数内",
|
|
973
|
-
"```",
|
|
974
|
-
"",
|
|
975
|
-
"**产出格式**:",
|
|
976
|
-
"```",
|
|
977
|
-
"violations: [",
|
|
978
|
-
" { file: 'src/pages/xxx/index.tsx', line: 42, hook: 'useState', issue: '在 if 条件内调用' }",
|
|
979
|
-
"]",
|
|
980
|
-
"```",
|
|
981
|
-
].join("\n"),
|
|
982
|
-
suggestedTools: ["Bash", "Read"],
|
|
983
|
-
output: "违反顶层调用规则的位置清单",
|
|
984
|
-
depends: ["scan-all-hooks"],
|
|
985
|
-
timeout: 20000,
|
|
986
|
-
},
|
|
987
|
-
{
|
|
988
|
-
id: "audit-deps-arrays",
|
|
989
|
-
title: "审查依赖数组完整性",
|
|
990
|
-
instruction: [
|
|
991
|
-
"## 检查 useEffect/useMemo/useCallback 依赖数组",
|
|
992
|
-
"",
|
|
993
|
-
"**执行方式**:",
|
|
994
|
-
"```bash",
|
|
995
|
-
"# 找到所有 useEffect/useMemo/useCallback 调用及其依赖数组",
|
|
996
|
-
"grep -rn 'useEffect\\|useMemo\\|useCallback' src/ --include='*.tsx' --include='*.ts' -A 5",
|
|
997
|
-
"```",
|
|
998
|
-
"",
|
|
999
|
-
"**检查项**:",
|
|
1000
|
-
"1. 依赖数组是否遗漏了回调/计算中使用的变量",
|
|
1001
|
-
"2. 是否有意忽略了某些依赖(如果有 eslint-disable 注释,检查是否合理)",
|
|
1002
|
-
"3. 对象/数组依赖是否因引用变化导致不必要的重执行",
|
|
1003
|
-
"4. 函数依赖是否应该用 useCallback 包裹",
|
|
1004
|
-
"",
|
|
1005
|
-
"**产出格式**:",
|
|
1006
|
-
"```",
|
|
1007
|
-
"missing_deps: [",
|
|
1008
|
-
" { file: '...', line: N, hook: 'useEffect', missing: ['userId'], current: [] }",
|
|
1009
|
-
"]",
|
|
1010
|
-
"unnecessary_deps: [...]",
|
|
1011
|
-
"```",
|
|
1012
|
-
].join("\n"),
|
|
1013
|
-
suggestedTools: ["Bash", "Read"],
|
|
1014
|
-
output: "依赖数组问题清单(缺失/多余/不稳定依赖)",
|
|
1015
|
-
depends: ["scan-all-hooks"],
|
|
1016
|
-
timeout: 20000,
|
|
1017
|
-
},
|
|
1018
|
-
{
|
|
1019
|
-
id: "audit-cleanups",
|
|
1020
|
-
title: "审查 useEffect 清理函数",
|
|
1021
|
-
instruction: [
|
|
1022
|
-
"## 检查 useEffect 清理函数",
|
|
1023
|
-
"",
|
|
1024
|
-
"**检查项**:",
|
|
1025
|
-
"1. 使用了订阅(addEventListener、subscribe)的 useEffect 是否有清理函数",
|
|
1026
|
-
"2. 使用了定时器(setTimeout、setInterval)的 useEffect 是否在清理中清除",
|
|
1027
|
-
"3. 使用了异步请求的 useEffect 是否有 AbortController 或取消标记",
|
|
1028
|
-
"4. WebSocket 连接是否在清理函数中关闭",
|
|
1029
|
-
"",
|
|
1030
|
-
"**执行方式**:",
|
|
1031
|
-
"```bash",
|
|
1032
|
-
"# 找到包含副作用但可能缺少清理的 useEffect",
|
|
1033
|
-
"grep -rn 'useEffect' src/ --include='*.tsx' --include='*.ts' -A 10 | grep -E 'addEventListener|subscribe|setTimeout|setInterval|fetch|WebSocket|connect'",
|
|
1034
|
-
"```",
|
|
1035
|
-
"",
|
|
1036
|
-
"**产出格式**:",
|
|
1037
|
-
"```",
|
|
1038
|
-
"missing_cleanup: [",
|
|
1039
|
-
" { file: '...', line: N, side_effect: 'addEventListener', description: '缺少 removeEventListener 清理' }",
|
|
1040
|
-
"]",
|
|
1041
|
-
"```",
|
|
1042
|
-
].join("\n"),
|
|
1043
|
-
suggestedTools: ["Bash", "Read"],
|
|
1044
|
-
output: "缺少清理函数的 useEffect 清单",
|
|
1045
|
-
depends: ["scan-all-hooks"],
|
|
1046
|
-
timeout: 15000,
|
|
1047
|
-
},
|
|
1048
|
-
{
|
|
1049
|
-
id: "detect-anti-patterns",
|
|
1050
|
-
title: "检测 React 反模式",
|
|
1051
|
-
instruction: [
|
|
1052
|
-
"## 检测 React 反模式",
|
|
1053
|
-
"",
|
|
1054
|
-
"基于 `scan-all-hooks` 的完整文件列表,检测以下反模式:",
|
|
1055
|
-
"",
|
|
1056
|
-
"**反模式清单**:",
|
|
1057
|
-
"1. **渲染中创建组件** — 在函数体内部定义 `function` 或 `const Component = () =>`",
|
|
1058
|
-
"2. **不必要的 useState** — 可以用计算值替代的状态(如 `const [full, setFull] = useState(first + last)`)",
|
|
1059
|
-
"3. **过大的 useEffect** — 单个 useEffect 超过 20 行,应拆分",
|
|
1060
|
-
"4. **useEffect 作为事件处理器** — 用 useEffect 响应事件而非用事件处理函数",
|
|
1061
|
-
"5. **直接修改 state** — `state.xxx = yyy` 而非 `setState`",
|
|
1062
|
-
"6. **key 使用 index** — 列表渲染使用数组 index 作为 key",
|
|
1063
|
-
"",
|
|
1064
|
-
"**执行方式**:",
|
|
1065
|
-
"```bash",
|
|
1066
|
-
"# 检测渲染中定义组件",
|
|
1067
|
-
"grep -rn 'const [A-Z].*= () =>\\|function [A-Z]' src/ --include='*.tsx' | grep -v '^.*:.*export'",
|
|
1068
|
-
"",
|
|
1069
|
-
"# 检测 key={index} 模式",
|
|
1070
|
-
"grep -rn 'key={.*index\\|key={.*i}' src/ --include='*.tsx'",
|
|
1071
|
-
"```",
|
|
1072
|
-
"",
|
|
1073
|
-
"**产出格式**:",
|
|
1074
|
-
"```",
|
|
1075
|
-
"anti_patterns: [",
|
|
1076
|
-
" { file: '...', line: N, type: 'component-in-render', severity: 'Critical', description: '...' }",
|
|
1077
|
-
"]",
|
|
1078
|
-
"```",
|
|
1079
|
-
].join("\n"),
|
|
1080
|
-
suggestedTools: ["Bash", "Read"],
|
|
1081
|
-
output: "反模式清单,按 Critical/Warning/Suggestion 分级",
|
|
1082
|
-
depends: ["scan-all-hooks"],
|
|
1083
|
-
timeout: 20000,
|
|
1084
|
-
},
|
|
1085
|
-
{
|
|
1086
|
-
id: "generate-review-report",
|
|
1087
|
-
title: "生成审查报告",
|
|
1088
|
-
instruction: [
|
|
1089
|
-
"## 生成 Hooks 审查报告",
|
|
1090
|
-
"",
|
|
1091
|
-
"汇总所有检查结果,生成结构化报告。",
|
|
1092
|
-
"",
|
|
1093
|
-
"**报告格式**:",
|
|
1094
|
-
"```",
|
|
1095
|
-
"## React Hooks 审查报告",
|
|
1096
|
-
"",
|
|
1097
|
-
"### 扫描覆盖",
|
|
1098
|
-
"- 扫描目录:<列出所有目录>",
|
|
1099
|
-
"- 扫描文件数:<N>",
|
|
1100
|
-
"- 发现 Hooks 调用总数:<N>",
|
|
1101
|
-
"",
|
|
1102
|
-
"### Critical(必须修复)",
|
|
1103
|
-
"| 文件 | 行号 | 问题 | 描述 |",
|
|
1104
|
-
"|------|------|------|------|",
|
|
1105
|
-
"| src/pages/xxx | 42 | 条件调用 Hook | useState 在 if 内调用 |",
|
|
1106
|
-
"",
|
|
1107
|
-
"### Warning(建议修复)",
|
|
1108
|
-
"| 文件 | 行号 | 问题 | 描述 |",
|
|
1109
|
-
"|------|------|------|------|",
|
|
1110
|
-
"",
|
|
1111
|
-
"### Suggestion(可选优化)",
|
|
1112
|
-
"| 文件 | 行号 | 问题 | 描述 |",
|
|
1113
|
-
"|------|------|------|------|",
|
|
1114
|
-
"```",
|
|
1115
|
-
].join("\n"),
|
|
1116
|
-
suggestedTools: ["Read"],
|
|
1117
|
-
output: "分优先级的完整审查报告",
|
|
1118
|
-
depends: ["check-top-level", "audit-deps-arrays", "audit-cleanups", "detect-anti-patterns"],
|
|
1119
|
-
timeout: 20000,
|
|
1120
|
-
},
|
|
1121
|
-
{
|
|
1122
|
-
id: "auto-fix-safe",
|
|
1123
|
-
title: "自动修复安全问题",
|
|
1124
|
-
instruction: [
|
|
1125
|
-
"## 自动修复安全的 Hooks 问题",
|
|
1126
|
-
"",
|
|
1127
|
-
"**可安全自动修复的问题**:",
|
|
1128
|
-
"1. 补充 useEffect/useMemo/useCallback 缺失的依赖项",
|
|
1129
|
-
"2. 为缺少清理的 useEffect 添加清理函数骨架",
|
|
1130
|
-
"3. 将 `key={index}` 改为使用唯一标识符",
|
|
1131
|
-
"",
|
|
1132
|
-
"**不可自动修复(需人工判断)**:",
|
|
1133
|
-
"- 条件调用 Hook — 需要重构逻辑",
|
|
1134
|
-
"- 反模式 — 需要理解业务意图",
|
|
1135
|
-
"",
|
|
1136
|
-
"**执行方式**:使用 Edit 工具逐个修复,每次修改后确认不影响周围代码。",
|
|
1137
|
-
].join("\n"),
|
|
1138
|
-
suggestedTools: ["Read", "Edit"],
|
|
1139
|
-
output: "修复的 diff 列表",
|
|
1140
|
-
depends: ["generate-review-report"],
|
|
1141
|
-
timeout: 30000,
|
|
1142
|
-
},
|
|
1143
|
-
{
|
|
1144
|
-
id: "verify-fixes",
|
|
1145
|
-
title: "验证修复",
|
|
1146
|
-
instruction: [
|
|
1147
|
-
"## 验证修复结果",
|
|
1148
|
-
"",
|
|
1149
|
-
"**执行动作**:",
|
|
1150
|
-
"1. 运行 TypeScript 类型检查:`npx tsc --noEmit`",
|
|
1151
|
-
"2. 运行 ESLint(如有 hooks 插件):`npx eslint src/ --ext .tsx,.ts`",
|
|
1152
|
-
"3. 运行项目测试:`npm test`",
|
|
1153
|
-
"4. 确认所有修复未引入新问题",
|
|
1154
|
-
].join("\n"),
|
|
1155
|
-
suggestedTools: ["Bash"],
|
|
1156
|
-
output: "验证结果(类型检查/ESLint/测试)",
|
|
1157
|
-
depends: ["auto-fix-safe"],
|
|
1158
|
-
timeout: 30000,
|
|
1159
|
-
},
|
|
1160
|
-
{
|
|
1161
|
-
id: "approve-fixes",
|
|
1162
|
-
title: "人工审查修复",
|
|
1163
|
-
instruction: [
|
|
1164
|
-
"## 人工审查高风险修复项",
|
|
1165
|
-
"",
|
|
1166
|
-
"将所有修复呈现给用户,等待确认。展示每个修复的 diff 和原因。",
|
|
1167
|
-
"",
|
|
1168
|
-
"**注意**:此步骤必须等待用户明确确认后才能继续。",
|
|
1169
|
-
].join("\n"),
|
|
1170
|
-
suggestedTools: ["Read"],
|
|
1171
|
-
output: "用户确认结果",
|
|
1172
|
-
depends: ["verify-fixes"],
|
|
1173
|
-
requiresUserConfirmation: true,
|
|
1174
|
-
timeout: 120000,
|
|
1175
|
-
},
|
|
1176
|
-
],
|
|
1177
|
-
triggers: [
|
|
1178
|
-
{ type: "cli", command: "review:hooks" },
|
|
1179
|
-
{ type: "mcp", tool: "review_hooks" },
|
|
1180
|
-
],
|
|
1181
|
-
},
|
|
1182
|
-
// ── 组件重构 ──
|
|
1183
|
-
{
|
|
1184
|
-
name: "component-refactor",
|
|
1185
|
-
description: "组件重构:复杂度评估 → 拆分建议 → 安全重构",
|
|
1186
|
-
version: "2.0.0",
|
|
1187
|
-
steps: [
|
|
1188
|
-
{
|
|
1189
|
-
id: "analyze-complexity",
|
|
1190
|
-
title: "分析组件复杂度",
|
|
1191
|
-
instruction: [
|
|
1192
|
-
"## 分析组件复杂度",
|
|
1193
|
-
"",
|
|
1194
|
-
"量化评估目标组件的复杂度指标。",
|
|
1195
|
-
"",
|
|
1196
|
-
"**执行动作**:",
|
|
1197
|
-
"1. 统计组件的基础指标:",
|
|
1198
|
-
" ```bash",
|
|
1199
|
-
" # 文件行数",
|
|
1200
|
-
" wc -l <component_file>",
|
|
1201
|
-
" # Props 数量",
|
|
1202
|
-
" grep -c '^\\s*\\w*\\?:' <component_file> # 统计 interface 中的字段",
|
|
1203
|
-
" # Hooks 调用数量",
|
|
1204
|
-
" grep -c 'use[A-Z]' <component_file>",
|
|
1205
|
-
" # JSX 嵌套层级",
|
|
1206
|
-
" # 手动检查或通过缩进层级判断",
|
|
1207
|
-
" ```",
|
|
1208
|
-
"2. 统计分支复杂度:",
|
|
1209
|
-
" ```bash",
|
|
1210
|
-
" grep -c 'if\\|else\\|switch\\|case\\|?\\|&&\\|||' <component_file>",
|
|
1211
|
-
" ```",
|
|
1212
|
-
"3. 统计 useEffect 数量和处理逻辑行数",
|
|
1213
|
-
"4. 评估组件职责数量(渲染 + 数据获取 + 状态管理 + 副作用)",
|
|
1214
|
-
"",
|
|
1215
|
-
"**复杂度评级标准**:",
|
|
1216
|
-
"- **A 级(简单)**:< 100 行,< 5 个 props,< 3 个 hooks",
|
|
1217
|
-
"- **B 级(中等)**:100-300 行,5-10 个 props,3-5 个 hooks",
|
|
1218
|
-
"- **C 级(复杂)**:300-500 行,>10 个 props,>5 个 hooks",
|
|
1219
|
-
"- **D 级(巨型)**:>500 行,需要拆分",
|
|
1220
|
-
"",
|
|
1221
|
-
"**产出格式**:",
|
|
1222
|
-
"```",
|
|
1223
|
-
"file: <path>",
|
|
1224
|
-
"lines: <N>",
|
|
1225
|
-
"props_count: <N>",
|
|
1226
|
-
"hooks_count: <N>",
|
|
1227
|
-
"use_effect_count: <N>",
|
|
1228
|
-
"branch_count: <N>",
|
|
1229
|
-
"responsibilities: ['rendering', 'data-fetching', 'state-management', 'side-effects']",
|
|
1230
|
-
"complexity_grade: A|B|C|D",
|
|
1231
|
-
"refactor_needed: true|false",
|
|
1232
|
-
"```",
|
|
1233
|
-
].join("\n"),
|
|
1234
|
-
suggestedTools: ["Bash", "Read"],
|
|
1235
|
-
output: "组件复杂度指标和评级",
|
|
1236
|
-
},
|
|
1237
|
-
{
|
|
1238
|
-
id: "identify-smells",
|
|
1239
|
-
title: "识别代码异味",
|
|
1240
|
-
instruction: [
|
|
1241
|
-
"## 识别组件代码异味",
|
|
1242
|
-
"",
|
|
1243
|
-
"基于 `analyze-complexity` 的分析结果,识别代码异味。",
|
|
1244
|
-
"",
|
|
1245
|
-
"**检查项**:",
|
|
1246
|
-
"1. **巨型组件** — 单文件 >300 行,承担多个职责",
|
|
1247
|
-
"2. **重复逻辑** — 组件内有 >20 行相似的 JSX 或逻辑",
|
|
1248
|
-
" ```bash",
|
|
1249
|
-
" # 检查是否有重复的 JSX 片段",
|
|
1250
|
-
" grep -n 'className=' <component_file> | head -20",
|
|
1251
|
-
" ```",
|
|
1252
|
-
"3. **过度耦合** — 组件直接访问多个外部状态(Context、Store、API)",
|
|
1253
|
-
" ```bash",
|
|
1254
|
-
" grep -n 'useContext\\|useSelector\\|useStore\\|fetch\\|axios' <component_file>",
|
|
1255
|
-
" ```",
|
|
1256
|
-
"4. **魔法数字/字符串** — 硬编码的数值、URL、配置值",
|
|
1257
|
-
" ```bash",
|
|
1258
|
-
" grep -nE '[0-9]{2,}|\"http[s]?://' <component_file>",
|
|
1259
|
-
" ```",
|
|
1260
|
-
"5. **深层嵌套** — 条件嵌套 >3 层",
|
|
1261
|
-
"6. **超长 Props** — interface 字段 >10 个",
|
|
1262
|
-
"7. **useEffect 滥用** — 用 useEffect 替代事件处理器",
|
|
1263
|
-
"",
|
|
1264
|
-
"**产出格式**:",
|
|
1265
|
-
"```",
|
|
1266
|
-
"smells: [",
|
|
1267
|
-
" { type: 'giant-component'|'duplication'|'coupling'|'magic-number'|'deep-nesting'|'long-props'|'useeffect-abuse',",
|
|
1268
|
-
" location: '<file>:<line>', severity: 'critical'|'warning'|'info',",
|
|
1269
|
-
" description: '...' }",
|
|
1270
|
-
"]",
|
|
1271
|
-
"```",
|
|
1272
|
-
].join("\n"),
|
|
1273
|
-
suggestedTools: ["Bash", "Read"],
|
|
1274
|
-
output: "代码异味清单(按严重程度排序)",
|
|
1275
|
-
depends: ["analyze-complexity"],
|
|
1276
|
-
},
|
|
1277
|
-
{
|
|
1278
|
-
id: "propose-split",
|
|
1279
|
-
title: "生成拆分方案",
|
|
1280
|
-
instruction: [
|
|
1281
|
-
"## 生成组件拆分方案",
|
|
1282
|
-
"",
|
|
1283
|
-
"基于 `identify-smells` 的结果,设计重构方案。",
|
|
1284
|
-
"",
|
|
1285
|
-
"**拆分策略**:",
|
|
1286
|
-
"1. **提取子组件** — 将独立的 UI 片段拆分为子组件",
|
|
1287
|
-
" - 识别可独立的 JSX 块(有明确的 props 边界)",
|
|
1288
|
-
" - 子组件命名:`<Parent><Child/></Parent>`",
|
|
1289
|
-
"2. **抽取自定义 Hooks** — 将逻辑从渲染中分离",
|
|
1290
|
-
" - 数据获取逻辑 → `useXxxData`",
|
|
1291
|
-
" - 表单逻辑 → `useXxxForm`",
|
|
1292
|
-
" - UI 状态逻辑 → `useXxxUI`",
|
|
1293
|
-
"3. **提取工具函数** — 将纯计算逻辑提取到 utils",
|
|
1294
|
-
"",
|
|
1295
|
-
"**执行动作**:",
|
|
1296
|
-
"1. 用 Read 工具仔细阅读组件全文",
|
|
1297
|
-
"2. 识别逻辑边界和可拆分的代码块",
|
|
1298
|
-
"3. 设计新文件结构:",
|
|
1299
|
-
" ```bash",
|
|
1300
|
-
" # 查看当前目录结构",
|
|
1301
|
-
" ls -la <component_dir>/",
|
|
1302
|
-
" ```",
|
|
1303
|
-
"4. 设计每个子组件 / Hook 的 Props 和返回值",
|
|
1304
|
-
"",
|
|
1305
|
-
"**产出格式**:",
|
|
1306
|
-
"```",
|
|
1307
|
-
"split_plan: {",
|
|
1308
|
-
" sub_components: [{ name: 'XxxHeader', responsibility: '...', props: {...} }],",
|
|
1309
|
-
" custom_hooks: [{ name: 'useXxxData', responsibility: '...', returns: {...} }],",
|
|
1310
|
-
" utils: [{ name: 'formatXxx', responsibility: '...' }],",
|
|
1311
|
-
" new_file_structure: ['Xxx/index.tsx', 'Xxx/XxxHeader.tsx', 'Xxx/useXxxData.ts']",
|
|
1312
|
-
"}",
|
|
1313
|
-
"```",
|
|
1314
|
-
].join("\n"),
|
|
1315
|
-
suggestedTools: ["Read", "Bash"],
|
|
1316
|
-
output: "组件拆分方案(子组件、自定义 Hooks、工具函数)",
|
|
1317
|
-
depends: ["identify-smells"],
|
|
1318
|
-
},
|
|
1319
|
-
{
|
|
1320
|
-
id: "extract-hooks",
|
|
1321
|
-
title: "抽取自定义 Hooks",
|
|
1322
|
-
instruction: [
|
|
1323
|
-
"## 抽取可复用逻辑为自定义 Hooks",
|
|
1324
|
-
"",
|
|
1325
|
-
"按照 `propose-split` 的方案,将逻辑提取为自定义 Hooks。",
|
|
1326
|
-
"",
|
|
1327
|
-
"**执行动作**:",
|
|
1328
|
-
"1. 对每个计划中的自定义 Hook:",
|
|
1329
|
-
" - 创建 Hook 文件:`src/hooks/useXxx.ts` 或组件旁的 `useXxx.ts`",
|
|
1330
|
-
" - 从原组件中剪切对应逻辑",
|
|
1331
|
-
" - 使用 Edit 工具在原位置替换为 Hook 调用",
|
|
1332
|
-
"2. Hook 编写规范:",
|
|
1333
|
-
" - 以 `use` 开头命名",
|
|
1334
|
-
" - 返回值使用对象形式 `{ data, loading, error }`",
|
|
1335
|
-
" - 入参使用对象形式 `{ userId, options }`",
|
|
1336
|
-
" - 添加 TypeScript 类型定义(入参和返回值)",
|
|
1337
|
-
"3. 更新原组件的 import",
|
|
1338
|
-
"4. 确保 Hook 符合 Hooks 规则(顶层调用、不嵌套)",
|
|
1339
|
-
"",
|
|
1340
|
-
"**产出格式**:",
|
|
1341
|
-
"```",
|
|
1342
|
-
"hooks_extracted: [{ name, file_path, params: {...}, returns: {...} }]",
|
|
1343
|
-
"original_component_changes: [{ file, line_range, description }]",
|
|
1344
|
-
"```",
|
|
1345
|
-
].join("\n"),
|
|
1346
|
-
suggestedTools: ["Read", "Edit", "Write"],
|
|
1347
|
-
output: "提取的自定义 Hooks 清单",
|
|
1348
|
-
depends: ["propose-split"],
|
|
1349
|
-
},
|
|
1350
|
-
{
|
|
1351
|
-
id: "extract-components",
|
|
1352
|
-
title: "拆分子组件",
|
|
1353
|
-
instruction: [
|
|
1354
|
-
"## 拆分子组件并更新引用",
|
|
1355
|
-
"",
|
|
1356
|
-
"按照 `propose-split` 的方案,将 UI 片段拆分为子组件。",
|
|
1357
|
-
"",
|
|
1358
|
-
"**执行动作**:",
|
|
1359
|
-
"1. 对每个计划中的子组件:",
|
|
1360
|
-
" - 创建组件文件",
|
|
1361
|
-
" - 从父组件中剪切对应 JSX 和相关逻辑",
|
|
1362
|
-
" - 使用 Edit 工具在父组件中替换为子组件调用",
|
|
1363
|
-
"2. 子组件编写规范:",
|
|
1364
|
-
" - 函数组件 + Hooks",
|
|
1365
|
-
" - Props 使用 interface 定义",
|
|
1366
|
-
" - 纯展示组件用 `React.memo` 包裹",
|
|
1367
|
-
" - 导出方式:`export function XxxComponent(props: XxxProps) {}`",
|
|
1368
|
-
"3. 更新父组件的 import 和 JSX",
|
|
1369
|
-
"4. 检查子组件是否需要传递事件处理器(回调 Props)",
|
|
1370
|
-
"",
|
|
1371
|
-
"**产出格式**:",
|
|
1372
|
-
"```",
|
|
1373
|
-
"components_extracted: [{ name, file_path, props: {...}, parent: '...' }]",
|
|
1374
|
-
"parent_component_changes: [{ file, imports_updated: [...], jsx_updated: true|false }]",
|
|
1375
|
-
"```",
|
|
1376
|
-
].join("\n"),
|
|
1377
|
-
suggestedTools: ["Read", "Edit", "Write"],
|
|
1378
|
-
output: "拆分出的子组件清单和父组件变更",
|
|
1379
|
-
depends: ["propose-split"],
|
|
1380
|
-
},
|
|
1381
|
-
{
|
|
1382
|
-
id: "update-imports",
|
|
1383
|
-
title: "更新依赖引用",
|
|
1384
|
-
instruction: [
|
|
1385
|
-
"## 更新所有依赖此组件的 import 路径",
|
|
1386
|
-
"",
|
|
1387
|
-
"**执行动作**:",
|
|
1388
|
-
"1. 查找所有导入了原组件的文件:",
|
|
1389
|
-
" ```bash",
|
|
1390
|
-
" grep -rn \"from.*<original_component_path>\" src/ --include='*.tsx' --include='*.ts' --include='*.jsx' --include='*.js'",
|
|
1391
|
-
" ```",
|
|
1392
|
-
"2. 对每个引用文件:",
|
|
1393
|
-
" - 检查是否需要更新 import 路径(组件拆分后文件位置变化)",
|
|
1394
|
-
" - 检查是否需要拆分 import(原来一个组件现在变成了多个)",
|
|
1395
|
-
" - 使用 Edit 工具精准修改 import 语句",
|
|
1396
|
-
"3. 检查是否有 barrel file(index.ts)需要更新:",
|
|
1397
|
-
" ```bash",
|
|
1398
|
-
" find src/components/ -name 'index.ts' | head -10",
|
|
1399
|
-
" ```",
|
|
1400
|
-
"4. 检查 Storybook stories 是否需要更新:",
|
|
1401
|
-
" ```bash",
|
|
1402
|
-
" find . -name '*.stories.*' | head -10",
|
|
1403
|
-
" ```",
|
|
1404
|
-
"",
|
|
1405
|
-
"**产出格式**:",
|
|
1406
|
-
"```",
|
|
1407
|
-
"imports_updated: [{ file, old_import: '...', new_import: '...' }]",
|
|
1408
|
-
"barrel_files_updated: [{ path }]",
|
|
1409
|
-
"stories_updated: [{ path }]",
|
|
1410
|
-
"```",
|
|
1411
|
-
].join("\n"),
|
|
1412
|
-
suggestedTools: ["Bash", "Read", "Edit"],
|
|
1413
|
-
output: "更新的 import 清单",
|
|
1414
|
-
depends: ["extract-components"],
|
|
1415
|
-
},
|
|
1416
|
-
{
|
|
1417
|
-
id: "regression-test",
|
|
1418
|
-
title: "运行回归测试",
|
|
1419
|
-
instruction: [
|
|
1420
|
-
"## 运行回归测试确保重构后行为一致",
|
|
1421
|
-
"",
|
|
1422
|
-
"**执行动作**:",
|
|
1423
|
-
"1. 运行 TypeScript 类型检查:",
|
|
1424
|
-
" ```bash",
|
|
1425
|
-
" npx tsc --noEmit",
|
|
1426
|
-
" ```",
|
|
1427
|
-
"2. 运行与重构组件相关的测试:",
|
|
1428
|
-
" ```bash",
|
|
1429
|
-
" # 找到相关测试文件",
|
|
1430
|
-
" find src/ -name '*.test.*' -o -name '*.spec.*' | grep -i '<component_name>'",
|
|
1431
|
-
" # 运行相关测试",
|
|
1432
|
-
" npx vitest run <test_files>",
|
|
1433
|
-
" ```",
|
|
1434
|
-
"3. 运行完整测试套件确认无回归:",
|
|
1435
|
-
" ```bash",
|
|
1436
|
-
" npm test 2>&1",
|
|
1437
|
-
" ```",
|
|
1438
|
-
"4. 分析测试结果:",
|
|
1439
|
-
" - 全部通过 → ✅ 重构成功",
|
|
1440
|
-
" - 有失败 → 分析是测试需要更新还是重构引入了 Bug",
|
|
1441
|
-
"5. 如果测试失败是因为 import 路径变化,更新测试文件中的 import",
|
|
1442
|
-
"",
|
|
1443
|
-
"**产出格式**:",
|
|
1444
|
-
"```",
|
|
1445
|
-
"type_check: passed | failed",
|
|
1446
|
-
"test_result: passed | failed",
|
|
1447
|
-
"tests_run: <N>",
|
|
1448
|
-
"tests_passed: <N>",
|
|
1449
|
-
"tests_failed: <N>",
|
|
1450
|
-
"fixes_needed: [{ file, issue: '...' }]",
|
|
1451
|
-
"```",
|
|
1452
|
-
].join("\n"),
|
|
1453
|
-
suggestedTools: ["Bash", "Read", "Edit"],
|
|
1454
|
-
output: "回归测试结果",
|
|
1455
|
-
depends: ["extract-hooks", "extract-components", "update-imports"],
|
|
1456
|
-
},
|
|
1457
|
-
],
|
|
1458
|
-
triggers: [
|
|
1459
|
-
{ type: "cli", command: "refactor" },
|
|
1460
|
-
{ type: "mcp", tool: "refactor_component" },
|
|
1461
|
-
],
|
|
1462
|
-
},
|
|
1463
|
-
// ── 新建组件(增强版) ──
|
|
1464
|
-
{
|
|
1465
|
-
name: "new-component",
|
|
1466
|
-
description: "新建 React 组件(含类型、测试、样式、Storybook)",
|
|
1467
|
-
version: "2.0.0",
|
|
1468
|
-
steps: [
|
|
1469
|
-
{
|
|
1470
|
-
id: "check-existing",
|
|
1471
|
-
title: "检查可复用组件",
|
|
1472
|
-
instruction: [
|
|
1473
|
-
"## 检查是否有可复用的现有组件",
|
|
1474
|
-
"",
|
|
1475
|
-
"避免创建功能重复的组件。",
|
|
1476
|
-
"",
|
|
1477
|
-
"**执行动作**:",
|
|
1478
|
-
"1. 搜索项目中是否已有功能相似的组件:",
|
|
1479
|
-
" ```bash",
|
|
1480
|
-
" # 列出所有组件",
|
|
1481
|
-
" find src/components/ -type f -name '*.tsx' | head -50",
|
|
1482
|
-
" # 按关键词搜索(根据用户需求中的关键词)",
|
|
1483
|
-
" find src/ -type f -name '*.tsx' | xargs grep -l '<keyword>' 2>/dev/null",
|
|
1484
|
-
" ```",
|
|
1485
|
-
"2. 检查组件库(如有 UI 库如 antd / MUI):",
|
|
1486
|
-
" ```bash",
|
|
1487
|
-
" grep -rn \"from 'antd'\\|from '@mui'\" src/ --include='*.tsx' --include='*.ts' | head -10",
|
|
1488
|
-
" ```",
|
|
1489
|
-
"3. 检查是否有类似的 Storybook stories 或文档:",
|
|
1490
|
-
" ```bash",
|
|
1491
|
-
" find . -name '*.stories.*' | head -10",
|
|
1492
|
-
" ```",
|
|
1493
|
-
"4. 如果找到相似组件,评估是否可以直接复用、扩展或作为参考",
|
|
1494
|
-
"",
|
|
1495
|
-
"**产出格式**:",
|
|
1496
|
-
"```",
|
|
1497
|
-
"similar_components: [{ name, path, similarity: 'high'|'medium'|'low', reuse_approach: 'direct'|'extend'|'reference'|'create_new' }]",
|
|
1498
|
-
"ui_library_available: true|false",
|
|
1499
|
-
"decision: create_new | extend_existing",
|
|
1500
|
-
"```",
|
|
1501
|
-
].join("\n"),
|
|
1502
|
-
suggestedTools: ["Bash", "Read"],
|
|
1503
|
-
output: "可复用组件清单和复用决策",
|
|
1504
|
-
},
|
|
1505
|
-
{
|
|
1506
|
-
id: "define-props",
|
|
1507
|
-
title: "定义 Props 类型",
|
|
1508
|
-
instruction: [
|
|
1509
|
-
"## 根据需求定义 TypeScript Props interface",
|
|
1510
|
-
"",
|
|
1511
|
-
"**执行动作**:",
|
|
1512
|
-
"1. 分析组件需要的 Props:",
|
|
1513
|
-
" - 数据 Props(传入组件的内容)",
|
|
1514
|
-
" - 回调 Props(事件处理器)",
|
|
1515
|
-
" - 样式 Props(className、style)",
|
|
1516
|
-
" - 子组件 Props(children)",
|
|
1517
|
-
"2. 遵循项目约定:",
|
|
1518
|
-
" - 使用 `interface` 定义(不用 `type`)",
|
|
1519
|
-
" - 接口命名:`XxxProps`",
|
|
1520
|
-
" - 必填 Props 在前,可选 Props 在后",
|
|
1521
|
-
" - 可选 Props 使用 `?:` 标记",
|
|
1522
|
-
"3. 为每个 Prop 添加 JSDoc 注释",
|
|
1523
|
-
"4. 使用 React 内置类型:",
|
|
1524
|
-
" - `React.ReactNode` 用于 children",
|
|
1525
|
-
" - `React.CSSProperties` 用于 style",
|
|
1526
|
-
" - 事件类型:`React.MouseEventHandler<HTMLButtonElement>`",
|
|
1527
|
-
"",
|
|
1528
|
-
"**产出格式**:",
|
|
1529
|
-
"```typescript",
|
|
1530
|
-
"interface XxxProps {",
|
|
1531
|
-
" /** 数据描述 */",
|
|
1532
|
-
" data: DataType;",
|
|
1533
|
-
" /** 点击回调 */",
|
|
1534
|
-
" onClick?: () => void;",
|
|
1535
|
-
" /** 自定义类名 */",
|
|
1536
|
-
" className?: string;",
|
|
1537
|
-
"}",
|
|
1538
|
-
"```",
|
|
1539
|
-
].join("\n"),
|
|
1540
|
-
suggestedTools: ["Read", "Write"],
|
|
1541
|
-
output: "TypeScript Props interface 定义",
|
|
1542
|
-
},
|
|
1543
|
-
{
|
|
1544
|
-
id: "create-component",
|
|
1545
|
-
title: "生成组件代码",
|
|
1546
|
-
instruction: [
|
|
1547
|
-
"## 生成组件代码",
|
|
1548
|
-
"",
|
|
1549
|
-
"基于 `define-props` 的类型定义生成组件实现。",
|
|
1550
|
-
"",
|
|
1551
|
-
"**执行动作**:",
|
|
1552
|
-
"1. 创建组件文件(遵循项目目录约定):",
|
|
1553
|
-
" ```bash",
|
|
1554
|
-
" # 确认组件应该放在哪个目录",
|
|
1555
|
-
" ls -la src/components/ 2>/dev/null",
|
|
1556
|
-
" ```",
|
|
1557
|
-
"2. 组件结构模板:",
|
|
1558
|
-
" - 导入依赖",
|
|
1559
|
-
" - Props interface(如已单独定义则 import)",
|
|
1560
|
-
" - 组件函数(含默认值 / 解构)",
|
|
1561
|
-
" - 状态和副作用(Hooks)",
|
|
1562
|
-
" - 事件处理器",
|
|
1563
|
-
" - 返回 JSX",
|
|
1564
|
-
" - export",
|
|
1565
|
-
"3. 质量要求:",
|
|
1566
|
-
" - 函数组件(无 Class)",
|
|
1567
|
-
" - `React.memo` 包裹纯展示组件",
|
|
1568
|
-
" - 错误处理:loading / error / empty 状态",
|
|
1569
|
-
" - 无 `any` 类型",
|
|
1570
|
-
" - 有意义的组件命名",
|
|
1571
|
-
"4. 使用 `React.memo` + `useMemo` / `useCallback`(仅当有性能收益时)",
|
|
1572
|
-
"",
|
|
1573
|
-
"**产出格式**:",
|
|
1574
|
-
"```",
|
|
1575
|
-
"component_file: <path>",
|
|
1576
|
-
"component_name: <name>",
|
|
1577
|
-
"has_memo: true|false",
|
|
1578
|
-
"has_error_handling: true|false",
|
|
1579
|
-
"hooks_used: ['useState', 'useEffect', ...]",
|
|
1580
|
-
"```",
|
|
1581
|
-
].join("\n"),
|
|
1582
|
-
suggestedTools: ["Read", "Write", "Edit"],
|
|
1583
|
-
output: "生成的组件文件",
|
|
1584
|
-
depends: ["define-props"],
|
|
1585
|
-
},
|
|
1586
|
-
{
|
|
1587
|
-
id: "create-styles",
|
|
1588
|
-
title: "生成样式文件",
|
|
1589
|
-
instruction: [
|
|
1590
|
-
"## 生成样式文件",
|
|
1591
|
-
"",
|
|
1592
|
-
"**执行动作**:",
|
|
1593
|
-
"1. 确认项目使用的样式方案:",
|
|
1594
|
-
" ```bash",
|
|
1595
|
-
" # 检查 tailwind / CSS Modules / styled-components 等",
|
|
1596
|
-
" cat package.json | grep -i 'tailwind\\|styled-components\\|emotion'",
|
|
1597
|
-
" find src/ -name '*.module.css' | head -5",
|
|
1598
|
-
" find src/ -name '*.module.scss' | head -5",
|
|
1599
|
-
" ```",
|
|
1600
|
-
"2. 按项目约定创建样式文件:",
|
|
1601
|
-
" - **CSS Modules**:`Xxx.module.css`",
|
|
1602
|
-
" - **Tailwind**:直接使用 class 名",
|
|
1603
|
-
" - **styled-components**:在组件文件内或单独文件",
|
|
1604
|
-
"3. 样式质量要求:",
|
|
1605
|
-
" - 响应式设计(至少支持 mobile / desktop)",
|
|
1606
|
-
" - 使用 CSS 变量(如项目有设计系统)",
|
|
1607
|
-
" - 避免硬编码的颜色值",
|
|
1608
|
-
" - 命名规范:kebab-case(CSS Modules)或 camelCase(CSS-in-JS)",
|
|
1609
|
-
"4. 在组件中导入样式",
|
|
1610
|
-
"",
|
|
1611
|
-
"**产出格式**:",
|
|
1612
|
-
"```",
|
|
1613
|
-
"style_file: <path>",
|
|
1614
|
-
"style_approach: 'css-modules'|'tailwind'|'styled-components'|'inline'",
|
|
1615
|
-
"responsive: true|false",
|
|
1616
|
-
"```",
|
|
1617
|
-
].join("\n"),
|
|
1618
|
-
suggestedTools: ["Bash", "Read", "Write"],
|
|
1619
|
-
output: "生成的样式文件",
|
|
1620
|
-
depends: ["create-component"],
|
|
1621
|
-
},
|
|
1622
|
-
{
|
|
1623
|
-
id: "create-tests",
|
|
1624
|
-
title: "生成测试文件",
|
|
1625
|
-
instruction: [
|
|
1626
|
-
"## 生成组件测试文件",
|
|
1627
|
-
"",
|
|
1628
|
-
"**执行动作**:",
|
|
1629
|
-
"1. 确认项目的测试框架和约定:",
|
|
1630
|
-
" ```bash",
|
|
1631
|
-
" # 检查测试框架",
|
|
1632
|
-
" cat package.json | grep -i 'vitest\\|jest\\|testing-library'",
|
|
1633
|
-
" # 检查测试目录约定",
|
|
1634
|
-
" find src/ -type d -name '__tests__' | head -5",
|
|
1635
|
-
" find src/ -name '*.test.*' -o -name '*.spec.*' | head -5",
|
|
1636
|
-
" ```",
|
|
1637
|
-
"2. 创建测试文件(与组件同目录或 __tests__ 目录)",
|
|
1638
|
-
"3. 测试用例清单:",
|
|
1639
|
-
" - **渲染测试**:默认 Props 下组件正确渲染",
|
|
1640
|
-
" - **Props 测试**:不同 Props 组合的渲染结果",
|
|
1641
|
-
" - **交互测试**:点击、输入等用户操作",
|
|
1642
|
-
" - **边界测试**:空数据、错误状态、loading 状态",
|
|
1643
|
-
" - **快照测试**(可选):`expect(component).toMatchSnapshot()`",
|
|
1644
|
-
"4. Mock 策略:",
|
|
1645
|
-
" - API 调用使用 `vi.mock` / `jest.mock`",
|
|
1646
|
-
" - Context 使用 wrapper",
|
|
1647
|
-
" - 路由使用 `MemoryRouter`",
|
|
1648
|
-
"",
|
|
1649
|
-
"**产出格式**:",
|
|
1650
|
-
"```",
|
|
1651
|
-
"test_file: <path>",
|
|
1652
|
-
"test_count: <N>",
|
|
1653
|
-
"test_cases: [{ describe: '...', it: '...' }]",
|
|
1654
|
-
"```",
|
|
1655
|
-
].join("\n"),
|
|
1656
|
-
suggestedTools: ["Bash", "Read", "Write"],
|
|
1657
|
-
output: "生成的测试文件",
|
|
1658
|
-
depends: ["create-component"],
|
|
1659
|
-
},
|
|
1660
|
-
{ id: "type-check", stepTemplate: "type-check", depends: ["create-component", "create-styles"] },
|
|
1661
|
-
{ id: "lint-check", stepTemplate: "lint-check", depends: ["type-check"] },
|
|
1662
|
-
{ id: "run-tests", stepTemplate: "run-tests", depends: ["create-tests", "lint-check"] },
|
|
1663
|
-
],
|
|
1664
|
-
triggers: [
|
|
1665
|
-
{ type: "cli", command: "new:component" },
|
|
1666
|
-
{ type: "mcp", tool: "new_component" },
|
|
1667
|
-
],
|
|
1668
|
-
},
|
|
1669
|
-
],
|
|
1670
|
-
},
|
|
1671
|
-
prompt: {
|
|
1672
|
-
system: "你是一个 React 18 专家。使用函数组件、Hooks 和 TypeScript。遇到问题先查文档再给方案,不凭空猜测 API 行为。",
|
|
1673
|
-
rules: [
|
|
1674
|
-
"使用函数组件 + Hooks,不使用 Class 组件",
|
|
1675
|
-
"每个文件只导出一个组件",
|
|
1676
|
-
"Props 使用 TypeScript interface 定义",
|
|
1677
|
-
"使用 React.memo 优化纯展示组件",
|
|
1678
|
-
"自定义 Hooks 命名以 use 开头",
|
|
1679
|
-
"避免在渲染中创建新对象/函数(使用 useMemo / useCallback)",
|
|
1680
|
-
"遇到不确定的 API 时先查 React 官方文档再回答",
|
|
1681
|
-
"修复 Bug 前先查 git log 找最近变更",
|
|
1682
|
-
"生成代码后必须通过 TypeScript 类型检查",
|
|
1683
|
-
"不能凭记忆猜测 API 行为,必须基于当前项目版本",
|
|
1684
|
-
],
|
|
1685
|
-
},
|
|
1686
|
-
tools: [
|
|
1687
|
-
{
|
|
1688
|
-
name: 'react_review_hooks',
|
|
1689
|
-
description: '审查所有 Hooks 调用:检查顶层调用规则、依赖数组完整性、清理函数缺失、反模式',
|
|
1690
|
-
inputSchema: {
|
|
1691
|
-
type: 'object',
|
|
1692
|
-
properties: {
|
|
1693
|
-
projectRoot: { type: 'string', description: '项目根目录路径' },
|
|
1694
|
-
},
|
|
1695
|
-
required: ['projectRoot'],
|
|
1696
|
-
},
|
|
1697
|
-
handler: async (input) => {
|
|
1698
|
-
const { scanFiles } = await import('./analyzers/file-scanner.js');
|
|
1699
|
-
const { reviewHooks } = await import('./analyzers/hooks-review.js');
|
|
1700
|
-
const ctx = scanFiles(input.projectRoot, { extensions: ['.tsx', '.ts', '.jsx', '.js'] });
|
|
1701
|
-
return reviewHooks(ctx);
|
|
1702
|
-
},
|
|
1703
|
-
},
|
|
1704
|
-
{
|
|
1705
|
-
name: 'react_audit_performance',
|
|
1706
|
-
description: '性能审计:检测缺少 React.memo 的纯展示组件、内联对象创建、大列表',
|
|
1707
|
-
inputSchema: {
|
|
1708
|
-
type: 'object',
|
|
1709
|
-
properties: {
|
|
1710
|
-
projectRoot: { type: 'string', description: '项目根目录路径' },
|
|
1711
|
-
},
|
|
1712
|
-
required: ['projectRoot'],
|
|
1713
|
-
},
|
|
1714
|
-
handler: async (input) => {
|
|
1715
|
-
const { scanFiles } = await import('./analyzers/file-scanner.js');
|
|
1716
|
-
const { auditPerformance } = await import('./analyzers/performance-audit.js');
|
|
1717
|
-
const ctx = scanFiles(input.projectRoot);
|
|
1718
|
-
return auditPerformance(ctx);
|
|
1719
|
-
},
|
|
1720
|
-
},
|
|
1721
|
-
{
|
|
1722
|
-
name: 'react_refactor_component',
|
|
1723
|
-
description: '组件重构:复杂度评估、异味检测、拆分建议',
|
|
1724
|
-
inputSchema: {
|
|
1725
|
-
type: 'object',
|
|
1726
|
-
properties: {
|
|
1727
|
-
filePath: { type: 'string', description: '组件文件路径' },
|
|
1728
|
-
projectRoot: { type: 'string', description: '项目根目录路径' },
|
|
1729
|
-
},
|
|
1730
|
-
required: ['filePath', 'projectRoot'],
|
|
1731
|
-
},
|
|
1732
|
-
handler: async (input) => {
|
|
1733
|
-
const { refactorComponent } = await import('./analyzers/refactor-component.js');
|
|
1734
|
-
return refactorComponent(input.filePath, input.projectRoot);
|
|
1735
|
-
},
|
|
1736
|
-
},
|
|
1737
|
-
{
|
|
1738
|
-
name: 'react_diagnose_bug',
|
|
1739
|
-
description: 'Bug 诊断:错误分析 → 根因定位 → 修复建议',
|
|
1740
|
-
inputSchema: {
|
|
1741
|
-
type: 'object',
|
|
1742
|
-
properties: {
|
|
1743
|
-
projectRoot: { type: 'string', description: '项目根目录路径' },
|
|
1744
|
-
errorMessage: { type: 'string', description: '错误消息' },
|
|
1745
|
-
stackTrace: { type: 'string', description: '堆栈跟踪(可选)' },
|
|
1746
|
-
},
|
|
1747
|
-
required: ['projectRoot', 'errorMessage'],
|
|
1748
|
-
},
|
|
1749
|
-
handler: async (input) => {
|
|
1750
|
-
const { diagnoseBug } = await import('./analyzers/diagnose-bug.js');
|
|
1751
|
-
return diagnoseBug({
|
|
1752
|
-
projectRoot: input.projectRoot,
|
|
1753
|
-
errorMessage: input.errorMessage,
|
|
1754
|
-
stackTrace: input.stackTrace,
|
|
1755
|
-
});
|
|
1756
|
-
},
|
|
1757
|
-
},
|
|
1758
|
-
{
|
|
1759
|
-
name: 'react_new_component',
|
|
1760
|
-
description: '新建 React 组件:模式分析 → 代码生成 → 遵循项目约定',
|
|
1761
|
-
inputSchema: {
|
|
1762
|
-
type: 'object',
|
|
1763
|
-
properties: {
|
|
1764
|
-
projectRoot: { type: 'string', description: '项目根目录路径' },
|
|
1765
|
-
componentName: { type: 'string', description: '组件名称' },
|
|
1766
|
-
props: { type: 'array', items: { type: 'object', properties: { name: { type: 'string' }, type: { type: 'string' } } }, description: 'Props 列表' },
|
|
1767
|
-
},
|
|
1768
|
-
required: ['projectRoot', 'componentName'],
|
|
1769
|
-
},
|
|
1770
|
-
handler: async (input) => {
|
|
1771
|
-
const { generateComponent } = await import('./analyzers/new-component.js');
|
|
1772
|
-
return generateComponent({
|
|
1773
|
-
projectRoot: input.projectRoot,
|
|
1774
|
-
componentName: input.componentName,
|
|
1775
|
-
props: input.props ?? [],
|
|
1776
|
-
});
|
|
1777
|
-
},
|
|
1778
|
-
},
|
|
1779
|
-
],
|
|
1780
|
-
};
|
|
1781
|
-
//# sourceMappingURL=index.js.map
|