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.
Files changed (85) hide show
  1. {super_dev-2.1.1/super_dev.egg-info → super_dev-2.1.3}/PKG-INFO +56 -6
  2. {super_dev-2.1.1 → super_dev-2.1.3}/README.md +55 -5
  3. {super_dev-2.1.1 → super_dev-2.1.3}/pyproject.toml +1 -1
  4. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/__init__.py +1 -1
  5. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/dependency_graph.py +11 -4
  6. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/detectors.py +30 -19
  7. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/feature_checklist.py +0 -1
  8. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/catalogs.py +3 -0
  9. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/cli.py +35 -17
  10. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/config/manager.py +5 -0
  11. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/document_generator.py +23 -20
  12. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/frontend_builder.py +4 -2
  13. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/implementation_builder.py +2 -1
  14. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/prompt_generator.py +13 -11
  15. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/spec_builder.py +6 -6
  16. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/delivery.py +1 -1
  17. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/migration.py +8 -12
  18. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/charts.py +3 -2
  19. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/codegen.py +2 -1
  20. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/generator.py +8 -2
  21. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/landing.py +2 -1
  22. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/tech_stack.py +4 -3
  23. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/tokens.py +8 -5
  24. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/ux_guide.py +2 -1
  25. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/integrations/manager.py +47 -2
  26. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/engine.py +15 -14
  27. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/experts.py +1 -1
  28. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/knowledge.py +20 -20
  29. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/quality.py +7 -1
  30. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/reviewers/quality_gate.py +8 -5
  31. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/reviewers/redteam.py +2 -2
  32. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/reviewers/ui_review.py +9 -5
  33. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/skills/manager.py +1 -0
  34. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/specs/generator.py +4 -3
  35. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/specs/manager.py +9 -5
  36. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/specs/models.py +9 -5
  37. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/specs/validator.py +6 -4
  38. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/terminal.py +32 -3
  39. {super_dev-2.1.1 → super_dev-2.1.3/super_dev.egg-info}/PKG-INFO +56 -6
  40. {super_dev-2.1.1 → super_dev-2.1.3}/LICENSE +0 -0
  41. {super_dev-2.1.1 → super_dev-2.1.3}/setup.cfg +0 -0
  42. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/__init__.py +0 -0
  43. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/analyzer.py +0 -0
  44. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/impact.py +0 -0
  45. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/models.py +0 -0
  46. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/regression_guard.py +0 -0
  47. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/analyzer/repo_map.py +0 -0
  48. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/config/__init__.py +0 -0
  49. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/config/frontend.py +0 -0
  50. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/__init__.py +0 -0
  51. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/creator.py +0 -0
  52. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/requirement_parser.py +0 -0
  53. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/creators/task_executor.py +0 -0
  54. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/__init__.py +0 -0
  55. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/cicd.py +0 -0
  56. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/rehearsal.py +0 -0
  57. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/deployers/rehearsal_runner.py +0 -0
  58. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/__init__.py +0 -0
  59. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/aesthetics.py +0 -0
  60. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/engine.py +0 -0
  61. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/design/ui_intelligence.py +0 -0
  62. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/exceptions.py +0 -0
  63. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/experts/__init__.py +0 -0
  64. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/experts/service.py +0 -0
  65. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/integrations/__init__.py +0 -0
  66. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/__init__.py +0 -0
  67. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/contracts.py +0 -0
  68. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/orchestrator/telemetry.py +0 -0
  69. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/policy/__init__.py +0 -0
  70. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/policy/manager.py +0 -0
  71. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/proof_pack.py +0 -0
  72. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/release_readiness.py +1 -1
  73. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/review_state.py +0 -0
  74. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/reviewers/__init__.py +0 -0
  75. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/reviewers/code_review.py +0 -0
  76. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/skills/__init__.py +0 -0
  77. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/specs/__init__.py +0 -0
  78. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/utils/__init__.py +0 -0
  79. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/utils/logger.py +0 -0
  80. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev/web/api.py +0 -0
  81. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev.egg-info/SOURCES.txt +0 -0
  82. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev.egg-info/dependency_links.txt +0 -0
  83. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev.egg-info/entry_points.txt +0 -0
  84. {super_dev-2.1.1 → super_dev-2.1.3}/super_dev.egg-info/requires.txt +0 -0
  85. {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.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.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.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.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
- ## 20 宿主支持
482
+ ## 21 宿主支持
483
483
 
484
- ### CLI 宿主(9 个)
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.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.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.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
- ## 20 宿主支持
441
+ ## 21 宿主支持
442
442
 
443
- ### CLI 宿主(9 个)
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
  ## 关键文档
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "super-dev"
7
- version = "2.1.1"
7
+ version = "2.1.3"
8
8
  description = "Super Dev - Pipeline AI Coding Assistant"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -6,6 +6,6 @@
6
6
  最后修改:2025-12-30
7
7
  """
8
8
 
9
- __version__ = "2.1.1"
9
+ __version__ = "2.1.3"
10
10
  __author__ = "Excellent"
11
11
  __description__ = "超级开发战队 - 一个宿主内 AI 开发治理与编排工具"
@@ -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
- critical_nodes = self._critical_nodes(path_index, inbound, outbound)
132
- critical_paths = self._critical_paths(edges, critical_nodes)
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
- entry_paths = {item.path for item in self.repo_map_builder.build().entry_points}
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
- entry_points = [item.path for item in self.repo_map_builder.build().entry_points]
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
- # 检查 Electron 项目
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
 
@@ -362,7 +362,6 @@ class FeatureChecklistBuilder:
362
362
  return explicit_gaps
363
363
 
364
364
  result: list[FeatureChecklistItem] = []
365
- gap_lookup = {gap.title: gap for gap in explicit_gaps}
366
365
  for feature in features:
367
366
  state = "unknown"
368
367
  priority = ""
@@ -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() if RICH_AVAILABLE else None
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
- self.console.print(Panel(
3404
- f"[bold cyan]Super Dev Run[/bold cyan]\n\n"
3405
- f" [dim]环节[/dim] {normalized} ({label})\n"
3406
- f" [dim]专家[/dim] [bold]{expert_role}[/bold] - {expert_title}",
3407
- border_style="cyan",
3408
- expand=True,
3409
- padding=(1, 2),
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, (int, float)) else "-"
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" - {Path(str(task_execution_summary.report_file)).relative_to(project_dir)}"
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("integrate_ok", True)
8709
- skill_ok = host.get("skill_ok", True)
8710
- slash_ok = host.get("slash_ok", True)
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['surface']}",
4337
- f"- **信息密度**: {profile['information_density']}",
4338
- f"- **行业语气**: {profile['industry_tone']}",
4339
- f"- **首选组件生态**: {profile['primary_library']['name']}",
4340
- f"- **表单基线**: {profile['component_stack']['form']}",
4341
- f"- **数据展示基线**: {profile['component_stack']['table']} / {profile['component_stack']['chart']}",
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["benchmark_principles"])
4348
+ lines.extend(f"- {item}" for item in profile.get("benchmark_principles", []))
4346
4349
  lines.extend(["", "**设计知识库关键词**:"])
4347
- lines.append("- " + " / ".join(profile["knowledge_keywords"]))
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["primary_library"]
4354
+ primary = profile.get("primary_library", {})
4352
4355
  lines = [
4353
- f"#### 首选方案: {primary['name']}",
4356
+ f"#### 首选方案: {primary.get('name', 'N/A')}",
4354
4357
  "",
4355
- f"**适用原因**: {primary['rationale']}",
4358
+ f"**适用原因**: {primary.get('rationale', 'N/A')}",
4356
4359
  "",
4357
4360
  "**核心能力**:",
4358
4361
  ]
4359
- lines.extend(f"- {item}" for item in primary["strengths"])
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["notes"])
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['component_stack']['form']}",
4373
- f"- **图表能力**: {profile['component_stack']['chart']}",
4374
- f"- **表格/数据工作区**: {profile['component_stack']['table']}",
4375
- f"- **图标体系**: {profile['component_stack']['icons']}",
4376
- f"- **动效能力**: {profile['component_stack']['motion']}",
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['name']}**: {item['rationale']}")
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
- print(f"Warning: Design engine failed: {e}")
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");