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,229 @@
1
+ """
2
+ 项目交付打包器
3
+
4
+ 在流水线最后阶段收敛产物,输出交付清单、报告和压缩包。
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ from dataclasses import dataclass
11
+ from datetime import datetime
12
+ from pathlib import Path
13
+ from zipfile import ZIP_DEFLATED, ZipFile
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class ArtifactSpec:
18
+ """交付物规则定义"""
19
+
20
+ path: Path
21
+ required: bool
22
+ reason: str
23
+
24
+
25
+ class DeliveryPackager:
26
+ """交付包生成器"""
27
+
28
+ def __init__(self, project_dir: Path, name: str, version: str = "2.0.0"):
29
+ self.project_dir = Path(project_dir).resolve()
30
+ self.name = name
31
+ self.version = version
32
+
33
+ def package(self, cicd_platform: str = "all") -> dict[str, object]:
34
+ """生成交付清单、报告和压缩包"""
35
+ output_dir = self.project_dir / "output" / "delivery"
36
+ output_dir.mkdir(parents=True, exist_ok=True)
37
+
38
+ specs = self._artifact_specs(cicd_platform=cicd_platform)
39
+ included_files: list[str] = []
40
+ missing_required: list[dict[str, str]] = []
41
+
42
+ for spec in specs:
43
+ if spec.path.exists():
44
+ included_files.append(self._relative(spec.path))
45
+ elif spec.required:
46
+ missing_required.append(
47
+ {
48
+ "path": self._relative(spec.path),
49
+ "reason": spec.reason,
50
+ }
51
+ )
52
+
53
+ migration_files = self._collect_migration_files()
54
+ if migration_files:
55
+ included_files.extend(self._relative(path) for path in migration_files)
56
+ else:
57
+ missing_required.append(
58
+ {
59
+ "path": "migrations/*",
60
+ "reason": "缺少数据库迁移脚本(至少应生成一种 ORM 迁移文件)",
61
+ }
62
+ )
63
+
64
+ included_files = sorted(set(included_files))
65
+ status = "ready" if not missing_required else "incomplete"
66
+
67
+ manifest: dict[str, object] = {
68
+ "project_name": self.name,
69
+ "version": self.version,
70
+ "generated_at": datetime.now().isoformat(timespec="seconds"),
71
+ "status": status,
72
+ "cicd_platform": cicd_platform,
73
+ "included_files": included_files,
74
+ "missing_required": missing_required,
75
+ "summary": {
76
+ "included_count": len(included_files),
77
+ "missing_required_count": len(missing_required),
78
+ },
79
+ }
80
+
81
+ manifest_file = output_dir / f"{self.name}-delivery-manifest.json"
82
+ manifest_file.write_text(
83
+ json.dumps(manifest, ensure_ascii=False, indent=2),
84
+ encoding="utf-8",
85
+ )
86
+
87
+ report_file = output_dir / f"{self.name}-delivery-report.md"
88
+ report_file.write_text(self._to_markdown(manifest), encoding="utf-8")
89
+
90
+ archive_file = output_dir / f"{self.name}-delivery-v{self.version}.zip"
91
+ self._build_archive(
92
+ archive_path=archive_file,
93
+ included_files=included_files,
94
+ extra_files=[manifest_file, report_file],
95
+ )
96
+
97
+ return {
98
+ "status": status,
99
+ "manifest_file": str(manifest_file),
100
+ "report_file": str(report_file),
101
+ "archive_file": str(archive_file),
102
+ "included_count": len(included_files),
103
+ "missing_required_count": len(missing_required),
104
+ "missing_required": missing_required,
105
+ }
106
+
107
+ def _artifact_specs(self, cicd_platform: str) -> list[ArtifactSpec]:
108
+ output_dir = self.project_dir / "output"
109
+ specs = [
110
+ ArtifactSpec(output_dir / f"{self.name}-research.md", True, "缺少需求增强报告"),
111
+ ArtifactSpec(output_dir / f"{self.name}-prd.md", True, "缺少 PRD"),
112
+ ArtifactSpec(output_dir / f"{self.name}-architecture.md", True, "缺少架构文档"),
113
+ ArtifactSpec(output_dir / f"{self.name}-uiux.md", True, "缺少 UI/UX 文档"),
114
+ ArtifactSpec(output_dir / f"{self.name}-execution-plan.md", True, "缺少执行路线图"),
115
+ ArtifactSpec(output_dir / f"{self.name}-frontend-blueprint.md", True, "缺少前端蓝图"),
116
+ ArtifactSpec(output_dir / f"{self.name}-redteam.md", True, "缺少红队报告"),
117
+ ArtifactSpec(output_dir / f"{self.name}-quality-gate.md", True, "缺少质量门禁报告"),
118
+ ArtifactSpec(output_dir / f"{self.name}-code-review.md", True, "缺少代码审查指南"),
119
+ ArtifactSpec(output_dir / f"{self.name}-ai-prompt.md", True, "缺少 AI 提示词"),
120
+ ArtifactSpec(output_dir / "frontend" / "index.html", True, "缺少前端演示页面"),
121
+ ArtifactSpec(output_dir / "frontend" / "styles.css", True, "缺少前端演示样式"),
122
+ ArtifactSpec(output_dir / "frontend" / "app.js", True, "缺少前端演示脚本"),
123
+ ArtifactSpec(self.project_dir / "backend" / "API_CONTRACT.md", True, "缺少 API 契约"),
124
+ ArtifactSpec(self.project_dir / ".env.deploy.example", True, "缺少部署环境模板"),
125
+ ArtifactSpec(
126
+ self.project_dir / "output" / "deploy" / "all-secrets-checklist.md",
127
+ True,
128
+ "缺少部署 Secrets 检查清单",
129
+ ),
130
+ ]
131
+ specs.extend(self._cicd_specs(cicd_platform=cicd_platform))
132
+ return specs
133
+
134
+ def _cicd_specs(self, cicd_platform: str) -> list[ArtifactSpec]:
135
+ mapping: dict[str, list[str]] = {
136
+ "github": [".github/workflows/ci.yml", ".github/workflows/cd.yml"],
137
+ "gitlab": [".gitlab-ci.yml"],
138
+ "jenkins": ["Jenkinsfile"],
139
+ "azure": [".azure-pipelines.yml"],
140
+ "bitbucket": ["bitbucket-pipelines.yml"],
141
+ "all": [
142
+ ".github/workflows/ci.yml",
143
+ ".github/workflows/cd.yml",
144
+ ".gitlab-ci.yml",
145
+ "Jenkinsfile",
146
+ ".azure-pipelines.yml",
147
+ "bitbucket-pipelines.yml",
148
+ ],
149
+ }
150
+ files = mapping.get(cicd_platform, mapping["github"])
151
+ return [
152
+ ArtifactSpec(self.project_dir / relative, True, f"缺少 CI/CD 文件: {relative}")
153
+ for relative in files
154
+ ]
155
+
156
+ def _collect_migration_files(self) -> list[Path]:
157
+ patterns = [
158
+ "prisma/migrations/**/*.sql",
159
+ "alembic/versions/*.py",
160
+ "backend/migrations/**/*.sql",
161
+ "backend/migrations/**/*.py",
162
+ "migrations/**/*.sql",
163
+ "src/main/resources/db/migration/*.sql",
164
+ ]
165
+ files: list[Path] = []
166
+ for pattern in patterns:
167
+ files.extend(self.project_dir.glob(pattern))
168
+ return sorted(path for path in files if path.is_file())
169
+
170
+ def _build_archive(
171
+ self,
172
+ archive_path: Path,
173
+ included_files: list[str],
174
+ extra_files: list[Path],
175
+ ) -> None:
176
+ with ZipFile(archive_path, mode="w", compression=ZIP_DEFLATED) as archive:
177
+ for relative in included_files:
178
+ file_path = self.project_dir / relative
179
+ if file_path.exists():
180
+ archive.write(file_path, arcname=relative)
181
+ for file_path in extra_files:
182
+ if file_path.exists():
183
+ arcname = self._relative(file_path)
184
+ archive.write(file_path, arcname=arcname)
185
+
186
+ def _to_markdown(self, manifest: dict[str, object]) -> str:
187
+ status = str(manifest.get("status", "incomplete"))
188
+ status_text = "可交付" if status == "ready" else "未完成"
189
+ included = manifest.get("included_files", [])
190
+ missing = manifest.get("missing_required", [])
191
+ cicd_platform = manifest.get("cicd_platform", "all")
192
+
193
+ lines = [
194
+ "# 交付报告",
195
+ "",
196
+ f"- 项目: {manifest.get('project_name', self.name)}",
197
+ f"- 版本: {manifest.get('version', self.version)}",
198
+ f"- 状态: {status_text} ({status})",
199
+ f"- CI/CD 平台: {cicd_platform}",
200
+ f"- 生成时间: {manifest.get('generated_at', '')}",
201
+ "",
202
+ "## 已包含文件",
203
+ "",
204
+ ]
205
+
206
+ if isinstance(included, list) and included:
207
+ for item in included:
208
+ lines.append(f"- {item}")
209
+ else:
210
+ lines.append("- (none)")
211
+ lines.append("")
212
+
213
+ lines.extend(["## 缺失必需项", ""])
214
+ if isinstance(missing, list) and missing:
215
+ for item in missing:
216
+ if isinstance(item, dict):
217
+ lines.append(
218
+ f"- {item.get('path', 'unknown')}: {item.get('reason', '')}"
219
+ )
220
+ else:
221
+ lines.append("- 无")
222
+ lines.append("")
223
+ return "\n".join(lines)
224
+
225
+ def _relative(self, path: Path) -> str:
226
+ try:
227
+ return str(path.relative_to(self.project_dir))
228
+ except ValueError:
229
+ return str(path)