super-dev 2.1.1__tar.gz → 2.1.3__tar.gz
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-2.1.1/super_dev.egg-info → super_dev-2.1.3}/PKG-INFO +56 -6
- {super_dev-2.1.1 → super_dev-2.1.3}/README.md +55 -5
- {super_dev-2.1.1 → super_dev-2.1.3}/pyproject.toml +1 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/__init__.py +1 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/dependency_graph.py +11 -4
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/detectors.py +30 -19
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/feature_checklist.py +0 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/catalogs.py +3 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/cli.py +35 -17
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/config/manager.py +5 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/document_generator.py +23 -20
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/frontend_builder.py +4 -2
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/implementation_builder.py +2 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/prompt_generator.py +13 -11
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/spec_builder.py +6 -6
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/delivery.py +1 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/migration.py +8 -12
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/charts.py +3 -2
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/codegen.py +2 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/generator.py +8 -2
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/landing.py +2 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/tech_stack.py +4 -3
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/tokens.py +8 -5
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/ux_guide.py +2 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/integrations/manager.py +47 -2
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/engine.py +15 -14
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/experts.py +1 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/knowledge.py +20 -20
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/quality.py +7 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/reviewers/quality_gate.py +8 -5
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/reviewers/redteam.py +2 -2
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/reviewers/ui_review.py +9 -5
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/skills/manager.py +1 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/specs/generator.py +4 -3
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/specs/manager.py +9 -5
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/specs/models.py +9 -5
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/specs/validator.py +6 -4
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/terminal.py +32 -3
- {super_dev-2.1.1 → super_dev-2.1.3/super_dev.egg-info}/PKG-INFO +56 -6
- {super_dev-2.1.1 → super_dev-2.1.3}/LICENSE +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/setup.cfg +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/analyzer.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/impact.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/models.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/regression_guard.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/repo_map.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/config/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/config/frontend.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/creator.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/requirement_parser.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/task_executor.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/cicd.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/rehearsal.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/rehearsal_runner.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/aesthetics.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/engine.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/ui_intelligence.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/exceptions.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/experts/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/experts/service.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/integrations/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/contracts.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/telemetry.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/policy/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/policy/manager.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/proof_pack.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/release_readiness.py +1 -1
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/review_state.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/reviewers/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/reviewers/code_review.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/skills/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/specs/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/utils/__init__.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/utils/logger.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/web/api.py +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev.egg-info/SOURCES.txt +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev.egg-info/dependency_links.txt +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev.egg-info/entry_points.txt +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev.egg-info/requires.txt +0 -0
- {super_dev-2.1.1 → super_dev-2.1.3}/super_dev.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: super-dev
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.3
|
|
4
4
|
Summary: Super Dev - Pipeline AI Coding Assistant
|
|
5
5
|
Author-email: Excellent <11964948@qq.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -60,7 +60,7 @@ Dynamic: license-file
|
|
|
60
60
|
|
|
61
61
|
## 版本
|
|
62
62
|
|
|
63
|
-
当前版本:`2.1.
|
|
63
|
+
当前版本:`2.1.3`
|
|
64
64
|
|
|
65
65
|
---
|
|
66
66
|
|
|
@@ -345,13 +345,13 @@ super-dev
|
|
|
345
345
|
### 3. 指定版本安装
|
|
346
346
|
|
|
347
347
|
```bash
|
|
348
|
-
pip install super-dev==2.1.
|
|
348
|
+
pip install super-dev==2.1.3
|
|
349
349
|
```
|
|
350
350
|
|
|
351
351
|
### 4. GitHub 指定标签安装
|
|
352
352
|
|
|
353
353
|
```bash
|
|
354
|
-
pip install git+https://github.com/shangyankeji/super-dev.git@v2.1.
|
|
354
|
+
pip install git+https://github.com/shangyankeji/super-dev.git@v2.1.3
|
|
355
355
|
```
|
|
356
356
|
|
|
357
357
|
### 5. 源码开发安装
|
|
@@ -479,9 +479,9 @@ super-dev bootstrap --name my-project --platform web --frontend next --backend n
|
|
|
479
479
|
|
|
480
480
|
---
|
|
481
481
|
|
|
482
|
-
##
|
|
482
|
+
## 21 宿主支持
|
|
483
483
|
|
|
484
|
-
### CLI 宿主(
|
|
484
|
+
### CLI 宿主(10 个)
|
|
485
485
|
|
|
486
486
|
| 宿主 | 触发方式 | 安装命令 |
|
|
487
487
|
|------|----------|----------|
|
|
@@ -489,6 +489,7 @@ super-dev bootstrap --name my-project --platform web --frontend next --backend n
|
|
|
489
489
|
| Codex CLI | `super-dev: 需求` | `super-dev onboard --host codex-cli` |
|
|
490
490
|
| Gemini CLI | `/super-dev 需求` | `super-dev onboard --host gemini-cli` |
|
|
491
491
|
| OpenCode | `/super-dev 需求` | `super-dev onboard --host opencode` |
|
|
492
|
+
| OpenClaw | `/super-dev 需求` | `openclaw plugins install @super-dev/openclaw-plugin` |
|
|
492
493
|
| Kiro CLI | `/super-dev 需求` | `super-dev onboard --host kiro-cli` |
|
|
493
494
|
| Cursor CLI | `/super-dev 需求` | `super-dev onboard --host cursor-cli` |
|
|
494
495
|
| Qoder CLI | `/super-dev 需求` | `super-dev onboard --host qoder-cli` |
|
|
@@ -948,6 +949,55 @@ super-dev: 你的需求
|
|
|
948
949
|
3. 建议先用 `super-dev doctor --host cline` 做一次确认。
|
|
949
950
|
4. 在同一个 Agent Chat 会话里完成整条流水线效果最佳。
|
|
950
951
|
|
|
952
|
+
#### 21. OpenClaw (原生插件)
|
|
953
|
+
|
|
954
|
+
OpenClaw 通过原生 Plugin SDK 集成,无需 `super-dev onboard`,直接安装 npm 插件即可。
|
|
955
|
+
|
|
956
|
+
安装:
|
|
957
|
+
```bash
|
|
958
|
+
# 第一步:安装 super-dev CLI
|
|
959
|
+
pip install super-dev
|
|
960
|
+
|
|
961
|
+
# 第二步:安装 OpenClaw 插件
|
|
962
|
+
openclaw plugins install @super-dev/openclaw-plugin
|
|
963
|
+
```
|
|
964
|
+
|
|
965
|
+
触发位置:
|
|
966
|
+
在 OpenClaw Agent 对话面板中,确保当前工作区为目标项目后触发。
|
|
967
|
+
|
|
968
|
+
触发命令:
|
|
969
|
+
```text
|
|
970
|
+
super-dev: 你的需求
|
|
971
|
+
```
|
|
972
|
+
或
|
|
973
|
+
```text
|
|
974
|
+
/super-dev 你的需求
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
插件提供 13 个专用 Tool:
|
|
978
|
+
|
|
979
|
+
| Tool | 功能 |
|
|
980
|
+
|------|------|
|
|
981
|
+
| `super_dev_pipeline` | 启动完整流水线 |
|
|
982
|
+
| `super_dev_init` | 项目初始化 |
|
|
983
|
+
| `super_dev_status` | 查看流水线状态 |
|
|
984
|
+
| `super_dev_quality` | 质量检查(按类型) |
|
|
985
|
+
| `super_dev_spec` | Spec 管理(propose/list/show/scaffold/validate) |
|
|
986
|
+
| `super_dev_config` | 配置管理(list/get/set) |
|
|
987
|
+
| `super_dev_review` | 审查与门禁确认(docs/ui/architecture/quality) |
|
|
988
|
+
| `super_dev_release` | 发布就绪度 / 交付证明包 |
|
|
989
|
+
| `super_dev_expert` | 专家咨询 (10 角色) |
|
|
990
|
+
| `super_dev_deploy` | CI/CD 配置 / Dockerfile / 发布演练 |
|
|
991
|
+
| `super_dev_analyze` | 项目分析(技术栈/依赖/结构) |
|
|
992
|
+
| `super_dev_doctor` | 环境诊断 |
|
|
993
|
+
| `super_dev_run` | 通用命令透传(可选) |
|
|
994
|
+
|
|
995
|
+
补充说明:
|
|
996
|
+
1. 插件通过 CLI subprocess 桥接调用 `super-dev`,因此必须先 `pip install super-dev`。
|
|
997
|
+
2. 安装后建议重启 OpenClaw Gateway 或新开会话,让 Plugin 和 Skill 生效。
|
|
998
|
+
3. 插件内嵌 SKILL.md,OpenClaw Agent 会自动理解流水线协议。
|
|
999
|
+
4. 使用 `super-dev doctor --host openclaw` 检查集成状态。
|
|
1000
|
+
|
|
951
1001
|
---
|
|
952
1002
|
|
|
953
1003
|
## 关键文档
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
## 版本
|
|
21
21
|
|
|
22
|
-
当前版本:`2.1.
|
|
22
|
+
当前版本:`2.1.3`
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
@@ -304,13 +304,13 @@ super-dev
|
|
|
304
304
|
### 3. 指定版本安装
|
|
305
305
|
|
|
306
306
|
```bash
|
|
307
|
-
pip install super-dev==2.1.
|
|
307
|
+
pip install super-dev==2.1.3
|
|
308
308
|
```
|
|
309
309
|
|
|
310
310
|
### 4. GitHub 指定标签安装
|
|
311
311
|
|
|
312
312
|
```bash
|
|
313
|
-
pip install git+https://github.com/shangyankeji/super-dev.git@v2.1.
|
|
313
|
+
pip install git+https://github.com/shangyankeji/super-dev.git@v2.1.3
|
|
314
314
|
```
|
|
315
315
|
|
|
316
316
|
### 5. 源码开发安装
|
|
@@ -438,9 +438,9 @@ super-dev bootstrap --name my-project --platform web --frontend next --backend n
|
|
|
438
438
|
|
|
439
439
|
---
|
|
440
440
|
|
|
441
|
-
##
|
|
441
|
+
## 21 宿主支持
|
|
442
442
|
|
|
443
|
-
### CLI 宿主(
|
|
443
|
+
### CLI 宿主(10 个)
|
|
444
444
|
|
|
445
445
|
| 宿主 | 触发方式 | 安装命令 |
|
|
446
446
|
|------|----------|----------|
|
|
@@ -448,6 +448,7 @@ super-dev bootstrap --name my-project --platform web --frontend next --backend n
|
|
|
448
448
|
| Codex CLI | `super-dev: 需求` | `super-dev onboard --host codex-cli` |
|
|
449
449
|
| Gemini CLI | `/super-dev 需求` | `super-dev onboard --host gemini-cli` |
|
|
450
450
|
| OpenCode | `/super-dev 需求` | `super-dev onboard --host opencode` |
|
|
451
|
+
| OpenClaw | `/super-dev 需求` | `openclaw plugins install @super-dev/openclaw-plugin` |
|
|
451
452
|
| Kiro CLI | `/super-dev 需求` | `super-dev onboard --host kiro-cli` |
|
|
452
453
|
| Cursor CLI | `/super-dev 需求` | `super-dev onboard --host cursor-cli` |
|
|
453
454
|
| Qoder CLI | `/super-dev 需求` | `super-dev onboard --host qoder-cli` |
|
|
@@ -907,6 +908,55 @@ super-dev: 你的需求
|
|
|
907
908
|
3. 建议先用 `super-dev doctor --host cline` 做一次确认。
|
|
908
909
|
4. 在同一个 Agent Chat 会话里完成整条流水线效果最佳。
|
|
909
910
|
|
|
911
|
+
#### 21. OpenClaw (原生插件)
|
|
912
|
+
|
|
913
|
+
OpenClaw 通过原生 Plugin SDK 集成,无需 `super-dev onboard`,直接安装 npm 插件即可。
|
|
914
|
+
|
|
915
|
+
安装:
|
|
916
|
+
```bash
|
|
917
|
+
# 第一步:安装 super-dev CLI
|
|
918
|
+
pip install super-dev
|
|
919
|
+
|
|
920
|
+
# 第二步:安装 OpenClaw 插件
|
|
921
|
+
openclaw plugins install @super-dev/openclaw-plugin
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
触发位置:
|
|
925
|
+
在 OpenClaw Agent 对话面板中,确保当前工作区为目标项目后触发。
|
|
926
|
+
|
|
927
|
+
触发命令:
|
|
928
|
+
```text
|
|
929
|
+
super-dev: 你的需求
|
|
930
|
+
```
|
|
931
|
+
或
|
|
932
|
+
```text
|
|
933
|
+
/super-dev 你的需求
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
插件提供 13 个专用 Tool:
|
|
937
|
+
|
|
938
|
+
| Tool | 功能 |
|
|
939
|
+
|------|------|
|
|
940
|
+
| `super_dev_pipeline` | 启动完整流水线 |
|
|
941
|
+
| `super_dev_init` | 项目初始化 |
|
|
942
|
+
| `super_dev_status` | 查看流水线状态 |
|
|
943
|
+
| `super_dev_quality` | 质量检查(按类型) |
|
|
944
|
+
| `super_dev_spec` | Spec 管理(propose/list/show/scaffold/validate) |
|
|
945
|
+
| `super_dev_config` | 配置管理(list/get/set) |
|
|
946
|
+
| `super_dev_review` | 审查与门禁确认(docs/ui/architecture/quality) |
|
|
947
|
+
| `super_dev_release` | 发布就绪度 / 交付证明包 |
|
|
948
|
+
| `super_dev_expert` | 专家咨询 (10 角色) |
|
|
949
|
+
| `super_dev_deploy` | CI/CD 配置 / Dockerfile / 发布演练 |
|
|
950
|
+
| `super_dev_analyze` | 项目分析(技术栈/依赖/结构) |
|
|
951
|
+
| `super_dev_doctor` | 环境诊断 |
|
|
952
|
+
| `super_dev_run` | 通用命令透传(可选) |
|
|
953
|
+
|
|
954
|
+
补充说明:
|
|
955
|
+
1. 插件通过 CLI subprocess 桥接调用 `super-dev`,因此必须先 `pip install super-dev`。
|
|
956
|
+
2. 安装后建议重启 OpenClaw Gateway 或新开会话,让 Plugin 和 Skill 生效。
|
|
957
|
+
3. 插件内嵌 SKILL.md,OpenClaw Agent 会自动理解流水线协议。
|
|
958
|
+
4. 使用 `super-dev doctor --host openclaw` 检查集成状态。
|
|
959
|
+
|
|
910
960
|
---
|
|
911
961
|
|
|
912
962
|
## 关键文档
|
|
@@ -128,8 +128,9 @@ class DependencyGraphBuilder:
|
|
|
128
128
|
module_index = self._build_module_index(files)
|
|
129
129
|
edges = self._build_edges(files, module_index, path_index)
|
|
130
130
|
inbound, outbound = self._degree(edges)
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
repo_map = self.repo_map_builder.build()
|
|
132
|
+
critical_nodes = self._critical_nodes(path_index, inbound, outbound, repo_map=repo_map)
|
|
133
|
+
critical_paths = self._critical_paths(edges, critical_nodes, repo_map=repo_map)
|
|
133
134
|
|
|
134
135
|
summary = (
|
|
135
136
|
f"The dependency graph highlights `{len(path_index)}` source nodes and `{len(edges)}` internal import edges. "
|
|
@@ -298,8 +299,11 @@ class DependencyGraphBuilder:
|
|
|
298
299
|
path_index: dict[str, Path],
|
|
299
300
|
inbound: dict[str, int],
|
|
300
301
|
outbound: dict[str, int],
|
|
302
|
+
repo_map: object | None = None,
|
|
301
303
|
) -> list[DependencyNode]:
|
|
302
|
-
|
|
304
|
+
if repo_map is None:
|
|
305
|
+
repo_map = self.repo_map_builder.build()
|
|
306
|
+
entry_paths = {item.path for item in repo_map.entry_points}
|
|
303
307
|
nodes: list[DependencyNode] = []
|
|
304
308
|
for rel in path_index:
|
|
305
309
|
in_count = inbound.get(rel, 0)
|
|
@@ -317,11 +321,14 @@ class DependencyGraphBuilder:
|
|
|
317
321
|
self,
|
|
318
322
|
edges: list[DependencyEdge],
|
|
319
323
|
critical_nodes: list[DependencyNode],
|
|
324
|
+
repo_map: object | None = None,
|
|
320
325
|
) -> list[CriticalPath]:
|
|
321
326
|
adjacency: dict[str, list[str]] = defaultdict(list)
|
|
322
327
|
for edge in edges:
|
|
323
328
|
adjacency[edge.source].append(edge.target)
|
|
324
|
-
|
|
329
|
+
if repo_map is None:
|
|
330
|
+
repo_map = self.repo_map_builder.build()
|
|
331
|
+
entry_points = [item.path for item in repo_map.entry_points]
|
|
325
332
|
targets = [item.path for item in critical_nodes[:5] if item.role != "entry-point"]
|
|
326
333
|
paths: list[CriticalPath] = []
|
|
327
334
|
for entry in entry_points[:5]:
|
|
@@ -74,18 +74,7 @@ def detect_project_type(project_path: Path) -> ProjectCategory:
|
|
|
74
74
|
if (project_path / "android").exists() or (project_path / "ios").exists():
|
|
75
75
|
return ProjectCategory.MOBILE
|
|
76
76
|
|
|
77
|
-
#
|
|
78
|
-
if package_json.exists():
|
|
79
|
-
try:
|
|
80
|
-
with open(package_json, encoding="utf-8") as f:
|
|
81
|
-
data = json.load(f)
|
|
82
|
-
deps = data.get("dependencies", {})
|
|
83
|
-
dev_deps = data.get("devDependencies", {})
|
|
84
|
-
|
|
85
|
-
if "electron" in deps or "electron" in dev_deps:
|
|
86
|
-
return ProjectCategory.DESKTOP
|
|
87
|
-
except (OSError, json.JSONDecodeError):
|
|
88
|
-
pass
|
|
77
|
+
# Electron 检测已移入 _detect_node_project_type
|
|
89
78
|
|
|
90
79
|
return ProjectCategory.UNKNOWN
|
|
91
80
|
|
|
@@ -102,6 +91,10 @@ def _detect_node_project_type(project_path: Path) -> ProjectCategory:
|
|
|
102
91
|
|
|
103
92
|
all_deps = {**deps, **dev_deps}
|
|
104
93
|
|
|
94
|
+
# 检测 Electron 桌面应用
|
|
95
|
+
if "electron" in all_deps:
|
|
96
|
+
return ProjectCategory.DESKTOP
|
|
97
|
+
|
|
105
98
|
# 检测前端框架
|
|
106
99
|
frontend_frameworks = [
|
|
107
100
|
"react", "react-dom", "vue", "vue-router", "@angular/core",
|
|
@@ -354,33 +347,51 @@ def _detect_node_tech_stack(project_path: Path, category: ProjectCategory) -> Te
|
|
|
354
347
|
def _detect_python_tech_stack(project_path: Path, category: ProjectCategory) -> TechStack:
|
|
355
348
|
"""检测 Python 技术栈"""
|
|
356
349
|
requirements_txt = project_path / "requirements.txt"
|
|
350
|
+
pyproject_toml = project_path / "pyproject.toml"
|
|
357
351
|
|
|
358
352
|
dependencies = []
|
|
359
353
|
framework = FrameworkType.UNKNOWN
|
|
360
354
|
testing_framework = ""
|
|
361
355
|
|
|
362
|
-
#
|
|
356
|
+
# 解析 requirements.txt
|
|
363
357
|
if requirements_txt.exists():
|
|
364
358
|
try:
|
|
365
359
|
with open(requirements_txt, encoding="utf-8") as f:
|
|
366
360
|
for line in f:
|
|
367
361
|
line = line.strip()
|
|
368
362
|
if line and not line.startswith("#"):
|
|
369
|
-
# 解析 requirement
|
|
370
363
|
match = re.match(r"^([a-zA-Z0-9_-]+)([>=<~]+(.+))?", line)
|
|
371
364
|
if match:
|
|
372
365
|
name = match.group(1)
|
|
373
366
|
version = match.group(3) or ""
|
|
374
367
|
dependencies.append(
|
|
375
|
-
Dependency(
|
|
376
|
-
name=name,
|
|
377
|
-
version=version,
|
|
378
|
-
type="prod",
|
|
379
|
-
)
|
|
368
|
+
Dependency(name=name, version=version, type="prod")
|
|
380
369
|
)
|
|
381
370
|
except OSError:
|
|
382
371
|
pass
|
|
383
372
|
|
|
373
|
+
# 解析 pyproject.toml 依赖(补充 requirements.txt 未覆盖的情况)
|
|
374
|
+
if pyproject_toml.exists() and not dependencies:
|
|
375
|
+
try:
|
|
376
|
+
content = pyproject_toml.read_text(encoding="utf-8", errors="ignore")
|
|
377
|
+
in_deps = False
|
|
378
|
+
for line in content.split("\n"):
|
|
379
|
+
stripped = line.strip()
|
|
380
|
+
if stripped in ("[project.dependencies]", "dependencies = ["):
|
|
381
|
+
in_deps = True
|
|
382
|
+
continue
|
|
383
|
+
if in_deps:
|
|
384
|
+
if stripped.startswith("[") or stripped == "]":
|
|
385
|
+
in_deps = False
|
|
386
|
+
continue
|
|
387
|
+
dep_match = re.match(r'"?([a-zA-Z0-9_-]+)', stripped)
|
|
388
|
+
if dep_match:
|
|
389
|
+
dependencies.append(
|
|
390
|
+
Dependency(name=dep_match.group(1), version="", type="prod")
|
|
391
|
+
)
|
|
392
|
+
except OSError:
|
|
393
|
+
pass
|
|
394
|
+
|
|
384
395
|
# 检测框架
|
|
385
396
|
dep_names = {d.name.lower() for d in dependencies}
|
|
386
397
|
|
|
@@ -153,6 +153,7 @@ HOST_TOOL_CATALOG: list[dict[str, str]] = [
|
|
|
153
153
|
{"id": "kiro", "name": "Kiro"},
|
|
154
154
|
{"id": "qoder", "name": "Qoder"},
|
|
155
155
|
{"id": "trae", "name": "Trae"},
|
|
156
|
+
{"id": "openclaw", "name": "OpenClaw"},
|
|
156
157
|
]
|
|
157
158
|
|
|
158
159
|
HOST_TOOL_IDS: tuple[str, ...] = tuple(item["id"] for item in HOST_TOOL_CATALOG)
|
|
@@ -196,6 +197,7 @@ CLI_HOST_TOOL_IDS: tuple[str, ...] = (
|
|
|
196
197
|
"iflow",
|
|
197
198
|
"kimi-cli",
|
|
198
199
|
"kiro-cli",
|
|
200
|
+
"openclaw",
|
|
199
201
|
"opencode",
|
|
200
202
|
"qoder-cli",
|
|
201
203
|
)
|
|
@@ -225,6 +227,7 @@ HOST_COMMAND_CANDIDATES: dict[str, list[str]] = {
|
|
|
225
227
|
"qoder-cli": ["qoder", "qoder-cli"],
|
|
226
228
|
"roo-code": ["roo", "roo-code"],
|
|
227
229
|
"cursor": ["cursor"],
|
|
230
|
+
"openclaw": ["openclaw", "openclaw-cli"],
|
|
228
231
|
"qoder": ["qoder"],
|
|
229
232
|
"trae": ["trae"],
|
|
230
233
|
}
|
|
@@ -97,7 +97,7 @@ class SuperDevCLI:
|
|
|
97
97
|
"""Super Dev 命令行接口"""
|
|
98
98
|
|
|
99
99
|
def __init__(self):
|
|
100
|
-
self.console = create_console()
|
|
100
|
+
self.console = create_console()
|
|
101
101
|
self.parser = self._create_parser()
|
|
102
102
|
self.logger = get_logger('cli', level='WARNING') # CLI只记录WARNING及以上级别
|
|
103
103
|
|
|
@@ -3398,16 +3398,19 @@ super-dev start --idea "你的需求"
|
|
|
3398
3398
|
}
|
|
3399
3399
|
expert_role, expert_title = expert_map.get(normalized, ("CODE", "代码专家"))
|
|
3400
3400
|
|
|
3401
|
-
from rich.panel import Panel
|
|
3402
3401
|
self.console.print("")
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3402
|
+
if RICH_AVAILABLE:
|
|
3403
|
+
from rich.panel import Panel
|
|
3404
|
+
self.console.print(Panel(
|
|
3405
|
+
f"[bold cyan]Super Dev Run[/bold cyan]\n\n"
|
|
3406
|
+
f" [dim]环节[/dim] {normalized} ({label})\n"
|
|
3407
|
+
f" [dim]专家[/dim] [bold]{expert_role}[/bold] - {expert_title}",
|
|
3408
|
+
border_style="cyan",
|
|
3409
|
+
expand=True,
|
|
3410
|
+
padding=(1, 2),
|
|
3410
3411
|
))
|
|
3412
|
+
else:
|
|
3413
|
+
self.console.print(f"Super Dev Run: {normalized} ({label}) | {expert_role} - {expert_title}")
|
|
3411
3414
|
self.console.print("")
|
|
3412
3415
|
|
|
3413
3416
|
if normalized in {"research", "prd", "architecture", "uiux"}:
|
|
@@ -3602,7 +3605,7 @@ super-dev start --idea "你的需求"
|
|
|
3602
3605
|
+ (", ".join(payload["skipped_gates"]) if payload["skipped_gates"] else "-")
|
|
3603
3606
|
)
|
|
3604
3607
|
scope_rate = payload["scope_coverage_rate"]
|
|
3605
|
-
scope_rate_text = f"{float(scope_rate):.1f}%" if isinstance(scope_rate,
|
|
3608
|
+
scope_rate_text = f"{float(scope_rate):.1f}%" if isinstance(scope_rate, int | float) else "-"
|
|
3606
3609
|
self.console.print(f" 范围覆盖状态: {payload['scope_coverage_status']}")
|
|
3607
3610
|
self.console.print(f" 范围覆盖率: {scope_rate_text}")
|
|
3608
3611
|
self.console.print(f" 范围缺口: {payload['scope_gap_count']}")
|
|
@@ -5361,6 +5364,16 @@ super-dev start --idea "你的需求"
|
|
|
5361
5364
|
knowledge_cache_exists=knowledge_cache_file.exists(),
|
|
5362
5365
|
)
|
|
5363
5366
|
|
|
5367
|
+
# 初始化 resume 跳过时可能未赋值的变量
|
|
5368
|
+
knowledge_bundle: dict | None = None
|
|
5369
|
+
cicd_files: dict[str, str] = {}
|
|
5370
|
+
remediation_outputs: dict = {"env_file": "", "checklist_file": "", "items_count": 0}
|
|
5371
|
+
migration_files: dict[str, str] = {}
|
|
5372
|
+
delivery_outputs: dict = {
|
|
5373
|
+
"manifest_file": "", "report_file": "", "archive_file": "", "status": "skipped",
|
|
5374
|
+
}
|
|
5375
|
+
task_execution_summary = None
|
|
5376
|
+
|
|
5364
5377
|
# ========== 第 0 阶段: 需求增强 ==========
|
|
5365
5378
|
_start_stage("0", "需求增强")
|
|
5366
5379
|
if _should_skip_for_resume(0):
|
|
@@ -6329,9 +6342,13 @@ super-dev start --idea "你的需求"
|
|
|
6329
6342
|
self.console.print(" - backend/src/*")
|
|
6330
6343
|
self.console.print(" - backend/API_CONTRACT.md")
|
|
6331
6344
|
self.console.print(" - backend/migrations/*.sql")
|
|
6332
|
-
if task_execution_summary is not None:
|
|
6345
|
+
if task_execution_summary is not None and task_execution_summary.report_file:
|
|
6346
|
+
try:
|
|
6347
|
+
rel = Path(str(task_execution_summary.report_file)).relative_to(project_dir)
|
|
6348
|
+
except ValueError:
|
|
6349
|
+
rel = Path(str(task_execution_summary.report_file)).name
|
|
6333
6350
|
self.console.print(
|
|
6334
|
-
f" - {
|
|
6351
|
+
f" - {rel}"
|
|
6335
6352
|
)
|
|
6336
6353
|
self.console.print("")
|
|
6337
6354
|
self.console.print(" CI/CD:")
|
|
@@ -8705,9 +8722,9 @@ super-dev start --idea "你的需求"
|
|
|
8705
8722
|
|
|
8706
8723
|
status = "[green]已就绪[/green]" if host["ready"] else "[red]未安装[/red]"
|
|
8707
8724
|
|
|
8708
|
-
integrate_ok = host.get("
|
|
8709
|
-
skill_ok = host.get("
|
|
8710
|
-
slash_ok = host.get("
|
|
8725
|
+
integrate_ok = bool(host.get("checks", {}).get("integrate", {}).get("ok", True))
|
|
8726
|
+
skill_ok = bool(host.get("checks", {}).get("skill", {}).get("ok", True))
|
|
8727
|
+
slash_ok = bool(host.get("checks", {}).get("slash", {}).get("ok", True))
|
|
8711
8728
|
|
|
8712
8729
|
integrate_text = "[green]已安装[/green]" if integrate_ok else "[red]未安装[/red]"
|
|
8713
8730
|
skill_text = "[green]已安装[/green]" if skill_ok else ("[dim]不适用[/dim]" if not IntegrationManager.requires_skill(target) else "[red]未安装[/red]")
|
|
@@ -9119,10 +9136,10 @@ super-dev start --idea "你的需求"
|
|
|
9119
9136
|
|
|
9120
9137
|
def _fetch_latest_pypi_version(self) -> str | None:
|
|
9121
9138
|
try:
|
|
9122
|
-
response = requests.get("https://pypi.org/pypi/super-dev/json", timeout=10)
|
|
9139
|
+
response = requests.get("https://pypi.org/pypi/super-dev/json", timeout=10) # type: ignore[name-defined]
|
|
9123
9140
|
response.raise_for_status()
|
|
9124
9141
|
payload = response.json()
|
|
9125
|
-
except Exception:
|
|
9142
|
+
except (Exception, NameError):
|
|
9126
9143
|
return None
|
|
9127
9144
|
info = payload.get("info", {})
|
|
9128
9145
|
version = info.get("version")
|
|
@@ -11326,6 +11343,7 @@ super-dev start --idea "你的需求"
|
|
|
11326
11343
|
domain=domain,
|
|
11327
11344
|
name=direct_overrides.get("name"),
|
|
11328
11345
|
cicd=cicd,
|
|
11346
|
+
mode=direct_overrides.get("mode", "feature"),
|
|
11329
11347
|
skip_redteam=bool(direct_overrides.get("skip_redteam", False)),
|
|
11330
11348
|
skip_scaffold=bool(direct_overrides.get("skip_scaffold", False)),
|
|
11331
11349
|
skip_quality_gate=bool(direct_overrides.get("skip_quality_gate", False)),
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
最后修改:2025-12-30
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
import dataclasses
|
|
9
10
|
from dataclasses import dataclass, field
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
from typing import Any, cast
|
|
@@ -142,6 +143,10 @@ class ConfigManager:
|
|
|
142
143
|
# 合并默认配置
|
|
143
144
|
config_data: dict[str, Any] = {**self.DEFAULT_CONFIG, **data}
|
|
144
145
|
|
|
146
|
+
# 过滤掉 ProjectConfig 不支持的字段,避免 TypeError
|
|
147
|
+
valid_fields = {f.name for f in dataclasses.fields(ProjectConfig)}
|
|
148
|
+
config_data = {k: v for k, v in config_data.items() if k in valid_fields}
|
|
149
|
+
|
|
145
150
|
return ProjectConfig(**cast(dict[str, Any], config_data))
|
|
146
151
|
|
|
147
152
|
def save(self, config: ProjectConfig | None = None) -> None:
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
最后修改:2025-01-04
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
+
import logging
|
|
11
12
|
from datetime import datetime
|
|
12
13
|
|
|
13
14
|
from .requirement_parser import RequirementParser
|
|
@@ -4332,48 +4333,50 @@ spec:
|
|
|
4332
4333
|
"""
|
|
4333
4334
|
|
|
4334
4335
|
def _render_ui_intelligence_summary(self, profile: dict) -> str:
|
|
4336
|
+
lib = profile.get("primary_library", {})
|
|
4337
|
+
stack = profile.get("component_stack", {})
|
|
4335
4338
|
lines = [
|
|
4336
|
-
f"- **界面定位**: {profile
|
|
4337
|
-
f"- **信息密度**: {profile
|
|
4338
|
-
f"- **行业语气**: {profile
|
|
4339
|
-
f"- **首选组件生态**: {
|
|
4340
|
-
f"- **表单基线**: {
|
|
4341
|
-
f"- **数据展示基线**: {
|
|
4339
|
+
f"- **界面定位**: {profile.get('surface', 'N/A')}",
|
|
4340
|
+
f"- **信息密度**: {profile.get('information_density', 'N/A')}",
|
|
4341
|
+
f"- **行业语气**: {profile.get('industry_tone', 'N/A')}",
|
|
4342
|
+
f"- **首选组件生态**: {lib.get('name', 'N/A')}",
|
|
4343
|
+
f"- **表单基线**: {stack.get('form', 'N/A')}",
|
|
4344
|
+
f"- **数据展示基线**: {stack.get('table', 'N/A')} / {stack.get('chart', 'N/A')}",
|
|
4342
4345
|
"",
|
|
4343
4346
|
"**优先原则**:",
|
|
4344
4347
|
]
|
|
4345
|
-
lines.extend(f"- {item}" for item in profile
|
|
4348
|
+
lines.extend(f"- {item}" for item in profile.get("benchmark_principles", []))
|
|
4346
4349
|
lines.extend(["", "**设计知识库关键词**:"])
|
|
4347
|
-
lines.append("- " + " / ".join(profile
|
|
4350
|
+
lines.append("- " + " / ".join(profile.get("knowledge_keywords", [])))
|
|
4348
4351
|
return "\n".join(lines)
|
|
4349
4352
|
|
|
4350
4353
|
def _render_component_ecosystem(self, profile: dict) -> str:
|
|
4351
|
-
primary = profile
|
|
4354
|
+
primary = profile.get("primary_library", {})
|
|
4352
4355
|
lines = [
|
|
4353
|
-
f"#### 首选方案: {primary
|
|
4356
|
+
f"#### 首选方案: {primary.get('name', 'N/A')}",
|
|
4354
4357
|
"",
|
|
4355
|
-
f"**适用原因**: {primary
|
|
4358
|
+
f"**适用原因**: {primary.get('rationale', 'N/A')}",
|
|
4356
4359
|
"",
|
|
4357
4360
|
"**核心能力**:",
|
|
4358
4361
|
]
|
|
4359
|
-
lines.extend(f"- {item}" for item in primary
|
|
4362
|
+
lines.extend(f"- {item}" for item in primary.get("strengths", []))
|
|
4360
4363
|
lines.extend(
|
|
4361
4364
|
[
|
|
4362
4365
|
"",
|
|
4363
4366
|
"**实现注意事项**:",
|
|
4364
4367
|
]
|
|
4365
4368
|
)
|
|
4366
|
-
lines.extend(f"- {item}" for item in primary
|
|
4369
|
+
lines.extend(f"- {item}" for item in primary.get("notes", []))
|
|
4367
4370
|
lines.extend(
|
|
4368
4371
|
[
|
|
4369
4372
|
"",
|
|
4370
4373
|
"#### 配套技术基线",
|
|
4371
4374
|
"",
|
|
4372
|
-
f"- **表单与验证**: {profile
|
|
4373
|
-
f"- **图表能力**: {profile
|
|
4374
|
-
f"- **表格/数据工作区**: {profile
|
|
4375
|
-
f"- **图标体系**: {profile
|
|
4376
|
-
f"- **动效能力**: {profile
|
|
4375
|
+
f"- **表单与验证**: {profile.get('component_stack', {}).get('form', 'N/A')}",
|
|
4376
|
+
f"- **图表能力**: {profile.get('component_stack', {}).get('chart', 'N/A')}",
|
|
4377
|
+
f"- **表格/数据工作区**: {profile.get('component_stack', {}).get('table', 'N/A')}",
|
|
4378
|
+
f"- **图标体系**: {profile.get('component_stack', {}).get('icons', 'N/A')}",
|
|
4379
|
+
f"- **动效能力**: {profile.get('component_stack', {}).get('motion', 'N/A')}",
|
|
4377
4380
|
]
|
|
4378
4381
|
)
|
|
4379
4382
|
|
|
@@ -4381,7 +4384,7 @@ spec:
|
|
|
4381
4384
|
if alternatives:
|
|
4382
4385
|
lines.extend(["", "#### 可选备选方案", ""])
|
|
4383
4386
|
for item in alternatives:
|
|
4384
|
-
lines.append(f"- **{item
|
|
4387
|
+
lines.append(f"- **{item.get('name', 'N/A')}**: {item.get('rationale', 'N/A')}")
|
|
4385
4388
|
matrix = profile.get("ui_library_matrix", [])
|
|
4386
4389
|
if matrix:
|
|
4387
4390
|
lines.extend(
|
|
@@ -4598,7 +4601,7 @@ spec:
|
|
|
4598
4601
|
|
|
4599
4602
|
except Exception as e:
|
|
4600
4603
|
# 如果设计引擎失败,返回空推荐
|
|
4601
|
-
|
|
4604
|
+
logging.getLogger(__name__).warning(f"Design engine failed: {e}")
|
|
4602
4605
|
return {
|
|
4603
4606
|
'styles': [],
|
|
4604
4607
|
'colors': None,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
+
import html
|
|
7
8
|
import json
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
|
|
@@ -53,7 +54,7 @@ class FrontendScaffoldBuilder:
|
|
|
53
54
|
<head>
|
|
54
55
|
<meta charset="UTF-8" />
|
|
55
56
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
56
|
-
<title>{self.name} · Frontend Blueprint</title>
|
|
57
|
+
<title>{html.escape(self.name)} · Frontend Blueprint</title>
|
|
57
58
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
58
59
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
59
60
|
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;700;800&family=Sora:wght@400;600;700&display=swap" rel="stylesheet" />
|
|
@@ -65,7 +66,7 @@ class FrontendScaffoldBuilder:
|
|
|
65
66
|
<nav class="topbar">
|
|
66
67
|
<div class="brand">
|
|
67
68
|
<span class="brand-mark">SD</span>
|
|
68
|
-
<span>{self.name}</span>
|
|
69
|
+
<span>{html.escape(self.name)}</span>
|
|
69
70
|
</div>
|
|
70
71
|
<div class="top-actions">
|
|
71
72
|
<a href="#trust">客户证明</a>
|
|
@@ -603,6 +604,7 @@ body {
|
|
|
603
604
|
"docs": docs,
|
|
604
605
|
}
|
|
605
606
|
payload_str = json.dumps(payload, ensure_ascii=False, indent=2)
|
|
607
|
+
payload_str = payload_str.replace("</", "<\\/")
|
|
606
608
|
return f"""const DATA = {payload_str};
|
|
607
609
|
|
|
608
610
|
const docContainer = document.getElementById("doc-links");
|