super-dev 2.3.7__tar.gz → 2.3.8__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.3.7/super_dev.egg-info → super_dev-2.3.8}/PKG-INFO +6 -6
- {super_dev-2.3.7 → super_dev-2.3.8}/README.md +5 -5
- {super_dev-2.3.7 → super_dev-2.3.8}/pyproject.toml +1 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/__init__.py +1 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/analyzer/analyzer.py +3 -11
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/analyzer/dependency_graph.py +13 -4
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/analyzer/detectors.py +67 -21
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/analyzer/feature_checklist.py +29 -8
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/analyzer/impact.py +61 -17
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/analyzer/models.py +32 -26
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/analyzer/product_audit.py +16 -4
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/analyzer/regression_guard.py +3 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/analyzer/repo_map.py +21 -6
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/branding.py +1 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/catalogs.py +8 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/cli.py +117 -84
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/cli_analysis_mixin.py +3 -3
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/cli_deploy_runtime_mixin.py +125 -36
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/cli_experience_mixin.py +340 -70
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/cli_governance_mixin.py +59 -36
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/cli_host_ops_mixin.py +87 -17
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/cli_host_report_renderers.py +32 -15
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/cli_parser_mixin.py +82 -23
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/cli_spec_mixin.py +25 -28
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/config/frontend.py +6 -11
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/config/manager.py +20 -8
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/config/schema_validator.py +13 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/adr_generator.py +28 -22
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/creator.py +17 -19
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/document_generator.py +171 -90
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/document_generator_content_mixin.py +557 -185
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/frontend_builder.py +124 -100
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/implementation_builder.py +273 -243
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/prompt_generator.py +9 -3
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/prompt_templates.py +17 -4
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/requirement_parser.py +315 -66
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/spec_builder.py +12 -12
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/task_executor.py +22 -17
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/deployers/cicd.py +1 -2
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/deployers/delivery.py +32 -14
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/deployers/migration.py +212 -146
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/deployers/rehearsal.py +6 -3
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/deployers/rehearsal_runner.py +75 -26
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/__init__.py +2 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/aesthetics.py +89 -39
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/charts.py +71 -39
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/codegen.py +45 -45
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/engine.py +207 -51
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/generator.py +33 -29
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/landing.py +43 -31
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/tech_stack.py +45 -50
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/tokens.py +0 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/ui_intelligence.py +1503 -320
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/design/ux_guide.py +41 -41
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/enforcement/host_hooks.py +6 -3
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/enforcement/validation.py +6 -6
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/experts/service.py +4 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/framework_harness.py +45 -19
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/frameworks.py +15 -5
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/guard.py +1 -3
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/hook_harness.py +15 -5
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/hooks/manager.py +5 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/host_adapters.py +16 -3
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/integrations/manager.py +26 -3
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/integrations/manager_content_mixin.py +29 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/knowledge_evolution.py +100 -55
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/knowledge_tracker.py +34 -21
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/migrate.py +1 -3
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/operational_harness.py +26 -8
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/contracts.py +9 -3
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/engine.py +26 -28
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/experts.py +91 -65
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/governance.py +13 -17
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/knowledge.py +98 -31
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/knowledge_pusher.py +107 -88
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/overseer.py +5 -12
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/plan_executor.py +14 -12
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/quality.py +73 -51
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/telemetry.py +18 -4
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/pipeline_cost.py +0 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/policy/manager.py +14 -4
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/proof_pack.py +153 -64
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/protocols/a2a.py +1 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/release_readiness.py +124 -41
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/retry.py +2 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/review_state.py +9 -3
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reviewers/code_review.py +114 -98
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reviewers/quality_gate.py +6 -12
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reviewers/ui_review.py +270 -75
- super_dev-2.3.8/super_dev/runtime_evidence.py +377 -0
- super_dev-2.3.8/super_dev/seeai_design_system.py +288 -0
- super_dev-2.3.8/super_dev/seeai_smoke_scenarios.py +130 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/sequential_thinking.py +71 -15
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/session_checkpoint.py +1 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/skills/skill_template.py +160 -27
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/specs/generator.py +56 -52
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/specs/manager.py +107 -58
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/specs/models.py +65 -97
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/terminal.py +5 -4
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/utils/__init__.py +1 -1
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/web/api.py +122 -49
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/web/routers/workflow.py +2 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/workflow_contract.py +7 -5
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/workflow_harness.py +28 -11
- {super_dev-2.3.7 → super_dev-2.3.8/super_dev.egg-info}/PKG-INFO +6 -6
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev.egg-info/SOURCES.txt +2 -0
- super_dev-2.3.7/super_dev/runtime_evidence.py +0 -203
- {super_dev-2.3.7 → super_dev-2.3.8}/LICENSE +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/setup.cfg +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/_enforcement_bridge.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/analyzer/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/cli_release_quality_mixin.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/completion.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/config/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/api_contract.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/compact_template.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/component_scaffold.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/nextjs_scaffold.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/creators/prompt_sections.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/deployers/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/enforcement/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/enforcement/pre_code_gate.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/error_handler.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/exceptions.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/experts/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/experts/behavioral_prompts.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/experts/loader.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/experts/review_protocol.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/experts/toolkit.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/harness_registry.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/hooks/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/hooks/models.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/host_registry.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/i18n.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/integrations/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/integrations/install_manifest.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/memory/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/memory/consolidator.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/memory/extractor.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/memory/store.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/merge_safety.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/metrics/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/metrics/pipeline_metrics.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/onboarding.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/orchestrator/context_compact.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/policy/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/project_templates.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/protocols/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/protocols/output_schemas.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reminders.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reviewers/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reviewers/external_reviews.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reviewers/quality_advisor.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reviewers/redteam.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reviewers/review_agents.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reviewers/rules/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/reviewers/validation_rules.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/rules/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/rules/loader.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/session/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/session/brief.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/skills/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/skills/manager.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/specs/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/specs/consistency_checker.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/specs/traceability.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/specs/validator.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/tips.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/utils/logger.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/utils/structured_logging.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/version_check.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/web/helpers.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/web/rate_limit.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/web/routers/__init__.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/web/routers/config_routes.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/web/routers/experts.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/web/routers/health.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/webhooks.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev/workflow_state.py +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev.egg-info/dependency_links.txt +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev.egg-info/entry_points.txt +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/super_dev.egg-info/requires.txt +0 -0
- {super_dev-2.3.7 → super_dev-2.3.8}/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.3.
|
|
3
|
+
Version: 2.3.8
|
|
4
4
|
Summary: Super Dev - Pipeline AI Coding Assistant
|
|
5
5
|
Author-email: Excellent <11964948@qq.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -60,9 +60,9 @@ Dynamic: license-file
|
|
|
60
60
|
|
|
61
61
|
## 版本
|
|
62
62
|
|
|
63
|
-
当前版本:`2.3.
|
|
63
|
+
当前版本:`2.3.8`
|
|
64
64
|
|
|
65
|
-
- 发布说明:[v2.3.
|
|
65
|
+
- 发布说明:[v2.3.8 更新内容](docs/releases/2.3.8.md)
|
|
66
66
|
- 官网更新历史:[superdev.goder.ai/changelog](https://superdev.goder.ai/changelog)
|
|
67
67
|
|
|
68
68
|
---
|
|
@@ -437,13 +437,13 @@ super-dev
|
|
|
437
437
|
### 3. 指定版本安装
|
|
438
438
|
|
|
439
439
|
```bash
|
|
440
|
-
pip install super-dev==2.3.
|
|
440
|
+
pip install super-dev==2.3.8
|
|
441
441
|
```
|
|
442
442
|
|
|
443
443
|
### 4. GitHub 指定标签安装
|
|
444
444
|
|
|
445
445
|
```bash
|
|
446
|
-
pip install git+https://github.com/shangyankeji/super-dev.git@v2.3.
|
|
446
|
+
pip install git+https://github.com/shangyankeji/super-dev.git@v2.3.8
|
|
447
447
|
```
|
|
448
448
|
|
|
449
449
|
### 5. 源码开发安装
|
|
@@ -614,7 +614,7 @@ super-dev bootstrap --name my-project --platform web --frontend next --backend n
|
|
|
614
614
|
|
|
615
615
|
## 架构概览
|
|
616
616
|
|
|
617
|
-
Super Dev 2.3.
|
|
617
|
+
Super Dev 2.3.8 架构由四层组成:**宿主接入层**(20 个统一接入宿主 + 1 个 OpenClaw 手动插件宿主)、**知识治理层**(306 索引 / 渐进式加载 / 自演化)、**编排引擎层**(9 阶段流水线 / 11 专家 + Overseer / 验证规则引擎)、**交付审计层**(DORA 度量 / ADR / 一致性检测 / proof-pack)。
|
|
618
618
|
|
|
619
619
|
### 一、系统高阶流转架构
|
|
620
620
|
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
|
|
20
20
|
## 版本
|
|
21
21
|
|
|
22
|
-
当前版本:`2.3.
|
|
22
|
+
当前版本:`2.3.8`
|
|
23
23
|
|
|
24
|
-
- 发布说明:[v2.3.
|
|
24
|
+
- 发布说明:[v2.3.8 更新内容](docs/releases/2.3.8.md)
|
|
25
25
|
- 官网更新历史:[superdev.goder.ai/changelog](https://superdev.goder.ai/changelog)
|
|
26
26
|
|
|
27
27
|
---
|
|
@@ -396,13 +396,13 @@ super-dev
|
|
|
396
396
|
### 3. 指定版本安装
|
|
397
397
|
|
|
398
398
|
```bash
|
|
399
|
-
pip install super-dev==2.3.
|
|
399
|
+
pip install super-dev==2.3.8
|
|
400
400
|
```
|
|
401
401
|
|
|
402
402
|
### 4. GitHub 指定标签安装
|
|
403
403
|
|
|
404
404
|
```bash
|
|
405
|
-
pip install git+https://github.com/shangyankeji/super-dev.git@v2.3.
|
|
405
|
+
pip install git+https://github.com/shangyankeji/super-dev.git@v2.3.8
|
|
406
406
|
```
|
|
407
407
|
|
|
408
408
|
### 5. 源码开发安装
|
|
@@ -573,7 +573,7 @@ super-dev bootstrap --name my-project --platform web --frontend next --backend n
|
|
|
573
573
|
|
|
574
574
|
## 架构概览
|
|
575
575
|
|
|
576
|
-
Super Dev 2.3.
|
|
576
|
+
Super Dev 2.3.8 架构由四层组成:**宿主接入层**(20 个统一接入宿主 + 1 个 OpenClaw 手动插件宿主)、**知识治理层**(306 索引 / 渐进式加载 / 自演化)、**编排引擎层**(9 阶段流水线 / 11 专家 + Overseer / 验证规则引擎)、**交付审计层**(DORA 度量 / ADR / 一致性检测 / proof-pack)。
|
|
577
577
|
|
|
578
578
|
### 一、系统高阶流转架构
|
|
579
579
|
|
|
@@ -268,10 +268,7 @@ class ProjectAnalyzer:
|
|
|
268
268
|
except Exception:
|
|
269
269
|
parts = path.parts
|
|
270
270
|
|
|
271
|
-
return any(
|
|
272
|
-
part.startswith(".") or part in self._ignored_dir_names
|
|
273
|
-
for part in parts
|
|
274
|
-
)
|
|
271
|
+
return any(part.startswith(".") or part in self._ignored_dir_names for part in parts)
|
|
275
272
|
|
|
276
273
|
def _check_file_for_patterns(
|
|
277
274
|
self, file_path: Path, patterns: list[DesignPattern], language: str
|
|
@@ -295,9 +292,7 @@ class ProjectAnalyzer:
|
|
|
295
292
|
except (OSError, UnicodeDecodeError):
|
|
296
293
|
pass
|
|
297
294
|
|
|
298
|
-
def _detect_python_ast_patterns(
|
|
299
|
-
self, file_path: Path, patterns: list[DesignPattern]
|
|
300
|
-
) -> None:
|
|
295
|
+
def _detect_python_ast_patterns(self, file_path: Path, patterns: list[DesignPattern]) -> None:
|
|
301
296
|
"""使用 AST 检测 Python 设计模式"""
|
|
302
297
|
try:
|
|
303
298
|
content = file_path.read_text(encoding="utf-8")
|
|
@@ -465,7 +460,4 @@ class ProjectAnalyzer:
|
|
|
465
460
|
if total == 0:
|
|
466
461
|
return {}
|
|
467
462
|
|
|
468
|
-
return {
|
|
469
|
-
lang: (count / total) * 100
|
|
470
|
-
for lang, count in self._report.languages_used.items()
|
|
471
|
-
}
|
|
463
|
+
return {lang: (count / total) * 100 for lang, count in self._report.languages_used.items()}
|
|
@@ -124,7 +124,9 @@ class DependencyGraphBuilder:
|
|
|
124
124
|
|
|
125
125
|
def build(self) -> DependencyGraphReport:
|
|
126
126
|
files = self._collect_source_files()
|
|
127
|
-
path_index = {
|
|
127
|
+
path_index = {
|
|
128
|
+
str(path.relative_to(self.project_dir)).replace("\\", "/"): path for path in files
|
|
129
|
+
}
|
|
128
130
|
module_index = self._build_module_index(files)
|
|
129
131
|
edges = self._build_edges(files, module_index, path_index)
|
|
130
132
|
inbound, outbound = self._degree(edges)
|
|
@@ -152,7 +154,9 @@ class DependencyGraphBuilder:
|
|
|
152
154
|
md_path = self.output_dir / f"{self.project_name}-dependency-graph.md"
|
|
153
155
|
json_path = self.output_dir / f"{self.project_name}-dependency-graph.json"
|
|
154
156
|
md_path.write_text(report.to_markdown(), encoding="utf-8")
|
|
155
|
-
json_path.write_text(
|
|
157
|
+
json_path.write_text(
|
|
158
|
+
json.dumps(report.to_dict(), ensure_ascii=False, indent=2), encoding="utf-8"
|
|
159
|
+
)
|
|
156
160
|
return {"markdown": md_path, "json": json_path}
|
|
157
161
|
|
|
158
162
|
def _collect_source_files(self) -> list[Path]:
|
|
@@ -244,7 +248,10 @@ class DependencyGraphBuilder:
|
|
|
244
248
|
@staticmethod
|
|
245
249
|
def _extract_js_imports(content: str) -> list[tuple[str, str]]:
|
|
246
250
|
imports: list[tuple[str, str]] = []
|
|
247
|
-
for match in re.finditer(
|
|
251
|
+
for match in re.finditer(
|
|
252
|
+
r"""from\s+['"]([^'"]+)['"]|require\(\s*['"]([^'"]+)['"]\s*\)|import\(\s*['"]([^'"]+)['"]\s*\)""",
|
|
253
|
+
content,
|
|
254
|
+
):
|
|
248
255
|
raw = match.group(1) or match.group(2) or match.group(3)
|
|
249
256
|
if raw:
|
|
250
257
|
imports.append((raw, "module-import"))
|
|
@@ -312,7 +319,9 @@ class DependencyGraphBuilder:
|
|
|
312
319
|
role = "entry-point" if rel in entry_paths else "internal"
|
|
313
320
|
if score > 0 or role == "entry-point":
|
|
314
321
|
nodes.append(
|
|
315
|
-
DependencyNode(
|
|
322
|
+
DependencyNode(
|
|
323
|
+
path=rel, inbound=in_count, outbound=out_count, score=score, role=role
|
|
324
|
+
)
|
|
316
325
|
)
|
|
317
326
|
nodes.sort(key=lambda item: (item.score, item.inbound, item.outbound), reverse=True)
|
|
318
327
|
return nodes[:10]
|
|
@@ -97,16 +97,30 @@ def _detect_node_project_type(project_path: Path) -> ProjectCategory:
|
|
|
97
97
|
|
|
98
98
|
# 检测前端框架
|
|
99
99
|
frontend_frameworks = [
|
|
100
|
-
"react",
|
|
101
|
-
"
|
|
100
|
+
"react",
|
|
101
|
+
"react-dom",
|
|
102
|
+
"vue",
|
|
103
|
+
"vue-router",
|
|
104
|
+
"@angular/core",
|
|
105
|
+
"angular",
|
|
106
|
+
"svelte",
|
|
107
|
+
"next",
|
|
108
|
+
"nuxt",
|
|
109
|
+
"@remix-run/react",
|
|
102
110
|
]
|
|
103
111
|
|
|
104
112
|
has_frontend = any(fw in all_deps for fw in frontend_frameworks)
|
|
105
113
|
|
|
106
114
|
# 检测后端框架
|
|
107
115
|
backend_frameworks = [
|
|
108
|
-
"express",
|
|
109
|
-
"
|
|
116
|
+
"express",
|
|
117
|
+
"fastify",
|
|
118
|
+
"koa",
|
|
119
|
+
"nest",
|
|
120
|
+
"@nestjs/common",
|
|
121
|
+
"hapi",
|
|
122
|
+
"feathers",
|
|
123
|
+
"socket.io",
|
|
110
124
|
]
|
|
111
125
|
|
|
112
126
|
has_backend = any(bw in all_deps for bw in backend_frameworks)
|
|
@@ -159,16 +173,27 @@ def _detect_python_project_type(project_path: Path) -> ProjectCategory:
|
|
|
159
173
|
|
|
160
174
|
# 检测 Web 框架
|
|
161
175
|
web_frameworks = {
|
|
162
|
-
"django",
|
|
163
|
-
"
|
|
176
|
+
"django",
|
|
177
|
+
"flask",
|
|
178
|
+
"fastapi",
|
|
179
|
+
"starlette",
|
|
180
|
+
"tornado",
|
|
181
|
+
"aiohttp",
|
|
182
|
+
"sanic",
|
|
183
|
+
"quart",
|
|
164
184
|
}
|
|
165
185
|
|
|
166
186
|
has_web = any(fw in dependencies for fw in web_frameworks)
|
|
167
187
|
|
|
168
188
|
# 检测前端相关
|
|
169
189
|
frontend_related = {
|
|
170
|
-
"webpack",
|
|
171
|
-
"
|
|
190
|
+
"webpack",
|
|
191
|
+
"vite",
|
|
192
|
+
"rollup",
|
|
193
|
+
"parcel",
|
|
194
|
+
"react",
|
|
195
|
+
"vue",
|
|
196
|
+
"angular",
|
|
172
197
|
}
|
|
173
198
|
|
|
174
199
|
has_frontend = any(fr in dependencies for fr in frontend_related)
|
|
@@ -272,9 +297,15 @@ def _detect_node_tech_stack(project_path: Path, category: ProjectCategory) -> Te
|
|
|
272
297
|
# 检测 UI 库
|
|
273
298
|
ui_library = ""
|
|
274
299
|
ui_libraries = [
|
|
275
|
-
"@mui/material",
|
|
276
|
-
"
|
|
277
|
-
"
|
|
300
|
+
"@mui/material",
|
|
301
|
+
"@chakra-ui/react",
|
|
302
|
+
"@mantine/core",
|
|
303
|
+
"antd",
|
|
304
|
+
"react-bootstrap",
|
|
305
|
+
"tailwindcss",
|
|
306
|
+
"element-plus",
|
|
307
|
+
"vuetify",
|
|
308
|
+
"antd-mobile",
|
|
278
309
|
]
|
|
279
310
|
for lib in ui_libraries:
|
|
280
311
|
if lib in all_deps:
|
|
@@ -284,8 +315,14 @@ def _detect_node_tech_stack(project_path: Path, category: ProjectCategory) -> Te
|
|
|
284
315
|
# 检测状态管理
|
|
285
316
|
state_management = ""
|
|
286
317
|
state_libs = [
|
|
287
|
-
"redux",
|
|
288
|
-
"
|
|
318
|
+
"redux",
|
|
319
|
+
"@reduxjs/toolkit",
|
|
320
|
+
"zustand",
|
|
321
|
+
"jotai",
|
|
322
|
+
"recoil",
|
|
323
|
+
"mobx",
|
|
324
|
+
"pinia",
|
|
325
|
+
"vuex",
|
|
289
326
|
]
|
|
290
327
|
for lib in state_libs:
|
|
291
328
|
if lib in all_deps:
|
|
@@ -295,8 +332,12 @@ def _detect_node_tech_stack(project_path: Path, category: ProjectCategory) -> Te
|
|
|
295
332
|
# 检测构建工具
|
|
296
333
|
build_tool = ""
|
|
297
334
|
build_tools = [
|
|
298
|
-
"vite",
|
|
299
|
-
"
|
|
335
|
+
"vite",
|
|
336
|
+
"webpack",
|
|
337
|
+
"rollup",
|
|
338
|
+
"parcel",
|
|
339
|
+
"esbuild",
|
|
340
|
+
"turbo",
|
|
300
341
|
]
|
|
301
342
|
for tool in build_tools:
|
|
302
343
|
if tool in all_deps:
|
|
@@ -306,8 +347,12 @@ def _detect_node_tech_stack(project_path: Path, category: ProjectCategory) -> Te
|
|
|
306
347
|
# 检测测试框架
|
|
307
348
|
testing_framework = ""
|
|
308
349
|
test_frameworks = [
|
|
309
|
-
"jest",
|
|
310
|
-
"
|
|
350
|
+
"jest",
|
|
351
|
+
"vitest",
|
|
352
|
+
"@testing-library/react",
|
|
353
|
+
"mocha",
|
|
354
|
+
"chai",
|
|
355
|
+
"jasmine",
|
|
311
356
|
]
|
|
312
357
|
for fw in test_frameworks:
|
|
313
358
|
if fw in all_deps:
|
|
@@ -364,9 +409,7 @@ def _detect_python_tech_stack(project_path: Path, category: ProjectCategory) ->
|
|
|
364
409
|
if match:
|
|
365
410
|
name = match.group(1)
|
|
366
411
|
version = match.group(3) or ""
|
|
367
|
-
dependencies.append(
|
|
368
|
-
Dependency(name=name, version=version, type="prod")
|
|
369
|
-
)
|
|
412
|
+
dependencies.append(Dependency(name=name, version=version, type="prod"))
|
|
370
413
|
except OSError:
|
|
371
414
|
pass
|
|
372
415
|
|
|
@@ -514,7 +557,10 @@ def _detect_node_architecture(project_path: Path, dirs: list[str]) -> Architectu
|
|
|
514
557
|
|
|
515
558
|
# 整洁架构检测
|
|
516
559
|
clean_arch_indicators = [
|
|
517
|
-
"domain",
|
|
560
|
+
"domain",
|
|
561
|
+
"use-cases",
|
|
562
|
+
"application",
|
|
563
|
+
"infrastructure",
|
|
518
564
|
]
|
|
519
565
|
if any(ind in src_dirs for ind in clean_arch_indicators):
|
|
520
566
|
return ArchitecturePattern.CLEAN_ARCHITECTURE
|
|
@@ -20,7 +20,15 @@ GAP_KEYWORDS = ("未实现", "待实现", "未完成", "missing", "not implement
|
|
|
20
20
|
PRIORITY_PATTERN = re.compile(r"\b(P[0-3])\b", re.IGNORECASE)
|
|
21
21
|
EXPLICIT_GAP_SOURCE_KEYWORDS = ("gap", "research", "execution-plan", "coverage", "compare")
|
|
22
22
|
EXPLICIT_GAP_SECTION_KEYWORDS = ("missing", "gap", "未实现", "待实现", "差距", "缺口", "coverage")
|
|
23
|
-
FEATURE_GROUP_HEADING_KEYWORDS = (
|
|
23
|
+
FEATURE_GROUP_HEADING_KEYWORDS = (
|
|
24
|
+
"核心功能",
|
|
25
|
+
"扩展功能",
|
|
26
|
+
"高级功能",
|
|
27
|
+
"功能模块",
|
|
28
|
+
"核心模块",
|
|
29
|
+
"mvp",
|
|
30
|
+
"phase",
|
|
31
|
+
)
|
|
24
32
|
NON_FEATURE_HEADING_KEYWORDS = (
|
|
25
33
|
"用户故事",
|
|
26
34
|
"优先级",
|
|
@@ -95,7 +103,9 @@ class FeatureCoverageReport:
|
|
|
95
103
|
}
|
|
96
104
|
|
|
97
105
|
def to_markdown(self) -> str:
|
|
98
|
-
coverage_text =
|
|
106
|
+
coverage_text = (
|
|
107
|
+
f"{self.coverage_rate:.1f}%" if self.coverage_rate is not None else "unknown"
|
|
108
|
+
)
|
|
99
109
|
lines = [
|
|
100
110
|
"# Feature Checklist",
|
|
101
111
|
"",
|
|
@@ -172,7 +182,9 @@ class FeatureChecklistBuilder:
|
|
|
172
182
|
)
|
|
173
183
|
|
|
174
184
|
total_features = len(items)
|
|
175
|
-
coverage_rate =
|
|
185
|
+
coverage_rate = (
|
|
186
|
+
None if total_features == 0 else round((covered_count / total_features) * 100, 1)
|
|
187
|
+
)
|
|
176
188
|
if explicit_gaps:
|
|
177
189
|
status = "partial"
|
|
178
190
|
elif total_features == 0:
|
|
@@ -182,7 +194,9 @@ class FeatureChecklistBuilder:
|
|
|
182
194
|
else:
|
|
183
195
|
status = "partial"
|
|
184
196
|
|
|
185
|
-
summary = self._summary(
|
|
197
|
+
summary = self._summary(
|
|
198
|
+
status, coverage_rate, explicit_gaps, total_features, covered_count, unknown_count
|
|
199
|
+
)
|
|
186
200
|
return FeatureCoverageReport(
|
|
187
201
|
project_name=self.project_name,
|
|
188
202
|
project_path=str(self.project_dir),
|
|
@@ -204,7 +218,9 @@ class FeatureChecklistBuilder:
|
|
|
204
218
|
md_path = self.output_dir / f"{self.project_name}-feature-checklist.md"
|
|
205
219
|
json_path = self.output_dir / f"{self.project_name}-feature-checklist.json"
|
|
206
220
|
md_path.write_text(report.to_markdown(), encoding="utf-8")
|
|
207
|
-
json_path.write_text(
|
|
221
|
+
json_path.write_text(
|
|
222
|
+
json.dumps(report.to_dict(), ensure_ascii=False, indent=2), encoding="utf-8"
|
|
223
|
+
)
|
|
208
224
|
return {"markdown": md_path, "json": json_path}
|
|
209
225
|
|
|
210
226
|
def _latest(self, pattern: str, base_dir: Path | None = None) -> Path | None:
|
|
@@ -250,7 +266,9 @@ class FeatureChecklistBuilder:
|
|
|
250
266
|
if (
|
|
251
267
|
normalized_title
|
|
252
268
|
and normalized_title not in seen
|
|
253
|
-
and not any(
|
|
269
|
+
and not any(
|
|
270
|
+
keyword in title_lower for keyword in FEATURE_GROUP_HEADING_KEYWORDS
|
|
271
|
+
)
|
|
254
272
|
):
|
|
255
273
|
seen.add(normalized_title)
|
|
256
274
|
heading_items.append(
|
|
@@ -310,11 +328,14 @@ class FeatureChecklistBuilder:
|
|
|
310
328
|
heading = re.match(r"^(#{2,4})\s+(.+)$", line)
|
|
311
329
|
if heading:
|
|
312
330
|
in_gap_section = any(
|
|
313
|
-
keyword in heading.group(2).lower()
|
|
331
|
+
keyword in heading.group(2).lower()
|
|
332
|
+
for keyword in EXPLICIT_GAP_SECTION_KEYWORDS
|
|
314
333
|
)
|
|
315
334
|
continue
|
|
316
335
|
priority_match = PRIORITY_PATTERN.search(line)
|
|
317
|
-
has_gap_keyword = any(keyword in line.lower() for keyword in GAP_KEYWORDS) or bool(
|
|
336
|
+
has_gap_keyword = any(keyword in line.lower() for keyword in GAP_KEYWORDS) or bool(
|
|
337
|
+
priority_match
|
|
338
|
+
)
|
|
318
339
|
if not in_gap_section and not priority_match:
|
|
319
340
|
continue
|
|
320
341
|
if not has_gap_keyword:
|
|
@@ -55,7 +55,9 @@ class ImpactAnalysisReport:
|
|
|
55
55
|
"summary": self.summary,
|
|
56
56
|
"affected_modules": [item.to_dict() for item in self.affected_modules],
|
|
57
57
|
"affected_entry_points": [item.to_dict() for item in self.affected_entry_points],
|
|
58
|
-
"affected_integration_surfaces": [
|
|
58
|
+
"affected_integration_surfaces": [
|
|
59
|
+
item.to_dict() for item in self.affected_integration_surfaces
|
|
60
|
+
],
|
|
59
61
|
"regression_focus": list(self.regression_focus),
|
|
60
62
|
"recommended_steps": list(self.recommended_steps),
|
|
61
63
|
}
|
|
@@ -75,7 +77,9 @@ class ImpactAnalysisReport:
|
|
|
75
77
|
lines.extend(["", self.summary, ""])
|
|
76
78
|
self._append_items(lines, "Affected Modules", self.affected_modules)
|
|
77
79
|
self._append_items(lines, "Affected Entry Points", self.affected_entry_points)
|
|
78
|
-
self._append_items(
|
|
80
|
+
self._append_items(
|
|
81
|
+
lines, "Affected Integration Surfaces", self.affected_integration_surfaces
|
|
82
|
+
)
|
|
79
83
|
lines.extend(["", "## Regression Focus", ""])
|
|
80
84
|
if self.regression_focus:
|
|
81
85
|
for item in self.regression_focus:
|
|
@@ -113,14 +117,34 @@ class ImpactAnalyzer:
|
|
|
113
117
|
description_tokens = _tokenize(description)
|
|
114
118
|
normalized_files = [str(Path(file)).replace("\\", "/") for file in files]
|
|
115
119
|
|
|
116
|
-
affected_modules = self._score_repo_items(
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
affected_modules = self._score_repo_items(
|
|
121
|
+
repo_map.top_modules, normalized_files, description_tokens, "module"
|
|
122
|
+
)
|
|
123
|
+
affected_entry_points = self._score_repo_items(
|
|
124
|
+
repo_map.entry_points, normalized_files, description_tokens, "entry-point"
|
|
125
|
+
)
|
|
126
|
+
affected_surfaces = self._score_repo_items(
|
|
127
|
+
repo_map.integration_surfaces,
|
|
128
|
+
normalized_files,
|
|
129
|
+
description_tokens,
|
|
130
|
+
"integration-surface",
|
|
131
|
+
)
|
|
119
132
|
|
|
120
133
|
risk_level = self._risk_level(affected_modules, affected_entry_points, affected_surfaces)
|
|
121
|
-
summary = self._summary(
|
|
122
|
-
|
|
123
|
-
|
|
134
|
+
summary = self._summary(
|
|
135
|
+
description,
|
|
136
|
+
normalized_files,
|
|
137
|
+
risk_level,
|
|
138
|
+
affected_modules,
|
|
139
|
+
affected_entry_points,
|
|
140
|
+
affected_surfaces,
|
|
141
|
+
)
|
|
142
|
+
regression_focus = self._regression_focus(
|
|
143
|
+
affected_modules, affected_surfaces, normalized_files
|
|
144
|
+
)
|
|
145
|
+
recommended_steps = self._recommended_steps(
|
|
146
|
+
risk_level, affected_modules, affected_surfaces, normalized_files
|
|
147
|
+
)
|
|
124
148
|
|
|
125
149
|
return ImpactAnalysisReport(
|
|
126
150
|
project_name=self.project_name,
|
|
@@ -140,7 +164,9 @@ class ImpactAnalyzer:
|
|
|
140
164
|
md_path = self.output_dir / f"{self.project_name}-impact-analysis.md"
|
|
141
165
|
json_path = self.output_dir / f"{self.project_name}-impact-analysis.json"
|
|
142
166
|
md_path.write_text(report.to_markdown(), encoding="utf-8")
|
|
143
|
-
json_path.write_text(
|
|
167
|
+
json_path.write_text(
|
|
168
|
+
json.dumps(report.to_dict(), ensure_ascii=False, indent=2), encoding="utf-8"
|
|
169
|
+
)
|
|
144
170
|
return {"markdown": md_path, "json": json_path}
|
|
145
171
|
|
|
146
172
|
def _score_repo_items(
|
|
@@ -160,7 +186,11 @@ class ImpactAnalyzer:
|
|
|
160
186
|
for file in files:
|
|
161
187
|
file_lower = file.lower()
|
|
162
188
|
top = file_lower.split("/")[0]
|
|
163
|
-
if
|
|
189
|
+
if (
|
|
190
|
+
item_path == file_lower
|
|
191
|
+
or item_path.startswith(file_lower)
|
|
192
|
+
or file_lower.startswith(item_path)
|
|
193
|
+
):
|
|
164
194
|
confidence = max(confidence, 0.95)
|
|
165
195
|
reasons.append("direct file/path overlap")
|
|
166
196
|
elif item_path == top or item_path.startswith(f"{top}/") or top == item_path:
|
|
@@ -219,19 +249,27 @@ class ImpactAnalyzer:
|
|
|
219
249
|
)
|
|
220
250
|
|
|
221
251
|
@staticmethod
|
|
222
|
-
def _regression_focus(
|
|
252
|
+
def _regression_focus(
|
|
253
|
+
modules: list[ImpactItem], surfaces: list[ImpactItem], files: list[str]
|
|
254
|
+
) -> list[str]:
|
|
223
255
|
focus: list[str] = []
|
|
224
|
-
joined_paths = " ".join(
|
|
256
|
+
joined_paths = " ".join(
|
|
257
|
+
[item.path.lower() for item in modules + surfaces] + [file.lower() for file in files]
|
|
258
|
+
)
|
|
225
259
|
if any(token in joined_paths for token in ["auth", "login", "session", "permission"]):
|
|
226
260
|
focus.append("Authentication, session, and permission regression checks")
|
|
227
261
|
if any(token in joined_paths for token in ["api", "controller", "route", "router"]):
|
|
228
262
|
focus.append("API contract and route-level regression checks")
|
|
229
263
|
if any(token in joined_paths for token in ["component", "ui", "page", "screen", "view"]):
|
|
230
264
|
focus.append("Critical UI paths, navigation, and state transition checks")
|
|
231
|
-
if any(
|
|
265
|
+
if any(
|
|
266
|
+
token in joined_paths for token in ["db", "database", "repository", "model", "entity"]
|
|
267
|
+
):
|
|
232
268
|
focus.append("Data model, persistence, and migration regression checks")
|
|
233
269
|
if not focus:
|
|
234
|
-
focus.append(
|
|
270
|
+
focus.append(
|
|
271
|
+
"Smoke test the primary user flow and the modules most likely to be touched"
|
|
272
|
+
)
|
|
235
273
|
return focus
|
|
236
274
|
|
|
237
275
|
@staticmethod
|
|
@@ -246,10 +284,16 @@ class ImpactAnalyzer:
|
|
|
246
284
|
"Limit edits to the highest-confidence modules before expanding the scope.",
|
|
247
285
|
]
|
|
248
286
|
if risk_level == "high":
|
|
249
|
-
steps.append(
|
|
287
|
+
steps.append(
|
|
288
|
+
"Freeze the affected surface in PRD / Architecture / UIUX or patch docs before coding."
|
|
289
|
+
)
|
|
250
290
|
if surfaces:
|
|
251
|
-
steps.append(
|
|
291
|
+
steps.append(
|
|
292
|
+
"Re-test the affected integration surfaces before declaring the change complete."
|
|
293
|
+
)
|
|
252
294
|
if files:
|
|
253
|
-
steps.append(
|
|
295
|
+
steps.append(
|
|
296
|
+
"Use the changed file list as the minimum review set, then inspect adjacent modules only if impact expands."
|
|
297
|
+
)
|
|
254
298
|
steps.append("Rerun bugfix/runtime/quality validation after implementation.")
|
|
255
299
|
return steps
|
|
@@ -88,9 +88,7 @@ class TechStack:
|
|
|
88
88
|
"""转换为字典"""
|
|
89
89
|
# 处理 framework 可能是字符串或枚举
|
|
90
90
|
framework_value = (
|
|
91
|
-
self.framework.value
|
|
92
|
-
if isinstance(self.framework, FrameworkType)
|
|
93
|
-
else self.framework
|
|
91
|
+
self.framework.value if isinstance(self.framework, FrameworkType) else self.framework
|
|
94
92
|
)
|
|
95
93
|
|
|
96
94
|
return {
|
|
@@ -231,31 +229,37 @@ class ArchitectureReport:
|
|
|
231
229
|
lines.append(f"- **测试框架**: {self.tech_stack.testing_framework}")
|
|
232
230
|
|
|
233
231
|
if self.architecture_pattern:
|
|
234
|
-
lines.extend(
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
232
|
+
lines.extend(
|
|
233
|
+
[
|
|
234
|
+
"",
|
|
235
|
+
"## 架构模式",
|
|
236
|
+
"",
|
|
237
|
+
f"识别到: **{self.architecture_pattern.value}**",
|
|
238
|
+
]
|
|
239
|
+
)
|
|
240
240
|
|
|
241
241
|
if self.design_patterns:
|
|
242
|
-
lines.extend(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
242
|
+
lines.extend(
|
|
243
|
+
[
|
|
244
|
+
"",
|
|
245
|
+
"## 设计模式",
|
|
246
|
+
"",
|
|
247
|
+
]
|
|
248
|
+
)
|
|
247
249
|
for pattern in self.design_patterns:
|
|
248
250
|
lines.append(f"- **{pattern.name.value}**: `{pattern.location}`")
|
|
249
251
|
if pattern.description:
|
|
250
252
|
lines.append(f" - {pattern.description}")
|
|
251
253
|
|
|
252
|
-
lines.extend(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
254
|
+
lines.extend(
|
|
255
|
+
[
|
|
256
|
+
"",
|
|
257
|
+
"## 项目统计",
|
|
258
|
+
"",
|
|
259
|
+
f"- **文件数量**: {self.file_count}",
|
|
260
|
+
f"- **代码行数**: {self.total_lines:,}",
|
|
261
|
+
]
|
|
262
|
+
)
|
|
259
263
|
|
|
260
264
|
if self.languages_used:
|
|
261
265
|
lines.append("- **语言分布**:")
|
|
@@ -266,11 +270,13 @@ class ArchitectureReport:
|
|
|
266
270
|
lines.append(f" - {lang}: {count:,} 行 ({percentage:.1f}%)")
|
|
267
271
|
|
|
268
272
|
if self.tech_stack.dependencies:
|
|
269
|
-
lines.extend(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
lines.extend(
|
|
274
|
+
[
|
|
275
|
+
"",
|
|
276
|
+
f"## 主要依赖 ({len(self.tech_stack.dependencies)})",
|
|
277
|
+
"",
|
|
278
|
+
]
|
|
279
|
+
)
|
|
274
280
|
for dep in self.tech_stack.dependencies[:20]: # 只显示前20个
|
|
275
281
|
lines.append(f"- {dep}")
|
|
276
282
|
|