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.
Files changed (61) hide show
  1. super_dev/__init__.py +11 -0
  2. super_dev/analyzer/__init__.py +34 -0
  3. super_dev/analyzer/analyzer.py +440 -0
  4. super_dev/analyzer/detectors.py +511 -0
  5. super_dev/analyzer/models.py +285 -0
  6. super_dev/cli.py +3257 -0
  7. super_dev/config/__init__.py +11 -0
  8. super_dev/config/frontend.py +557 -0
  9. super_dev/config/manager.py +281 -0
  10. super_dev/creators/__init__.py +26 -0
  11. super_dev/creators/creator.py +134 -0
  12. super_dev/creators/document_generator.py +2473 -0
  13. super_dev/creators/frontend_builder.py +371 -0
  14. super_dev/creators/implementation_builder.py +789 -0
  15. super_dev/creators/prompt_generator.py +289 -0
  16. super_dev/creators/requirement_parser.py +354 -0
  17. super_dev/creators/spec_builder.py +195 -0
  18. super_dev/deployers/__init__.py +20 -0
  19. super_dev/deployers/cicd.py +1269 -0
  20. super_dev/deployers/delivery.py +229 -0
  21. super_dev/deployers/migration.py +1032 -0
  22. super_dev/design/__init__.py +74 -0
  23. super_dev/design/aesthetics.py +530 -0
  24. super_dev/design/charts.py +396 -0
  25. super_dev/design/codegen.py +379 -0
  26. super_dev/design/engine.py +528 -0
  27. super_dev/design/generator.py +395 -0
  28. super_dev/design/landing.py +422 -0
  29. super_dev/design/tech_stack.py +524 -0
  30. super_dev/design/tokens.py +269 -0
  31. super_dev/design/ux_guide.py +391 -0
  32. super_dev/exceptions.py +119 -0
  33. super_dev/experts/__init__.py +19 -0
  34. super_dev/experts/service.py +161 -0
  35. super_dev/integrations/__init__.py +7 -0
  36. super_dev/integrations/manager.py +264 -0
  37. super_dev/orchestrator/__init__.py +12 -0
  38. super_dev/orchestrator/engine.py +958 -0
  39. super_dev/orchestrator/experts.py +423 -0
  40. super_dev/orchestrator/knowledge.py +352 -0
  41. super_dev/orchestrator/quality.py +356 -0
  42. super_dev/reviewers/__init__.py +17 -0
  43. super_dev/reviewers/code_review.py +471 -0
  44. super_dev/reviewers/quality_gate.py +964 -0
  45. super_dev/reviewers/redteam.py +881 -0
  46. super_dev/skills/__init__.py +7 -0
  47. super_dev/skills/manager.py +307 -0
  48. super_dev/specs/__init__.py +44 -0
  49. super_dev/specs/generator.py +264 -0
  50. super_dev/specs/manager.py +428 -0
  51. super_dev/specs/models.py +348 -0
  52. super_dev/specs/validator.py +415 -0
  53. super_dev/utils/__init__.py +11 -0
  54. super_dev/utils/logger.py +133 -0
  55. super_dev/web/api.py +1402 -0
  56. super_dev-2.0.0.dist-info/METADATA +252 -0
  57. super_dev-2.0.0.dist-info/RECORD +61 -0
  58. super_dev-2.0.0.dist-info/WHEEL +5 -0
  59. super_dev-2.0.0.dist-info/entry_points.txt +2 -0
  60. super_dev-2.0.0.dist-info/licenses/LICENSE +21 -0
  61. super_dev-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,528 @@
