super-dev 2.0.0__py3-none-any.whl
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.
- super_dev/__init__.py +11 -0
- super_dev/analyzer/__init__.py +34 -0
- super_dev/analyzer/analyzer.py +440 -0
- super_dev/analyzer/detectors.py +511 -0
- super_dev/analyzer/models.py +285 -0
- super_dev/cli.py +3257 -0
- super_dev/config/__init__.py +11 -0
- super_dev/config/frontend.py +557 -0
- super_dev/config/manager.py +281 -0
- super_dev/creators/__init__.py +26 -0
- super_dev/creators/creator.py +134 -0
- super_dev/creators/document_generator.py +2473 -0
- super_dev/creators/frontend_builder.py +371 -0
- super_dev/creators/implementation_builder.py +789 -0
- super_dev/creators/prompt_generator.py +289 -0
- super_dev/creators/requirement_parser.py +354 -0
- super_dev/creators/spec_builder.py +195 -0
- super_dev/deployers/__init__.py +20 -0
- super_dev/deployers/cicd.py +1269 -0
- super_dev/deployers/delivery.py +229 -0
- super_dev/deployers/migration.py +1032 -0
- super_dev/design/__init__.py +74 -0
- super_dev/design/aesthetics.py +530 -0
- super_dev/design/charts.py +396 -0
- super_dev/design/codegen.py +379 -0
- super_dev/design/engine.py +528 -0
- super_dev/design/generator.py +395 -0
- super_dev/design/landing.py +422 -0
- super_dev/design/tech_stack.py +524 -0
- super_dev/design/tokens.py +269 -0
- super_dev/design/ux_guide.py +391 -0
- super_dev/exceptions.py +119 -0
- super_dev/experts/__init__.py +19 -0
- super_dev/experts/service.py +161 -0
- super_dev/integrations/__init__.py +7 -0
- super_dev/integrations/manager.py +264 -0
- super_dev/orchestrator/__init__.py +12 -0
- super_dev/orchestrator/engine.py +958 -0
- super_dev/orchestrator/experts.py +423 -0
- super_dev/orchestrator/knowledge.py +352 -0
- super_dev/orchestrator/quality.py +356 -0
- super_dev/reviewers/__init__.py +17 -0
- super_dev/reviewers/code_review.py +471 -0
- super_dev/reviewers/quality_gate.py +964 -0
- super_dev/reviewers/redteam.py +881 -0
- super_dev/skills/__init__.py +7 -0
- super_dev/skills/manager.py +307 -0
- super_dev/specs/__init__.py +44 -0
- super_dev/specs/generator.py +264 -0
- super_dev/specs/manager.py +428 -0
- super_dev/specs/models.py +348 -0
- super_dev/specs/validator.py +415 -0
- super_dev/utils/__init__.py +11 -0
- super_dev/utils/logger.py +133 -0
- super_dev/web/api.py +1402 -0
- super_dev-2.0.0.dist-info/METADATA +252 -0
- super_dev-2.0.0.dist-info/RECORD +61 -0
- super_dev-2.0.0.dist-info/WHEEL +5 -0
- super_dev-2.0.0.dist-info/entry_points.txt +2 -0
- super_dev-2.0.0.dist-info/licenses/LICENSE +21 -0
- super_dev-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
"""
|
|
2
|
+
开发:Excellent(11964948@qq.com)
|
|
3
|
+
功能:代码片段生成器
|
|
4
|
+
作用:基于设计系统生成多框架的 UI 组件代码片段
|
|
5
|
+
创建时间:2025-01-04
|
|
6
|
+
最后修改:2025-01-04
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import csv
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from enum import Enum
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
from .generator import DesignSystem
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Framework(str, Enum):
|
|
18
|
+
"""支持的框架"""
|
|
19
|
+
NEXTJS = "nextjs"
|
|
20
|
+
REACT = "react"
|
|
21
|
+
VUE = "vue"
|
|
22
|
+
SVELTE = "svelte"
|
|
23
|
+
HTML = "html"
|
|
24
|
+
TAILWIND = "tailwind"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ComponentCategory(str, Enum):
|
|
28
|
+
"""组件类别"""
|
|
29
|
+
BUTTON = "button"
|
|
30
|
+
INPUT = "input"
|
|
31
|
+
CARD = "card"
|
|
32
|
+
MODAL = "modal"
|
|
33
|
+
NAVIGATION = "navigation"
|
|
34
|
+
FORM = "form"
|
|
35
|
+
FEEDBACK = "feedback"
|
|
36
|
+
LAYOUT = "layout"
|
|
37
|
+
TYPOGRAPHY = "typography"
|
|
38
|
+
DATA_DISPLAY = "data_display"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class ComponentSnippet:
|
|
43
|
+
"""组件代码片段"""
|
|
44
|
+
name: str
|
|
45
|
+
category: ComponentCategory
|
|
46
|
+
framework: Framework
|
|
47
|
+
code: str
|
|
48
|
+
dependencies: list[str]
|
|
49
|
+
props: dict[str, str]
|
|
50
|
+
preview: str
|
|
51
|
+
description: str
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@dataclass
|
|
55
|
+
class GeneratedComponent:
|
|
56
|
+
"""生成的组件"""
|
|
57
|
+
code: str
|
|
58
|
+
imports: list[str]
|
|
59
|
+
styles: str
|
|
60
|
+
dependencies: list[str]
|
|
61
|
+
description: str
|
|
62
|
+
usage_example: str
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class CodeGenerator:
|
|
66
|
+
"""代码生成器"""
|
|
67
|
+
|
|
68
|
+
def __init__(self, data_dir: Path | None = None):
|
|
69
|
+
"""
|
|
70
|
+
初始化代码生成器
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
data_dir: 数据目录路径
|
|
74
|
+
"""
|
|
75
|
+
if data_dir is None:
|
|
76
|
+
data_dir = Path(__file__).parent.parent / "data" / "design"
|
|
77
|
+
|
|
78
|
+
self.data_dir = Path(data_dir)
|
|
79
|
+
self.snippets: list[ComponentSnippet] = []
|
|
80
|
+
self._load_snippets()
|
|
81
|
+
|
|
82
|
+
def _load_snippets(self):
|
|
83
|
+
"""加载组件片段数据"""
|
|
84
|
+
csv_path = self.data_dir / "components.csv"
|
|
85
|
+
|
|
86
|
+
if not csv_path.exists():
|
|
87
|
+
self.snippets = self._get_default_snippets()
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
with open(csv_path, encoding='utf-8') as f:
|
|
91
|
+
reader = csv.DictReader(f)
|
|
92
|
+
for row in reader:
|
|
93
|
+
try:
|
|
94
|
+
snippet = ComponentSnippet(
|
|
95
|
+
name=row["name"],
|
|
96
|
+
category=ComponentCategory(row["category"]),
|
|
97
|
+
framework=Framework(row["framework"]),
|
|
98
|
+
code=row["code"],
|
|
99
|
+
dependencies=row["dependencies"].split(";"),
|
|
100
|
+
props=self._parse_props(row["props"]),
|
|
101
|
+
preview=row.get("preview", ""),
|
|
102
|
+
description=row.get("description", "")
|
|
103
|
+
)
|
|
104
|
+
self.snippets.append(snippet)
|
|
105
|
+
except Exception as e:
|
|
106
|
+
print(f"Warning: Failed to parse snippet: {e}")
|
|
107
|
+
|
|
108
|
+
def _parse_props(self, props_str: str) -> dict[str, str]:
|
|
109
|
+
"""解析 props 字符串"""
|
|
110
|
+
props = {}
|
|
111
|
+
for item in props_str.split(";"):
|
|
112
|
+
if ":" in item:
|
|
113
|
+
key, value = item.split(":", 1)
|
|
114
|
+
props[key.strip()] = value.strip()
|
|
115
|
+
return props
|
|
116
|
+
|
|
117
|
+
def _get_default_snippets(self) -> list[ComponentSnippet]:
|
|
118
|
+
"""获取默认组件片段"""
|
|
119
|
+
return [
|
|
120
|
+
ComponentSnippet(
|
|
121
|
+
name="Button",
|
|
122
|
+
category=ComponentCategory.BUTTON,
|
|
123
|
+
framework=Framework.REACT,
|
|
124
|
+
code="import React from 'react'\n\ninterface ButtonProps {\n children: React.ReactNode\n onClick?: () => void\n variant?: 'primary' | 'secondary'\n size?: 'sm' | 'md' | 'lg'\n}\n\nexport const Button: React.FC<ButtonProps> = ({\n children,\n onClick,\n variant = 'primary',\n size = 'md'\n}) => {\n const baseStyles = 'rounded-lg font-medium transition-colors'\n const variants = {\n primary: 'bg-blue-500 hover:bg-blue-600 text-white',\n secondary: 'bg-gray-200 hover:bg-gray-300 text-gray-800'\n }\n const sizes = {\n sm: 'px-3 py-1.5 text-sm',\n md: 'px-4 py-2 text-base',\n lg: 'px-6 py-3 text-lg'\n }\n\n return (\n <button\n onClick={onClick}\n className={`${baseStyles} ${variants[variant]} ${sizes[size]}`}\n >\n {children}\n </button>\n )\n}",
|
|
125
|
+
dependencies=["react"],
|
|
126
|
+
props={"children": "React.ReactNode", "onClick": "() => void", "variant": "'primary' | 'secondary'", "size": "'sm' | 'md' | 'lg'"},
|
|
127
|
+
preview="<Button variant=\"primary\" size=\"md\">Click me</Button>",
|
|
128
|
+
description="A versatile button component with multiple variants and sizes"
|
|
129
|
+
),
|
|
130
|
+
ComponentSnippet(
|
|
131
|
+
name="Card",
|
|
132
|
+
category=ComponentCategory.CARD,
|
|
133
|
+
framework=Framework.REACT,
|
|
134
|
+
code="import React from 'react'\n\ninterface CardProps {\n children: React.ReactNode\n title?: string\n footer?: React.ReactNode\n}\n\nexport const Card: React.FC<CardProps> = ({ children, title, footer }) => {\n return (\n <div className=\"bg-white rounded-lg shadow-md overflow-hidden\">\n {title && (\n <div className=\"px-6 py-4 border-b border-gray-200\">\n <h3 className=\"text-lg font-semibold text-gray-900\">{title}</h3>\n </div>\n )}\n <div className=\"px-6 py-4\">\n {children}\n </div>\n {footer && (\n <div className=\"px-6 py-4 bg-gray-50 border-t border-gray-200\">\n {footer}\n </div>\n )}\n </div>\n )\n}",
|
|
135
|
+
dependencies=["react"],
|
|
136
|
+
props={"children": "React.ReactNode", "title": "string", "footer": "React.ReactNode"},
|
|
137
|
+
preview="<Card title=\"Card Title\">Card content</Card>",
|
|
138
|
+
description="A card component with optional header and footer"
|
|
139
|
+
),
|
|
140
|
+
ComponentSnippet(
|
|
141
|
+
name="Input",
|
|
142
|
+
category=ComponentCategory.INPUT,
|
|
143
|
+
framework=Framework.REACT,
|
|
144
|
+
code="import React from 'react'\n\ninterface InputProps {\n type?: 'text' | 'email' | 'password' | 'number'\n placeholder?: string\n value: string\n onChange: (value: string) => void\n label?: string\n error?: string\n}\n\nexport const Input: React.FC<InputProps> = ({\n type = 'text',\n placeholder,\n value,\n onChange,\n label,\n error\n}) => {\n return (\n <div className=\"w-full\">\n {label && (\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {label}\n </label>\n )}\n <input\n type={type}\n placeholder={placeholder}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n className={`w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 ${\n error\n ? 'border-red-500 focus:ring-red-500'\n : 'border-gray-300 focus:ring-blue-500'\n }`}\n />\n {error && (\n <p className=\"mt-1 text-sm text-red-600\">{error}</p>\n )}\n </div>\n )\n}",
|
|
145
|
+
dependencies=["react"],
|
|
146
|
+
props={"type": "'text' | 'email' | 'password' | 'number'", "placeholder": "string", "value": "string", "onChange": "(value: string) => void", "label": "string", "error": "string"},
|
|
147
|
+
preview="<Input label=\"Email\" value=\"\" onChange={() => {}} />",
|
|
148
|
+
description="A text input with label and error handling"
|
|
149
|
+
)
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
def search_components(
|
|
153
|
+
self,
|
|
154
|
+
query: str,
|
|
155
|
+
framework: str | None = None,
|
|
156
|
+
category: str | None = None
|
|
157
|
+
) -> list[ComponentSnippet]:
|
|
158
|
+
"""
|
|
159
|
+
搜索组件片段
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
query: 搜索查询
|
|
163
|
+
framework: 框架过滤
|
|
164
|
+
category: 类别过滤
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
组件片段列表
|
|
168
|
+
"""
|
|
169
|
+
query_lower = query.lower()
|
|
170
|
+
results = []
|
|
171
|
+
|
|
172
|
+
for snippet in self.snippets:
|
|
173
|
+
# 框架过滤
|
|
174
|
+
if framework and snippet.framework.value != framework.lower():
|
|
175
|
+
continue
|
|
176
|
+
|
|
177
|
+
# 类别过滤
|
|
178
|
+
if category and snippet.category.value != category.lower():
|
|
179
|
+
continue
|
|
180
|
+
|
|
181
|
+
# 搜索匹配
|
|
182
|
+
score = 0
|
|
183
|
+
if query_lower in snippet.name.lower():
|
|
184
|
+
score += 10
|
|
185
|
+
if query_lower in snippet.description.lower():
|
|
186
|
+
score += 5
|
|
187
|
+
if query_lower in snippet.category.value:
|
|
188
|
+
score += 3
|
|
189
|
+
|
|
190
|
+
if score > 0:
|
|
191
|
+
results.append((snippet, score))
|
|
192
|
+
|
|
193
|
+
results.sort(key=lambda x: x[1], reverse=True)
|
|
194
|
+
return [r[0] for r in results]
|
|
195
|
+
|
|
196
|
+
def generate_component(
|
|
197
|
+
self,
|
|
198
|
+
component_name: str,
|
|
199
|
+
framework: Framework,
|
|
200
|
+
design_system: DesignSystem | None = None
|
|
201
|
+
) -> GeneratedComponent | None:
|
|
202
|
+
"""
|
|
203
|
+
生成组件代码
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
component_name: 组件名称
|
|
207
|
+
framework: 目标框架
|
|
208
|
+
design_system: 设计系统(可选)
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
生成的组件
|
|
212
|
+
"""
|
|
213
|
+
# 查找组件片段
|
|
214
|
+
snippet = None
|
|
215
|
+
for s in self.snippets:
|
|
216
|
+
if s.name.lower() == component_name.lower() and s.framework == framework:
|
|
217
|
+
snippet = s
|
|
218
|
+
break
|
|
219
|
+
|
|
220
|
+
if not snippet:
|
|
221
|
+
return None
|
|
222
|
+
|
|
223
|
+
# 如果提供了设计系统,应用设计 tokens
|
|
224
|
+
code = snippet.code
|
|
225
|
+
if design_system:
|
|
226
|
+
code = self._apply_design_tokens(code, design_system, framework)
|
|
227
|
+
|
|
228
|
+
return GeneratedComponent(
|
|
229
|
+
code=code,
|
|
230
|
+
imports=self._extract_imports(code, framework),
|
|
231
|
+
styles=self._extract_styles(code, framework),
|
|
232
|
+
dependencies=snippet.dependencies,
|
|
233
|
+
description=snippet.description,
|
|
234
|
+
usage_example=snippet.preview
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
def generate_from_design_system(
|
|
238
|
+
self,
|
|
239
|
+
design_system: DesignSystem,
|
|
240
|
+
framework: Framework
|
|
241
|
+
) -> dict[str, GeneratedComponent]:
|
|
242
|
+
"""
|
|
243
|
+
从设计系统生成组件
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
design_system: 设计系统
|
|
247
|
+
framework: 目标框架
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
生成的组件字典
|
|
251
|
+
"""
|
|
252
|
+
components = {}
|
|
253
|
+
|
|
254
|
+
# 为设计系统生成核心组件
|
|
255
|
+
for category in ComponentCategory:
|
|
256
|
+
# 查找该类别的组件
|
|
257
|
+
category_snippets = [
|
|
258
|
+
s for s in self.snippets
|
|
259
|
+
if s.category == category and s.framework == framework
|
|
260
|
+
]
|
|
261
|
+
|
|
262
|
+
for snippet in category_snippets:
|
|
263
|
+
component = self.generate_component(
|
|
264
|
+
snippet.name,
|
|
265
|
+
framework,
|
|
266
|
+
design_system
|
|
267
|
+
)
|
|
268
|
+
if component:
|
|
269
|
+
components[snippet.name] = component
|
|
270
|
+
|
|
271
|
+
return components
|
|
272
|
+
|
|
273
|
+
def _apply_design_tokens(
|
|
274
|
+
self,
|
|
275
|
+
code: str,
|
|
276
|
+
design_system: DesignSystem,
|
|
277
|
+
framework: Framework
|
|
278
|
+
) -> str:
|
|
279
|
+
"""应用设计 tokens 到代码"""
|
|
280
|
+
# 提取颜色值
|
|
281
|
+
colors = design_system.colors
|
|
282
|
+
if colors:
|
|
283
|
+
# 替换颜色值
|
|
284
|
+
primary = colors.get("primary", "#000000")
|
|
285
|
+
secondary = colors.get("secondary", "#666666")
|
|
286
|
+
|
|
287
|
+
# 简化示例:实际应该更智能地替换
|
|
288
|
+
if framework == Framework.TAILWIND:
|
|
289
|
+
# 生成 Tailwind 配置建议
|
|
290
|
+
code = f"/* Apply these colors in tailwind.config.js:\n * primary: '{primary}'\n * secondary: '{secondary}'\n */\n\n{code}"
|
|
291
|
+
elif framework in [Framework.REACT, Framework.NEXTJS]:
|
|
292
|
+
# 添加 CSS 变量注释
|
|
293
|
+
code = f"/* Use these CSS variables:\n * --color-primary: {primary}\n * --color-secondary: {secondary}\n */\n\n{code}"
|
|
294
|
+
|
|
295
|
+
return code
|
|
296
|
+
|
|
297
|
+
def _extract_imports(self, code: str, framework: Framework) -> list[str]:
|
|
298
|
+
"""提取 import 语句"""
|
|
299
|
+
imports = []
|
|
300
|
+
for line in code.split('\n'):
|
|
301
|
+
if line.strip().startswith('import '):
|
|
302
|
+
imports.append(line.strip())
|
|
303
|
+
return imports
|
|
304
|
+
|
|
305
|
+
def _extract_styles(self, code: str, framework: Framework) -> str:
|
|
306
|
+
"""提取样式代码"""
|
|
307
|
+
if framework in [Framework.REACT, Framework.NEXTJS, Framework.TAILWIND]:
|
|
308
|
+
# Tailwind 类名
|
|
309
|
+
import re
|
|
310
|
+
matches = re.findall(r'className="([^"]+)"', code)
|
|
311
|
+
return "\n".join(matches)
|
|
312
|
+
return ""
|
|
313
|
+
|
|
314
|
+
def get_available_components(
|
|
315
|
+
self,
|
|
316
|
+
framework: Framework | None = None
|
|
317
|
+
) -> dict[str, list[str]]:
|
|
318
|
+
"""
|
|
319
|
+
获取可用组件列表
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
framework: 框架过滤
|
|
323
|
+
|
|
324
|
+
Returns:
|
|
325
|
+
按类别分组的组件列表
|
|
326
|
+
"""
|
|
327
|
+
components: dict[str, list[str]] = {}
|
|
328
|
+
|
|
329
|
+
for snippet in self.snippets:
|
|
330
|
+
if framework and snippet.framework != framework:
|
|
331
|
+
continue
|
|
332
|
+
|
|
333
|
+
category = snippet.category.value
|
|
334
|
+
if category not in components:
|
|
335
|
+
components[category] = []
|
|
336
|
+
|
|
337
|
+
components[category].append(snippet.name)
|
|
338
|
+
|
|
339
|
+
return components
|
|
340
|
+
|
|
341
|
+
def list_frameworks(self) -> list[str]:
|
|
342
|
+
"""列出支持的框架"""
|
|
343
|
+
return [f.value for f in Framework]
|
|
344
|
+
|
|
345
|
+
def list_categories(self) -> list[str]:
|
|
346
|
+
"""列出组件类别"""
|
|
347
|
+
return [c.value for c in ComponentCategory]
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
# 便捷函数
|
|
351
|
+
def get_code_generator(data_dir: Path | None = None) -> CodeGenerator:
|
|
352
|
+
"""获取代码生成器实例"""
|
|
353
|
+
return CodeGenerator(data_dir)
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def generate_component_snippet(
|
|
357
|
+
component_name: str,
|
|
358
|
+
framework: str = "react",
|
|
359
|
+
design_system: DesignSystem | None = None
|
|
360
|
+
) -> GeneratedComponent | None:
|
|
361
|
+
"""
|
|
362
|
+
快捷函数:生成组件片段
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
component_name: 组件名称
|
|
366
|
+
framework: 框架名称
|
|
367
|
+
design_system: 设计系统
|
|
368
|
+
|
|
369
|
+
Returns:
|
|
370
|
+
生成的组件
|
|
371
|
+
"""
|
|
372
|
+
generator = get_code_generator()
|
|
373
|
+
|
|
374
|
+
try:
|
|
375
|
+
fw_enum = Framework(framework.lower())
|
|
376
|
+
except ValueError:
|
|
377
|
+
return None
|
|
378
|
+
|
|
379
|
+
return generator.generate_component(component_name, fw_enum, design_system)
|