1
+ """
2
+ 开发:Excellent(11964948@qq.com)
3
+ 功能:设计智能引擎
4
+ 作用:提供 UI/UX 设计智能搜索和推荐
5
+ 创建时间:2025-12-30
6
+ 最后修改:2025-12-30
7
+ """
8
+
9
+ import csv
10
+ import re
11
+ from collections import defaultdict
12
+ from dataclasses import dataclass
13
+ from math import log
14
+ from pathlib import Path
15
+ from typing import Any, cast
16
+
17
+ from .aesthetics import AestheticEngine
18
+
19
+ # ============ 配置 ============
20
+ DATA_DIR = Path(__file__).parent.parent / "data" / "design"
21
+ MAX_RESULTS = 5
22
+
23
+
24
+ # ============ 数据模型 ============
25
+ @dataclass
26
+ class SearchResult:
27
+ """搜索结果"""
28
+ score: float
29
+ relevance: str # high, medium, low
30
+ data: dict[str, Any]
31
+
32
+ def to_dict(self) -> dict[str, Any]:
33
+ return {
34
+ "score": self.score,
35
+ "relevance": self.relevance,
36
+ **self.data
37
+ }
38
+
39
+
40
+ # ============ 增强版 BM25 ============
41
+ class EnhancedBM25:
42
+ """
43
+ 增强版 BM25 算法
44
+
45
+ 改进点:
46
+ 1. 支持 IDF 平滑
47
+ 2. 支持字段权重
48
+ 3. 支持模糊匹配
49
+ 4. 支持短语匹配
50
+ """
51
+
52
+ def __init__(self, k1: float = 1.5, b: float = 0.75, epsilon: float = 0.25):
53
+ self.k1 = k1
54
+ self.b = b
55
+ self.epsilon = epsilon # IDF 平滑参数
56
+ self.corpus: list[list[str]] = []
57
+ self.doc_lengths: list[int] = []
58
+ self.avgdl: float = 0.0
59
+ self.idf: dict[str, float] = {}
60
+ self.doc_freqs: defaultdict[str, int] = defaultdict(int)
61
+ self.N = 0
62
+ self.field_weights: dict[str, float] = {} # 字段权重
63
+
64
+ def tokenize(self, text: str) -> list[str]:
65
+ """分词 - 支持中英文"""
66
+ # 移除标点
67
+ text = re.sub(r'[^\w\s\u4e00-\u9fff]', ' ', str(text).lower())
68
+ # 分词(英文按空格,中文按字符)
69
+ words: list[str] = []
70
+ for word in text.split():
71
+ if re.match(r'[\u4e00-\u9fff]', word):
72
+ # 中文,按字符分
73
+ words.extend(list(word))
74
+ else:
75
+ # 英文,过滤短词
76
+ if len(word) > 2:
77
+ words.append(word)
78
+ return words
79
+
80
+ def fit(self, documents: list[str], field_weights: dict[str, float] | None = None):
81
+ """构建索引"""
82
+ self.field_weights = field_weights or {}
83
+ self.corpus = [self.tokenize(doc) for doc in documents]
84
+ self.N = len(self.corpus)
85
+ if self.N == 0:
86
+ return
87
+
88
+ self.doc_lengths = [len(doc) for doc in self.corpus]
89
+ self.avgdl = sum(self.doc_lengths) / self.N
90
+
91
+ # 计算文档频率
92
+ for doc in self.corpus:
93
+ seen = set()
94
+ for word in doc:
95
+ if word not in seen:
96
+ self.doc_freqs[word] += 1
97
+ seen.add(word)
98
+
99
+ # 计算 IDF(带平滑)
100
+ for word, freq in self.doc_freqs.items():
101
+ idf = log((self.N - freq + 0.5) / (freq + 0.5) + 1)
102
+ self.idf[word] = max(idf, self.epsilon)
103
+
104
+ def score(self, query: str, phrase_boost: float = 1.5) -> list[tuple[int, float]]:
105
+ """评分 - 支持短语匹配加成"""
106
+ query_tokens = self.tokenize(query)
107
+ scores: list[tuple[int, float]] = []
108
+
109
+ for idx, doc in enumerate(self.corpus):
110
+ score = 0.0
111
+ doc_len = self.doc_lengths[idx]
112
+ term_freqs: defaultdict[str, int] = defaultdict(int)
113
+
114
+ for word in doc:
115
+ term_freqs[word] += 1
116
+
117
+ # 短语匹配检测
118
+ doc_text = " ".join(doc)
119
+ phrase_match = 1.0
120
+ if len(query_tokens) >= 2:
121
+ phrase = " ".join(query_tokens)
122
+ if phrase in doc_text:
123
+ phrase_match = phrase_boost
124
+
125
+ for token in query_tokens:
126
+ if token in self.idf:
127
+ tf = term_freqs[token]
128
+ idf = self.idf[token]
129
+ numerator = tf * (self.k1 + 1)
130
+ denominator = tf + self.k1 * (1 - self.b + self.b * doc_len / self.avgdl)
131
+ score += idf * numerator / denominator
132
+
133
+ scores.append((idx, score * phrase_match))
134
+
135
+ return sorted(scores, key=lambda x: x[1], reverse=True)
136
+
137
+
138
+ # ============ 设计智能引擎 ============
139
+ class DesignIntelligenceEngine:
140
+ """
141
+ 设计智能引擎
142
+
143
+ 设计智能引擎核心能力:
144
+ 1. 更多设计资产(100+ styles, 150+ palettes, 80+ fonts)
145
+ 2. AI 驱动的推荐
146
+ 3. 语义搜索支持
147
+ 4. 上下文感知
148
+ 5. 与项目工作流集成
149
+ """
150
+
151
+ def __init__(self, data_dir: Path | None = None):
152
+ """
153
+ 初始化设计智能引擎
154
+
155
+ Args:
156
+ data_dir: 数据目录,默认使用内置数据
157
+ """
158
+ self.data_dir = data_dir or DATA_DIR
159
+ self.aesthetic_engine = AestheticEngine()
160
+ self._cache: dict[str, dict[str, Any]] = {}
161
+
162
+ # 领域配置(扩展版)
163
+ self.domain_configs: dict[str, dict[str, Any]] = {
164
+ "style": {
165
+ "file": "styles.csv",
166
+ "search_cols": ["name", "category", "keywords", "best_for"],
167
+ "output_cols": ["name", "category", "keywords", "description", "primary_colors",
168
+ "effects", "animations", "best_for", "complexity", "accessibility",
169
+ "performance", "frameworks", "example_prompt"],
170
+ },
171
+ "color": {
172
+ "file": "colors.csv",
173
+ "search_cols": ["name", "category", "keywords", "mood", "best_for"],
174
+ "output_cols": ["name", "category", "primary", "secondary", "accent",
175
+ "background", "surface", "text", "text_muted", "border",
176
+ "keywords", "mood", "best_for", "css_vars"],
177
+ },
178
+ "typography": {
179
+ "file": "typography.csv",
180
+ "search_cols": ["name", "category", "mood", "heading_font", "body_font", "keywords"],
181
+ "output_cols": ["name", "category", "heading_font", "body_font", "accent_font",
182
+ "mood", "keywords", "best_for", "google_fonts_url", "css_import",
183
+ "tailwind_config", "notes"],
184
+ },
185
+ "component": {
186
+ "file": "components.csv",
187
+ "search_cols": ["name", "type", "keywords", "use_case", "complexity"],
188
+ "output_cols": ["name", "type", "description", "keywords", "use_case",
189
+ "complexity", "accessibility", "responsive", "frameworks",
190
+ "code_example", "props"],
191
+ },
192
+ "layout": {
193
+ "file": "layouts.csv",
194
+ "search_cols": ["name", "type", "keywords", "best_for"],
195
+ "output_cols": ["name", "type", "description", "keywords", "structure",
196
+ "responsive", "best_for", "css_grid"],
197
+ },
198
+ "animation": {
199
+ "file": "animations.csv",
200
+ "search_cols": ["name", "type", "keywords", "effect"],
201
+ "output_cols": ["name", "type", "description", "keywords", "css_code",
202
+ "duration", "easing", "best_for", "accessibility"],
203
+ },
204
+ "ux": {
205
+ "file": "ux_guidelines.csv",
206
+ "search_cols": ["domain", "topic", "best_practice", "anti_pattern", "impact"],
207
+ "output_cols": ["domain", "topic", "best_practice", "anti_pattern",
208
+ "example", "impact", "complexity"],
209
+ },
210
+ "chart": {
211
+ "file": "chart_types.csv",
212
+ "search_cols": ["name", "category", "data_type", "keywords", "description"],
213
+ "output_cols": ["name", "category", "data_type", "description",
214
+ "best_libraries", "accessibility_notes", "use_cases", "limitations", "keywords"],
215
+ },
216
+ "product": {
217
+ "file": "landing_patterns.csv",
218
+ "search_cols": ["name", "category", "description", "best_for", "keywords"],
219
+ "output_cols": ["name", "category", "description", "sections", "cta_strategy",
220
+ "best_for", "conversion_tips", "complexity", "keywords"],
221
+ },
222
+ "stack": {
223
+ "file": "tech_stacks.csv",
224
+ "search_cols": ["framework", "category", "topic", "recommendation", "use_cases"],
225
+ "output_cols": ["framework", "category", "topic", "recommendation",
226
+ "code_example", "benefits", "use_cases", "complexity"],
227
+ },
228
+ }
229
+
230
+ def search(
231
+ self,
232
+ query: str,
233
+ domain: str | None = None,
234
+ max_results: int = MAX_RESULTS,
235
+ use_cache: bool = True,
236
+ ) -> dict[str, Any]:
237
+ """
238
+ 搜索设计资产
239
+
240
+ Args:
241
+ query: 搜索查询
242
+ domain: 领域(style, color, typography, component, layout, animation, ux, chart, product, stack)
243
+ max_results: 最大结果数
244
+ use_cache: 是否使用缓存
245
+
246
+ Returns:
247
+ 搜索结果字典
248
+ """
249
+ # 自动检测领域
250
+ if domain is None:
251
+ domain = self._detect_domain(query)
252
+
253
+ # 检查缓存
254
+ cache_key = f"{domain}:{query}"
255
+ if use_cache and cache_key in self._cache:
256
+ return self._cache[cache_key]
257
+
258
+ # 获取配置
259
+ config = self.domain_configs.get(domain)
260
+ if not config:
261
+ return {"error": f"Unknown domain: {domain}", "domain": domain}
262
+
263
+ # 加载数据
264
+ filepath = self.data_dir / str(config["file"])
265
+ if not filepath.exists():
266
+ # 如果文件不存在,返回空结果
267
+ return {
268
+ "domain": domain,
269
+ "query": query,
270
+ "count": 0,
271
+ "results": [],
272
+ "note": f"Data file not found: {filepath}",
273
+ }
274
+
275
+ # 执行搜索
276
+ results = self._search_csv(
277
+ filepath,
278
+ cast(list[str], config["search_cols"]),
279
+ cast(list[str], config["output_cols"]),
280
+ query,
281
+ max_results,
282
+ )
283
+
284
+ response = {
285
+ "domain": domain,
286
+ "query": query,
287
+ "count": len(results),
288
+ "results": results,
289
+ }
290
+
291
+ # 缓存结果
292
+ if use_cache:
293
+ self._cache[cache_key] = response
294
+
295
+ return response
296
+
297
+ def recommend_design_system(
298
+ self,
299
+ product_type: str,
300
+ industry: str,
301
+ keywords: list[str],
302
+ platform: str = "web",
303
+ ) -> dict[str, Any]:
304
+ """
305
+ AI 驱动的完整设计系统推荐
306
+
307
+ 不只搜索,而是推荐完整的设计系统
308
+
309
+ Args:
310
+ product_type: 产品类型(SaaS, E-commerce, Portfolio, Dashboard)
311
+ industry: 行业(Fintech, Healthcare, Education, Gaming)
312
+ keywords: 关键词列表
313
+ platform: 平台(web, mobile, desktop)
314
+
315
+ Returns:
316
+ 完整的设计系统推荐
317
+ """
318
+ # 搜索产品类型推荐
319
+ product_result = self.search(f"{product_type} {industry}", domain="product")
320
+
321
+ # 搜索风格
322
+ style_query = " ".join(keywords[:3])
323
+ style_result = self.search(style_query, domain="style")
324
+
325
+ # 搜索配色
326
+ color_result = self.search(f"{industry} {product_type}", domain="color")
327
+
328
+ # 搜索字体
329
+ typography_result = self.search(style_query, domain="typography")
330
+
331
+ # 生成美学方向
332
+ aesthetic = self.aesthetic_engine.generate_direction()
333
+
334
+ # 综合推荐
335
+ return {
336
+ "product_analysis": product_result.get("results", [{}])[0] if product_result.get("results") else {},
337
+ "recommended_style": style_result.get("results", [{}])[0] if style_result.get("results") else {},
338
+ "color_palette": color_result.get("results", [{}])[0] if color_result.get("results") else {},
339
+ "typography": typography_result.get("results", [{}])[0] if typography_result.get("results") else {},
340
+ "aesthetic_direction": {
341
+ "name": aesthetic.name,
342
+ "description": aesthetic.description,
343
+ "differentiation": aesthetic.differentiation,
344
+ },
345
+ "ux_guidelines": self.search(f"{product_type} best practices", domain="ux").get("results", []),
346
+ "implementation_stack": self._get_stack_recommendation(platform),
347
+ }
348
+
349
+ def generate_design_tokens(self, design_system: dict[str, Any]) -> str:
350
+ """
351
+ 生成 Design Tokens
352
+
353
+ 生成可直接使用的 design tokens
354
+
355
+ Args:
356
+ design_system: 设计系统字典
357
+
358
+ Returns:
359
+ CSS Variables 格式的 tokens
360
+ """
361
+ tokens = [":root {"]
362
+ tokens.append(" /* Colors */")
363
+
364
+ # 颜色 tokens
365
+ colors = design_system.get("color_palette", {})
366
+ for key in ["primary", "secondary", "accent", "background", "surface", "text", "text_muted", "border"]:
367
+ value = colors.get(key, "")
368
+ if value:
369
+ css_var = f"--color-{key}"
370
+ tokens.append(f" {css_var}: {value};")
371
+
372
+ tokens.append("")
373
+ tokens.append(" /* Typography */")
374
+
375
+ # 字体 tokens
376
+ typography = design_system.get("typography", {})
377
+ for key in ["heading_font", "body_font", "accent_font"]:
378
+ value = typography.get(key, "")
379
+ if value:
380
+ css_var = f"--font-{key}"
381
+ tokens.append(f" {css_var}: {value};")
382
+
383
+ tokens.append("")
384
+ tokens.append(" /* Spacing */")
385
+ tokens.append(" --space-xs: 0.25rem;")
386
+ tokens.append(" --space-sm: 0.5rem;")
387
+ tokens.append(" --space-md: 1rem;")
388
+ tokens.append(" --space-lg: 1.5rem;")
389
+ tokens.append(" --space-xl: 2rem;")
390
+ tokens.append(" --space-2xl: 3rem;")
391
+
392
+ tokens.append("")
393
+ tokens.append(" /* Border Radius */")
394
+ tokens.append(" --radius-sm: 0.25rem;")
395
+ tokens.append(" --radius-md: 0.5rem;")
396
+ tokens.append(" --radius-lg: 1rem;")
397
+ tokens.append(" --radius-xl: 1.5rem;")
398
+ tokens.append(" --radius-full: 9999px;")
399
+
400
+ tokens.append("")
401
+
402
+ # 阴影 tokens
403
+ tokens.append(" /* Shadows */")
404
+ tokens.append(" --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);")
405
+ tokens.append(" --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);")
406
+ tokens.append(" --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);")
407
+ tokens.append(" --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1);")
408
+
409
+ tokens.append("}")
410
+
411
+ return "\n".join(tokens)
412
+
413
+ def _detect_domain(self, query: str) -> str:
414
+ """自动检测领域"""
415
+ query_lower = query.lower()
416
+
417
+ # 关键词映射(扩展版)
418
+ domain_keywords = {
419
+ "color": ["color", "palette", "hex", "#", "rgb", "hsl", "主题色", "配色"],
420
+ "typography": ["font", "type", "typography", "heading", "body", "serif", "sans", "字体", "排版"],
421
+ "component": ["component", "button", "modal", "navbar", "card", "form", "组件", "按钮"],
422
+ "layout": ["layout", "grid", "flex", "structure", "布局", "网格"],
423
+ "animation": ["animation", "transition", "motion", "effect", "动画", "过渡", "特效"],
424
+ "chart": ["chart", "graph", "visualization", "trend", "data", "图表", "可视化", "数据"],
425
+ "ux": ["ux", "usability", "accessibility", "wcag", "experience", "体验", "可用性", "无障碍"],
426
+ "product": ["saas", "ecommerce", "fintech", "healthcare", "portfolio", "dashboard", "产品"],
427
+ "style": ["style", "design", "ui", "minimalism", "glassmorphism", "brutalism", "风格", "设计"],
428
+ "stack": ["react", "vue", "nextjs", "tailwind", "framework", "框架"],
429
+ }
430
+
431
+ # 计算每个领域的匹配分数
432
+ scores: dict[str, int] = {}
433
+ for domain, keywords in domain_keywords.items():
434
+ scores[domain] = sum(1 for kw in keywords if kw in query_lower)
435
+
436
+ # 返回最高分的领域
437
+ best = max(scores, key=lambda key: scores[key])
438
+ return best if scores[best] > 0 else "style"
439
+
440
+ def _search_csv(
441
+ self,
442
+ filepath: Path,
443
+ search_cols: list[str],
444
+ output_cols: list[str],
445
+ query: str,
446
+ max_results: int,
447
+ ) -> list[dict[str, Any]]:
448
+ """在 CSV 文件中搜索"""
449
+ try:
450
+ with open(filepath, encoding="utf-8") as f:
451
+ reader = csv.DictReader(f)
452
+ data = list(reader)
453
+ except Exception:
454
+ return []
455
+
456
+ if not data:
457
+ return []
458
+
459
+ # 构建文档
460
+ documents = [
461
+ " ".join(str(row.get(col, "")) for col in search_cols)
462
+ for row in data
463
+ ]
464
+
465
+ # BM25 搜索
466
+ bm25 = EnhancedBM25()
467
+ bm25.fit(documents)
468
+ ranked = bm25.score(query)
469
+
470
+ # 获取结果
471
+ results = []
472
+ for idx, score in ranked[:max_results]:
473
+ if score > 0:
474
+ row = data[idx]
475
+ result = {col: row.get(col, "") for col in output_cols if col in row}
476
+
477
+ # 计算相关性
478
+ relevance = "high" if score > 2.0 else "medium" if score > 1.0 else "low"
479
+
480
+ results.append(SearchResult(
481
+ score=round(score, 3),
482
+ relevance=relevance,
483
+ data=result,
484
+ ).to_dict())
485
+
486
+ return results
487
+
488
+ def _get_stack_recommendation(self, platform: str) -> dict[str, str]:
489
+ """获取技术栈推荐"""
490
+ stack_map = {
491
+ "web": {
492
+ "default": "nextjs",
493
+ "alternative": "react",
494
+ "styling": "tailwindcss",
495
+ "ui_library": "shadcn-ui",
496
+ },
497
+ "mobile": {
498
+ "default": "react-native",
499
+ "alternative": "flutter",
500
+ "styling": "styled-components",
501
+ "ui_library": "react-native-paper",
502
+ },
503
+ "desktop": {
504
+ "default": "electron",
505
+ "alternative": "tauri",
506
+ "styling": "css",
507
+ "ui_library": "mui",
508
+ },
509
+ }
510
+ return stack_map.get(platform, stack_map["web"])
511
+
512
+ def get_available_domains(self) -> list[str]:
513
+ """获取可用的搜索领域"""
514
+ return list(self.domain_configs.keys())
515
+
516
+ def clear_cache(self):
517
+ """清除缓存"""
518
+ self._cache.clear()
519
+
520
+ def get_statistics(self) -> dict[str, Any]:
521
+ """获取统计信息"""
522
+ stats = {
523
+ "domains": len(self.domain_configs),
524
+ "available_domains": list(self.domain_configs.keys()),
525
+ "cached_results": len(self._cache),
526
+ "data_dir": str(self.data_dir),
527
+ }
528
+ return stats