moai-adk 0.35.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/__init__.py +10 -0
- moai_adk/__main__.py +199 -0
- moai_adk/cli/__init__.py +6 -0
- moai_adk/cli/commands/__init__.py +17 -0
- moai_adk/cli/commands/analyze.py +116 -0
- moai_adk/cli/commands/doctor.py +272 -0
- moai_adk/cli/commands/init.py +372 -0
- moai_adk/cli/commands/language.py +248 -0
- moai_adk/cli/commands/status.py +104 -0
- moai_adk/cli/commands/update.py +2686 -0
- moai_adk/cli/main.py +13 -0
- moai_adk/cli/prompts/__init__.py +5 -0
- moai_adk/cli/prompts/init_prompts.py +219 -0
- moai_adk/cli/spec_status.py +263 -0
- moai_adk/cli/ui/__init__.py +44 -0
- moai_adk/cli/ui/progress.py +422 -0
- moai_adk/cli/ui/prompts.py +389 -0
- moai_adk/cli/ui/theme.py +129 -0
- moai_adk/cli/worktree/__init__.py +27 -0
- moai_adk/cli/worktree/__main__.py +31 -0
- moai_adk/cli/worktree/cli.py +683 -0
- moai_adk/cli/worktree/exceptions.py +89 -0
- moai_adk/cli/worktree/manager.py +493 -0
- moai_adk/cli/worktree/models.py +65 -0
- moai_adk/cli/worktree/registry.py +422 -0
- moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
- moai_adk/core/__init__.py +1 -0
- moai_adk/core/analysis/__init__.py +9 -0
- moai_adk/core/analysis/session_analyzer.py +400 -0
- moai_adk/core/claude_integration.py +393 -0
- moai_adk/core/command_helpers.py +270 -0
- moai_adk/core/comprehensive_monitoring_system.py +1183 -0
- moai_adk/core/config/__init__.py +19 -0
- moai_adk/core/config/auto_spec_config.py +340 -0
- moai_adk/core/config/migration.py +244 -0
- moai_adk/core/config/unified.py +436 -0
- moai_adk/core/context_manager.py +273 -0
- moai_adk/core/diagnostics/__init__.py +19 -0
- moai_adk/core/diagnostics/slash_commands.py +159 -0
- moai_adk/core/enterprise_features.py +1404 -0
- moai_adk/core/error_recovery_system.py +1902 -0
- moai_adk/core/event_driven_hook_system.py +1371 -0
- moai_adk/core/git/__init__.py +31 -0
- moai_adk/core/git/branch.py +25 -0
- moai_adk/core/git/branch_manager.py +129 -0
- moai_adk/core/git/checkpoint.py +134 -0
- moai_adk/core/git/commit.py +67 -0
- moai_adk/core/git/conflict_detector.py +413 -0
- moai_adk/core/git/event_detector.py +79 -0
- moai_adk/core/git/manager.py +216 -0
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +901 -0
- moai_adk/core/input_validation_middleware.py +1006 -0
- moai_adk/core/integration/__init__.py +22 -0
- moai_adk/core/integration/engine.py +157 -0
- moai_adk/core/integration/integration_tester.py +226 -0
- moai_adk/core/integration/models.py +88 -0
- moai_adk/core/integration/utils.py +211 -0
- moai_adk/core/issue_creator.py +305 -0
- moai_adk/core/jit_context_loader.py +956 -0
- moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
- moai_adk/core/language_config.py +202 -0
- moai_adk/core/language_config_resolver.py +572 -0
- moai_adk/core/language_validator.py +543 -0
- moai_adk/core/mcp/setup.py +116 -0
- moai_adk/core/merge/__init__.py +9 -0
- moai_adk/core/merge/analyzer.py +605 -0
- moai_adk/core/migration/__init__.py +18 -0
- moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
- moai_adk/core/migration/backup_manager.py +277 -0
- moai_adk/core/migration/custom_element_scanner.py +358 -0
- moai_adk/core/migration/file_migrator.py +209 -0
- moai_adk/core/migration/interactive_checkbox_ui.py +488 -0
- moai_adk/core/migration/selective_restorer.py +470 -0
- moai_adk/core/migration/template_utils.py +74 -0
- moai_adk/core/migration/user_selection_ui.py +338 -0
- moai_adk/core/migration/version_detector.py +139 -0
- moai_adk/core/migration/version_migrator.py +228 -0
- moai_adk/core/performance/__init__.py +6 -0
- moai_adk/core/performance/cache_system.py +316 -0
- moai_adk/core/performance/parallel_processor.py +116 -0
- moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
- moai_adk/core/project/__init__.py +1 -0
- moai_adk/core/project/backup_utils.py +70 -0
- moai_adk/core/project/checker.py +300 -0
- moai_adk/core/project/detector.py +293 -0
- moai_adk/core/project/initializer.py +387 -0
- moai_adk/core/project/phase_executor.py +716 -0
- moai_adk/core/project/validator.py +139 -0
- moai_adk/core/quality/__init__.py +6 -0
- moai_adk/core/quality/trust_checker.py +377 -0
- moai_adk/core/quality/validators/__init__.py +6 -0
- moai_adk/core/quality/validators/base_validator.py +19 -0
- moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
- moai_adk/core/robust_json_parser.py +611 -0
- moai_adk/core/rollback_manager.py +918 -0
- moai_adk/core/session_manager.py +651 -0
- moai_adk/core/skill_loading_system.py +579 -0
- moai_adk/core/spec/confidence_scoring.py +680 -0
- moai_adk/core/spec/ears_template_engine.py +1247 -0
- moai_adk/core/spec/quality_validator.py +687 -0
- moai_adk/core/spec_status_manager.py +478 -0
- moai_adk/core/template/__init__.py +7 -0
- moai_adk/core/template/backup.py +174 -0
- moai_adk/core/template/config.py +191 -0
- moai_adk/core/template/languages.py +43 -0
- moai_adk/core/template/merger.py +233 -0
- moai_adk/core/template/processor.py +1200 -0
- moai_adk/core/template_engine.py +310 -0
- moai_adk/core/template_variable_synchronizer.py +417 -0
- moai_adk/core/unified_permission_manager.py +745 -0
- moai_adk/core/user_behavior_analytics.py +851 -0
- moai_adk/core/version_sync.py +429 -0
- moai_adk/foundation/__init__.py +56 -0
- moai_adk/foundation/backend.py +1027 -0
- moai_adk/foundation/database.py +1115 -0
- moai_adk/foundation/devops.py +1585 -0
- moai_adk/foundation/ears.py +431 -0
- moai_adk/foundation/frontend.py +870 -0
- moai_adk/foundation/git/commit_templates.py +557 -0
- moai_adk/foundation/git.py +376 -0
- moai_adk/foundation/langs.py +484 -0
- moai_adk/foundation/ml_ops.py +1162 -0
- moai_adk/foundation/testing.py +1524 -0
- moai_adk/foundation/trust/trust_principles.py +676 -0
- moai_adk/foundation/trust/validation_checklist.py +1573 -0
- moai_adk/project/__init__.py +0 -0
- moai_adk/project/configuration.py +1084 -0
- moai_adk/project/documentation.py +566 -0
- moai_adk/project/schema.py +447 -0
- moai_adk/statusline/__init__.py +38 -0
- moai_adk/statusline/alfred_detector.py +105 -0
- moai_adk/statusline/config.py +376 -0
- moai_adk/statusline/enhanced_output_style_detector.py +372 -0
- moai_adk/statusline/git_collector.py +190 -0
- moai_adk/statusline/main.py +322 -0
- moai_adk/statusline/metrics_tracker.py +78 -0
- moai_adk/statusline/renderer.py +343 -0
- moai_adk/statusline/update_checker.py +129 -0
- moai_adk/statusline/version_reader.py +741 -0
- moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +714 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +474 -0
- moai_adk/templates/.claude/agents/moai/builder-command.md +1172 -0
- moai_adk/templates/.claude/agents/moai/builder-plugin.md +637 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +666 -0
- moai_adk/templates/.claude/agents/moai/expert-backend.md +899 -0
- moai_adk/templates/.claude/agents/moai/expert-database.md +777 -0
- moai_adk/templates/.claude/agents/moai/expert-debug.md +401 -0
- moai_adk/templates/.claude/agents/moai/expert-devops.md +720 -0
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +734 -0
- moai_adk/templates/.claude/agents/moai/expert-performance.md +657 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +513 -0
- moai_adk/templates/.claude/agents/moai/expert-testing.md +733 -0
- moai_adk/templates/.claude/agents/moai/expert-uiux.md +1041 -0
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +432 -0
- moai_adk/templates/.claude/agents/moai/manager-docs.md +573 -0
- moai_adk/templates/.claude/agents/moai/manager-git.md +1060 -0
- moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
- moai_adk/templates/.claude/agents/moai/manager-quality.md +624 -0
- moai_adk/templates/.claude/agents/moai/manager-spec.md +809 -0
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +780 -0
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +784 -0
- moai_adk/templates/.claude/agents/moai/mcp-context7.md +458 -0
- moai_adk/templates/.claude/agents/moai/mcp-figma.md +1607 -0
- moai_adk/templates/.claude/agents/moai/mcp-notion.md +789 -0
- moai_adk/templates/.claude/agents/moai/mcp-playwright.md +469 -0
- moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +1032 -0
- moai_adk/templates/.claude/commands/moai/0-project.md +1386 -0
- moai_adk/templates/.claude/commands/moai/1-plan.md +1427 -0
- moai_adk/templates/.claude/commands/moai/2-run.md +943 -0
- moai_adk/templates/.claude/commands/moai/3-sync.md +1324 -0
- moai_adk/templates/.claude/commands/moai/9-feedback.md +314 -0
- moai_adk/templates/.claude/hooks/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/lib/__init__.py +85 -0
- moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +244 -0
- moai_adk/templates/.claude/hooks/moai/lib/common.py +131 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +446 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
- moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +590 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +317 -0
- moai_adk/templates/.claude/hooks/moai/lib/models.py +102 -0
- moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +28 -0
- moai_adk/templates/.claude/hooks/moai/lib/project.py +768 -0
- moai_adk/templates/.claude/hooks/moai/lib/test_hooks_improvements.py +443 -0
- moai_adk/templates/.claude/hooks/moai/lib/timeout.py +160 -0
- moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +530 -0
- moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +862 -0
- moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +1083 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +560 -0
- moai_adk/templates/.claude/output-styles/moai/yoda.md +359 -0
- moai_adk/templates/.claude/settings.json +172 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +307 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +431 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/batch_generate.py +560 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/generate_image.py +362 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +249 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +406 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +44 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +130 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +152 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +178 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +147 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +328 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +320 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +718 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +464 -0
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +323 -0
- moai_adk/templates/.claude/skills/moai-domain-database/examples.md +830 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/README.md +53 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/mongodb.md +231 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/postgresql.md +169 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/redis.md +262 -0
- moai_adk/templates/.claude/skills/moai-domain-database/reference.md +545 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +968 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +664 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +455 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
- moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +492 -0
- moai_adk/templates/.claude/skills/moai-formats-data/examples.md +804 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +98 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/SKILL-MODULARIZATION-TEMPLATE.md +278 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/caching-performance.md +459 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/data-validation.md +485 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/json-optimization.md +374 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/toon-encoding.md +308 -0
- moai_adk/templates/.claude/skills/moai-formats-data/reference.md +585 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +202 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/examples.md +732 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/best-practices-checklist.md +616 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +560 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-iam-official.md +635 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-memory-official.md +543 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-settings-official.md +663 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +113 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +238 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/complete-configuration-guide.md +175 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-examples.md +1674 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-formatting-guide.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-examples.md +1513 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-formatting-guide.md +1086 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-integration-patterns.md +1100 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference.md +209 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +441 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/examples.md +1048 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/reference.md +246 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +420 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/examples.md +358 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/README.md +296 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/agents-reference.md +359 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/commands-reference.md +432 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +757 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/execution-rules.md +687 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/modular-system.md +665 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/progressive-disclosure.md +649 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +864 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/token-optimization.md +708 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +981 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/reference.md +478 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +315 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/examples.md +228 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/assumption-matrix.md +80 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/cognitive-bias.md +199 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/first-principles.md +140 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/trade-off-analysis.md +154 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/reference.md +157 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +364 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/examples.md +1232 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/best-practices.md +261 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/integration-patterns.md +194 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/proactive-analysis.md +229 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/trust5-validation.md +169 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/reference.md +1266 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/scripts/quality-gate.sh +668 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/github-actions-quality.yml +481 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/quality-config.yaml +519 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +649 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +478 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +612 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +477 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/examples.md +1090 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/reference.md +686 -0
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +376 -0
- moai_adk/templates/.claude/skills/moai-lang-go/examples.md +919 -0
- moai_adk/templates/.claude/skills/moai-lang-go/reference.md +737 -0
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +385 -0
- moai_adk/templates/.claude/skills/moai-lang-java/examples.md +864 -0
- moai_adk/templates/.claude/skills/moai-lang-java/reference.md +291 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +382 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +1006 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +562 -0
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +644 -0
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +481 -0
- moai_adk/templates/.claude/skills/moai-lang-python/examples.md +977 -0
- moai_adk/templates/.claude/skills/moai-lang-python/reference.md +804 -0
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +579 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +687 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +372 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +659 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +504 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +633 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +423 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +918 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +672 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +368 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +1089 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +731 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +300 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/advanced-patterns.md +465 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/optimization.md +440 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/reference.md +228 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +319 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/examples.md +592 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-deployment-patterns.md +182 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +17 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +57 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/content-architecture-optimization.md +162 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/deployment.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/framework-core-configuration.md +186 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/i18n-setup.md +55 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/mdx-components.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/optimization.md +303 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/reference.md +379 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +372 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
- moai_adk/templates/.claude/skills/moai-mcp-figma/SKILL.md +402 -0
- moai_adk/templates/.claude/skills/moai-mcp-figma/advanced-patterns.md +607 -0
- moai_adk/templates/.claude/skills/moai-mcp-notion/SKILL.md +300 -0
- moai_adk/templates/.claude/skills/moai-mcp-notion/advanced-patterns.md +537 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +291 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +390 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +398 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +379 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +358 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +467 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +377 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +466 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +482 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/SKILL.md +474 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/examples.md +621 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/migration.md +341 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/reference.md +463 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/validation.md +373 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/SKILL.md +275 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/adaptive-mfa.md +233 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/akamai-integration.md +215 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/application-credentials.md +280 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-log-events.md +225 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-overview.md +140 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/bot-detection.md +144 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/breached-password-detection.md +187 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/brute-force-protection.md +189 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/certifications.md +282 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/compliance-overview.md +263 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/continuous-session-protection.md +307 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/customize-mfa.md +178 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/dpop-implementation.md +283 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/fapi-implementation.md +259 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/gdpr-compliance.md +313 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/guardian-configuration.md +269 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/highly-regulated-identity.md +272 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/jwt-fundamentals.md +248 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mdl-verification.md +211 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-api-management.md +278 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-factors.md +226 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-overview.md +174 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mtls-sender-constraining.md +316 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/ropg-flow-mfa.md +217 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-center.md +325 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-guidance.md +277 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/state-parameters.md +178 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/step-up-authentication.md +251 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/suspicious-ip-throttling.md +240 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/tenant-access-control.md +180 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/webauthn-fido.md +235 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +449 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/examples.md +544 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/reference.md +307 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +390 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +520 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +574 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +317 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +663 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +175 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples.md +547 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +17 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +158 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +340 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +713 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +538 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +1336 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +730 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +608 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +1005 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/reference.md +275 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1434 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +92 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +436 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +534 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/examples.md +900 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/reference.md +704 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +377 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/examples.md +552 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/code-templates.md +124 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/feedback-templates.md +100 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/template-optimizer.md +138 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/reference.md +346 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/LICENSE.txt +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +456 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/advanced-patterns.md +576 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/ai-powered-testing.py +294 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/console_logging.py +35 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/element_discovery.py +40 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/static_html_automation.py +34 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples.md +672 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +220 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +845 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +1416 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +1234 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +1243 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +1260 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/optimization.md +505 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/reference/playwright-best-practices.md +57 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/reference.md +440 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/scripts/with_server.py +218 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/templates/alfred-integration.md +376 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/workflows/enterprise-testing-workflow.py +571 -0
- moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +411 -0
- moai_adk/templates/.claude/skills/moai-worktree/examples.md +606 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +982 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +778 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +646 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +782 -0
- moai_adk/templates/.claude/skills/moai-worktree/reference.md +357 -0
- moai_adk/templates/.git-hooks/pre-commit +128 -0
- moai_adk/templates/.git-hooks/pre-push +365 -0
- moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
- moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
- moai_adk/templates/.github/workflows/spec-issue-sync.yml +337 -0
- moai_adk/templates/.gitignore +222 -0
- moai_adk/templates/.mcp.json +13 -0
- moai_adk/templates/.moai/config/config.yaml +58 -0
- moai_adk/templates/.moai/config/questions/_schema.yaml +174 -0
- moai_adk/templates/.moai/config/questions/tab0-init.yaml +251 -0
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +107 -0
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +79 -0
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +632 -0
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +182 -0
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +96 -0
- moai_adk/templates/.moai/config/sections/git-strategy.yaml +116 -0
- moai_adk/templates/.moai/config/sections/language.yaml +11 -0
- moai_adk/templates/.moai/config/sections/project.yaml +13 -0
- moai_adk/templates/.moai/config/sections/quality.yaml +17 -0
- moai_adk/templates/.moai/config/sections/system.yaml +24 -0
- moai_adk/templates/.moai/config/sections/user.yaml +5 -0
- moai_adk/templates/.moai/config/statusline-config.yaml +92 -0
- moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
- moai_adk/templates/CLAUDE.md +642 -0
- moai_adk/utils/__init__.py +30 -0
- moai_adk/utils/banner.py +38 -0
- moai_adk/utils/common.py +294 -0
- moai_adk/utils/link_validator.py +241 -0
- moai_adk/utils/logger.py +147 -0
- moai_adk/utils/safe_file_reader.py +206 -0
- moai_adk/utils/timeout.py +160 -0
- moai_adk/utils/toon_utils.py +256 -0
- moai_adk/version.py +22 -0
- moai_adk-0.35.1.dist-info/METADATA +3018 -0
- moai_adk-0.35.1.dist-info/RECORD +502 -0
- moai_adk-0.35.1.dist-info/WHEEL +4 -0
- moai_adk-0.35.1.dist-info/entry_points.txt +3 -0
- moai_adk-0.35.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,1243 @@
|
|
|
1
|
+
# Smart Refactoring with Technical Debt Management
|
|
2
|
+
|
|
3
|
+
> Module: AI-powered code refactoring with technical debt analysis and safe transformation
|
|
4
|
+
> Complexity: Advanced
|
|
5
|
+
> Time: 25+ minutes
|
|
6
|
+
> Dependencies: Python 3.8+, Rope, AST, Context7 MCP, asyncio, dataclasses
|
|
7
|
+
|
|
8
|
+
## Core Implementation
|
|
9
|
+
|
|
10
|
+
### AIRefactorer Class
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
import ast
|
|
14
|
+
import asyncio
|
|
15
|
+
from typing import Dict, List, Optional, Any, Union, Tuple
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from enum import Enum
|
|
18
|
+
import rope.base.project
|
|
19
|
+
import rope.base.libutils
|
|
20
|
+
from rope.refactor import rename, move, extract, inline
|
|
21
|
+
|
|
22
|
+
class RefactorType(Enum):
|
|
23
|
+
"""Types of refactoring operations."""
|
|
24
|
+
RENAME = "rename"
|
|
25
|
+
EXTRACT_METHOD = "extract_method"
|
|
26
|
+
EXTRACT_VARIABLE = "extract_variable"
|
|
27
|
+
INLINE_VARIABLE = "inline_variable"
|
|
28
|
+
MOVE_MODULE = "move_module"
|
|
29
|
+
REORGANIZE_IMPORTS = "reorganize_imports"
|
|
30
|
+
SIMPLIFY_CONDITIONALS = "simplify_conditionals"
|
|
31
|
+
EXTRACT_CLASS = "extract_class"
|
|
32
|
+
REMOVE_DEAD_CODE = "remove_dead_code"
|
|
33
|
+
OPTIMIZE_IMPORTS = "optimize_imports"
|
|
34
|
+
|
|
35
|
+
class TechnicalDebtType(Enum):
|
|
36
|
+
"""Categories of technical debt."""
|
|
37
|
+
CODE_COMPLEXITY = "code_complexity"
|
|
38
|
+
DUPLICATION = "duplication"
|
|
39
|
+
LONG_METHODS = "long_methods"
|
|
40
|
+
LARGE_CLASSES = "large_classes"
|
|
41
|
+
DEEP_NESTING = "deep_nesting"
|
|
42
|
+
POOR_NAMING = "poor_naming"
|
|
43
|
+
MISSING_TESTS = "missing_tests"
|
|
44
|
+
SECURITY_ISSUES = "security_issues"
|
|
45
|
+
PERFORMANCE_ISSUES = "performance_issues"
|
|
46
|
+
DOCUMENTATION_DEBT = "documentation_debt"
|
|
47
|
+
|
|
48
|
+
@dataclass
|
|
49
|
+
class TechnicalDebtItem:
|
|
50
|
+
"""Individual technical debt item with metrics."""
|
|
51
|
+
type: TechnicalDebtType
|
|
52
|
+
file_path: str
|
|
53
|
+
line_number: int
|
|
54
|
+
severity: str # "low", "medium", "high", "critical"
|
|
55
|
+
description: str
|
|
56
|
+
impact: str # "maintainability", "readability", "performance", "security"
|
|
57
|
+
estimated_effort: str # "minutes", "hours", "days"
|
|
58
|
+
code_snippet: str
|
|
59
|
+
suggested_fix: str
|
|
60
|
+
dependencies: List[str]
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
class RefactorOpportunity:
|
|
64
|
+
"""Potential refactoring opportunity with analysis."""
|
|
65
|
+
type: RefactorType
|
|
66
|
+
file_path: str
|
|
67
|
+
line_range: Tuple[int, int]
|
|
68
|
+
confidence: float
|
|
69
|
+
complexity_reduction: float
|
|
70
|
+
risk_level: str # "low", "medium", "high"
|
|
71
|
+
description: str
|
|
72
|
+
before_code: str
|
|
73
|
+
after_code: str
|
|
74
|
+
technical_debt_addresses: List[TechnicalDebtType]
|
|
75
|
+
|
|
76
|
+
@dataclass
|
|
77
|
+
class RefactorPlan:
|
|
78
|
+
"""Comprehensive refactoring plan with execution strategy."""
|
|
79
|
+
opportunities: List[RefactorOpportunity]
|
|
80
|
+
technical_debt_items: List[TechnicalDebtItem]
|
|
81
|
+
execution_order: List[int] # Indices of opportunities in execution order
|
|
82
|
+
estimated_time: str
|
|
83
|
+
risk_assessment: str
|
|
84
|
+
prerequisites: List[str]
|
|
85
|
+
rollback_strategy: str
|
|
86
|
+
|
|
87
|
+
class TechnicalDebtAnalyzer:
|
|
88
|
+
"""Analyzes codebase for technical debt patterns."""
|
|
89
|
+
|
|
90
|
+
def __init__(self):
|
|
91
|
+
self.debt_patterns = self._load_debt_patterns()
|
|
92
|
+
self.complexity_metrics = {}
|
|
93
|
+
|
|
94
|
+
def _load_debt_patterns(self) -> Dict[str, Any]:
|
|
95
|
+
"""Load technical debt detection patterns."""
|
|
96
|
+
return {
|
|
97
|
+
TechnicalDebtType.CODE_COMPLEXITY: {
|
|
98
|
+
'thresholds': {
|
|
99
|
+
'cyclomatic_complexity': 10,
|
|
100
|
+
'cognitive_complexity': 15,
|
|
101
|
+
'nesting_depth': 4
|
|
102
|
+
},
|
|
103
|
+
'indicators': [
|
|
104
|
+
'high_cyclomatic_complexity',
|
|
105
|
+
'deep_nesting',
|
|
106
|
+
'multiple_responsibilities'
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
TechnicalDebtType.DUPLICATION: {
|
|
110
|
+
'thresholds': {
|
|
111
|
+
'similarity_threshold': 0.8,
|
|
112
|
+
'min_lines': 5
|
|
113
|
+
},
|
|
114
|
+
'indicators': [
|
|
115
|
+
'similar_code_blocks',
|
|
116
|
+
'repeated_patterns',
|
|
117
|
+
'copied_pasted_code'
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
TechnicalDebtType.LONG_METHODS: {
|
|
121
|
+
'thresholds': {
|
|
122
|
+
'max_lines': 50,
|
|
123
|
+
'max_parameters': 7
|
|
124
|
+
},
|
|
125
|
+
'indicators': [
|
|
126
|
+
'excessive_length',
|
|
127
|
+
'too_many_parameters',
|
|
128
|
+
'multiple_responsibilities'
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
TechnicalDebtType.POOR_NAMING: {
|
|
132
|
+
'patterns': [
|
|
133
|
+
r'^[a-z]$',
|
|
134
|
+
r'^[a-z]{1,2}$',
|
|
135
|
+
r'^[A-Z]+_[A-Z_]+$',
|
|
136
|
+
r'^temp.*',
|
|
137
|
+
r'^tmp.*'
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async def analyze(self, codebase_path: str) -> List[TechnicalDebtItem]:
|
|
143
|
+
"""Analyze codebase for technical debt."""
|
|
144
|
+
|
|
145
|
+
debt_items = []
|
|
146
|
+
|
|
147
|
+
# Find all Python files
|
|
148
|
+
python_files = self._find_python_files(codebase_path)
|
|
149
|
+
|
|
150
|
+
for file_path in python_files:
|
|
151
|
+
file_debt = await self._analyze_file(file_path)
|
|
152
|
+
debt_items.extend(file_debt)
|
|
153
|
+
|
|
154
|
+
# Cross-file analysis for duplication
|
|
155
|
+
duplication_debt = await self._analyze_duplication(python_files)
|
|
156
|
+
debt_items.extend(duplication_debt)
|
|
157
|
+
|
|
158
|
+
return self._prioritize_debt_items(debt_items)
|
|
159
|
+
|
|
160
|
+
def _find_python_files(self, codebase_path: str) -> List[str]:
|
|
161
|
+
"""Find all Python files in codebase."""
|
|
162
|
+
import os
|
|
163
|
+
python_files = []
|
|
164
|
+
|
|
165
|
+
for root, dirs, files in os.walk(codebase_path):
|
|
166
|
+
# Skip common non-source directories
|
|
167
|
+
dirs[:] = [d for d in dirs if d not in ['__pycache__', '.git', 'venv', 'node_modules']]
|
|
168
|
+
|
|
169
|
+
for file in files:
|
|
170
|
+
if file.endswith('.py'):
|
|
171
|
+
python_files.append(os.path.join(root, file))
|
|
172
|
+
|
|
173
|
+
return python_files
|
|
174
|
+
|
|
175
|
+
async def _analyze_file(self, file_path: str) -> List[TechnicalDebtItem]:
|
|
176
|
+
"""Analyze individual file for technical debt."""
|
|
177
|
+
|
|
178
|
+
debt_items = []
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
182
|
+
content = f.read()
|
|
183
|
+
|
|
184
|
+
# Parse AST
|
|
185
|
+
tree = ast.parse(content)
|
|
186
|
+
|
|
187
|
+
# Analyze complexity
|
|
188
|
+
complexity_debt = self._analyze_complexity(tree, file_path, content)
|
|
189
|
+
debt_items.extend(complexity_debt)
|
|
190
|
+
|
|
191
|
+
# Analyze method length
|
|
192
|
+
length_debt = self._analyze_method_length(tree, file_path, content)
|
|
193
|
+
debt_items.extend(length_debt)
|
|
194
|
+
|
|
195
|
+
# Analyze naming
|
|
196
|
+
naming_debt = self._analyze_naming(tree, file_path, content)
|
|
197
|
+
debt_items.extend(naming_debt)
|
|
198
|
+
|
|
199
|
+
except Exception as e:
|
|
200
|
+
print(f"Error analyzing {file_path}: {e}")
|
|
201
|
+
|
|
202
|
+
return debt_items
|
|
203
|
+
|
|
204
|
+
def _analyze_complexity(
|
|
205
|
+
self, tree: ast.AST, file_path: str, content: str
|
|
206
|
+
) -> List[TechnicalDebtItem]:
|
|
207
|
+
"""Analyze cyclomatic and cognitive complexity."""
|
|
208
|
+
|
|
209
|
+
debt_items = []
|
|
210
|
+
lines = content.split('\n')
|
|
211
|
+
|
|
212
|
+
class ComplexityVisitor(ast.NodeVisitor):
|
|
213
|
+
def __init__(self):
|
|
214
|
+
self.complexities = {}
|
|
215
|
+
self.nesting_depths = {}
|
|
216
|
+
self.current_depth = 0
|
|
217
|
+
|
|
218
|
+
def visit_FunctionDef(self, node):
|
|
219
|
+
# Calculate cyclomatic complexity
|
|
220
|
+
complexity = 1 # Base complexity
|
|
221
|
+
for child in ast.walk(node):
|
|
222
|
+
if isinstance(child, (ast.If, ast.While, ast.For, ast.AsyncFor)):
|
|
223
|
+
complexity += 1
|
|
224
|
+
elif isinstance(child, ast.ExceptHandler):
|
|
225
|
+
complexity += 1
|
|
226
|
+
elif isinstance(child, ast.With, ast.AsyncWith):
|
|
227
|
+
complexity += 1
|
|
228
|
+
elif isinstance(child, ast.BoolOp):
|
|
229
|
+
complexity += len(child.values) - 1
|
|
230
|
+
|
|
231
|
+
# Calculate maximum nesting depth
|
|
232
|
+
self.current_depth = 0
|
|
233
|
+
max_depth = self._calculate_nesting_depth(node)
|
|
234
|
+
|
|
235
|
+
self.complexities[node.name] = {
|
|
236
|
+
'complexity': complexity,
|
|
237
|
+
'line': node.lineno,
|
|
238
|
+
'max_depth': max_depth
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
self.generic_visit(node)
|
|
242
|
+
|
|
243
|
+
def _calculate_nesting_depth(self, node, current_depth=0):
|
|
244
|
+
"""Calculate maximum nesting depth."""
|
|
245
|
+
max_depth = current_depth
|
|
246
|
+
|
|
247
|
+
for child in ast.walk(node):
|
|
248
|
+
if isinstance(child, (ast.If, ast.While, ast.For, ast.AsyncFor,
|
|
249
|
+
ast.With, ast.AsyncWith, ast.Try)):
|
|
250
|
+
child_depth = self._calculate_nesting_depth(child, current_depth + 1)
|
|
251
|
+
max_depth = max(max_depth, child_depth)
|
|
252
|
+
|
|
253
|
+
return max_depth
|
|
254
|
+
|
|
255
|
+
visitor = ComplexityVisitor()
|
|
256
|
+
visitor.visit(tree)
|
|
257
|
+
|
|
258
|
+
# Create debt items for high complexity
|
|
259
|
+
for func_name, metrics in visitor.complexities.items():
|
|
260
|
+
if metrics['complexity'] > 10: # Cyclomatic complexity threshold
|
|
261
|
+
debt_item = TechnicalDebtItem(
|
|
262
|
+
type=TechnicalDebtType.CODE_COMPLEXITY,
|
|
263
|
+
file_path=file_path,
|
|
264
|
+
line_number=metrics['line'],
|
|
265
|
+
severity=self._assess_complexity_severity(metrics['complexity']),
|
|
266
|
+
description=f"Function '{func_name}' has high cyclomatic complexity: {metrics['complexity']}",
|
|
267
|
+
impact="maintainability",
|
|
268
|
+
estimated_effort="hours",
|
|
269
|
+
code_snippet=lines[metrics['line'] - 1] if metrics['line'] <= len(lines) else "",
|
|
270
|
+
suggested_fix=f"Consider extracting sub-functions or simplifying logic in '{func_name}'",
|
|
271
|
+
dependencies=["unit_tests"]
|
|
272
|
+
)
|
|
273
|
+
debt_items.append(debt_item)
|
|
274
|
+
|
|
275
|
+
if metrics['max_depth'] > 4: # Nesting depth threshold
|
|
276
|
+
debt_item = TechnicalDebtItem(
|
|
277
|
+
type=TechnicalDebtType.DEEP_NESTING,
|
|
278
|
+
file_path=file_path,
|
|
279
|
+
line_number=metrics['line'],
|
|
280
|
+
severity=self._assess_nesting_severity(metrics['max_depth']),
|
|
281
|
+
description=f"Function '{func_name}' has deep nesting: {metrics['max_depth']} levels",
|
|
282
|
+
impact="readability",
|
|
283
|
+
estimated_effort="minutes",
|
|
284
|
+
code_snippet=lines[metrics['line'] - 1] if metrics['line'] <= len(lines) else "",
|
|
285
|
+
suggested_fix=f"Consider using early returns or guard clauses in '{func_name}'",
|
|
286
|
+
dependencies=[]
|
|
287
|
+
)
|
|
288
|
+
debt_items.append(debt_item)
|
|
289
|
+
|
|
290
|
+
return debt_items
|
|
291
|
+
|
|
292
|
+
def _analyze_method_length(
|
|
293
|
+
self, tree: ast.AST, file_path: str, content: str
|
|
294
|
+
) -> List[TechnicalDebtItem]:
|
|
295
|
+
"""Analyze method length violations."""
|
|
296
|
+
|
|
297
|
+
debt_items = []
|
|
298
|
+
lines = content.split('\n')
|
|
299
|
+
|
|
300
|
+
class MethodLengthVisitor(ast.NodeVisitor):
|
|
301
|
+
def __init__(self):
|
|
302
|
+
self.methods = []
|
|
303
|
+
|
|
304
|
+
def visit_FunctionDef(self, node):
|
|
305
|
+
# Calculate method length (excluding docstrings and comments)
|
|
306
|
+
start_line = node.lineno
|
|
307
|
+
|
|
308
|
+
# Find end of function
|
|
309
|
+
end_line = start_line
|
|
310
|
+
for child in ast.walk(node):
|
|
311
|
+
if hasattr(child, 'lineno') and child.lineno > end_line:
|
|
312
|
+
end_line = child.lineno
|
|
313
|
+
|
|
314
|
+
# Count non-empty, non-comment lines
|
|
315
|
+
method_lines = []
|
|
316
|
+
for i in range(start_line - 1, min(end_line, len(lines))):
|
|
317
|
+
line = lines[i].strip()
|
|
318
|
+
if line and not line.startswith('#') and not line.startswith('"""') and not line.startswith("'''"):
|
|
319
|
+
method_lines.append(line)
|
|
320
|
+
|
|
321
|
+
length = len(method_lines)
|
|
322
|
+
param_count = len(node.args.args)
|
|
323
|
+
|
|
324
|
+
self.methods.append({
|
|
325
|
+
'name': node.name,
|
|
326
|
+
'line': start_line,
|
|
327
|
+
'length': length,
|
|
328
|
+
'param_count': param_count
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
self.generic_visit(node)
|
|
332
|
+
|
|
333
|
+
visitor = MethodLengthVisitor()
|
|
334
|
+
visitor.visit(tree)
|
|
335
|
+
|
|
336
|
+
# Create debt items for long methods
|
|
337
|
+
for method in visitor.methods:
|
|
338
|
+
if method['length'] > 50: # Lines threshold
|
|
339
|
+
debt_item = TechnicalDebtItem(
|
|
340
|
+
type=TechnicalDebtType.LONG_METHODS,
|
|
341
|
+
file_path=file_path,
|
|
342
|
+
line_number=method['line'],
|
|
343
|
+
severity=self._assess_length_severity(method['length']),
|
|
344
|
+
description=f"Method '{method['name']}' is too long: {method['length']} lines",
|
|
345
|
+
impact="maintainability",
|
|
346
|
+
estimated_effort="hours",
|
|
347
|
+
code_snippet=lines[method['line'] - 1] if method['line'] <= len(lines) else "",
|
|
348
|
+
suggested_fix=f"Consider extracting smaller methods from '{method['name']}'",
|
|
349
|
+
dependencies=["unit_tests"]
|
|
350
|
+
)
|
|
351
|
+
debt_items.append(debt_item)
|
|
352
|
+
|
|
353
|
+
if method['param_count'] > 7: # Parameters threshold
|
|
354
|
+
debt_item = TechnicalDebtItem(
|
|
355
|
+
type=TechnicalDebtType.LARGE_CLASSES, # Could also be its own type
|
|
356
|
+
file_path=file_path,
|
|
357
|
+
line_number=method['line'],
|
|
358
|
+
severity="medium",
|
|
359
|
+
description=f"Method '{method['name']}' has too many parameters: {method['param_count']}",
|
|
360
|
+
impact="readability",
|
|
361
|
+
estimated_effort="minutes",
|
|
362
|
+
code_snippet=lines[method['line'] - 1] if method['line'] <= len(lines) else "",
|
|
363
|
+
suggested_fix=f"Consider using parameter objects or configuration dictionaries",
|
|
364
|
+
dependencies=[]
|
|
365
|
+
)
|
|
366
|
+
debt_items.append(debt_item)
|
|
367
|
+
|
|
368
|
+
return debt_items
|
|
369
|
+
|
|
370
|
+
def _analyze_naming(
|
|
371
|
+
self, tree: ast.AST, file_path: str, content: str
|
|
372
|
+
) -> List[TechnicalDebtItem]:
|
|
373
|
+
"""Analyze naming convention violations."""
|
|
374
|
+
|
|
375
|
+
debt_items = []
|
|
376
|
+
lines = content.split('\n')
|
|
377
|
+
patterns = self.debt_patterns[TechnicalDebtType.POOR_NAMING]['patterns']
|
|
378
|
+
|
|
379
|
+
class NamingVisitor(ast.NodeVisitor):
|
|
380
|
+
def __init__(self):
|
|
381
|
+
self.variables = []
|
|
382
|
+
self.functions = []
|
|
383
|
+
self.classes = []
|
|
384
|
+
|
|
385
|
+
def visit_Name(self, node):
|
|
386
|
+
if isinstance(node.ctx, ast.Store):
|
|
387
|
+
self.variables.append({
|
|
388
|
+
'name': node.id,
|
|
389
|
+
'line': node.lineno
|
|
390
|
+
})
|
|
391
|
+
self.generic_visit(node)
|
|
392
|
+
|
|
393
|
+
def visit_FunctionDef(self, node):
|
|
394
|
+
self.functions.append({
|
|
395
|
+
'name': node.name,
|
|
396
|
+
'line': node.lineno
|
|
397
|
+
})
|
|
398
|
+
self.generic_visit(node)
|
|
399
|
+
|
|
400
|
+
def visit_ClassDef(self, node):
|
|
401
|
+
self.classes.append({
|
|
402
|
+
'name': node.name,
|
|
403
|
+
'line': node.lineno
|
|
404
|
+
})
|
|
405
|
+
self.generic_visit(node)
|
|
406
|
+
|
|
407
|
+
visitor = NamingVisitor()
|
|
408
|
+
visitor.visit(tree)
|
|
409
|
+
|
|
410
|
+
import re
|
|
411
|
+
|
|
412
|
+
# Check variable names
|
|
413
|
+
for var in visitor.variables:
|
|
414
|
+
for pattern in patterns:
|
|
415
|
+
if re.match(pattern, var['name']):
|
|
416
|
+
debt_item = TechnicalDebtItem(
|
|
417
|
+
type=TechnicalDebtType.POOR_NAMING,
|
|
418
|
+
file_path=file_path,
|
|
419
|
+
line_number=var['line'],
|
|
420
|
+
severity="low",
|
|
421
|
+
description=f"Variable '{var['name']}' has poor naming pattern",
|
|
422
|
+
impact="readability",
|
|
423
|
+
estimated_effort="minutes",
|
|
424
|
+
code_snippet=lines[var['line'] - 1] if var['line'] <= len(lines) else "",
|
|
425
|
+
suggested_fix=f"Rename '{var['name']}' to something more descriptive",
|
|
426
|
+
dependencies=[]
|
|
427
|
+
)
|
|
428
|
+
debt_items.append(debt_item)
|
|
429
|
+
|
|
430
|
+
return debt_items
|
|
431
|
+
|
|
432
|
+
async def _analyze_duplication(
|
|
433
|
+
self, python_files: List[str]
|
|
434
|
+
) -> List[TechnicalDebtItem]:
|
|
435
|
+
"""Analyze code duplication across files."""
|
|
436
|
+
|
|
437
|
+
debt_items = []
|
|
438
|
+
code_blocks = {}
|
|
439
|
+
|
|
440
|
+
# Extract code blocks from all files
|
|
441
|
+
for file_path in python_files:
|
|
442
|
+
try:
|
|
443
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
444
|
+
content = f.read()
|
|
445
|
+
|
|
446
|
+
# Split into logical blocks (functions, classes, etc.)
|
|
447
|
+
tree = ast.parse(content)
|
|
448
|
+
blocks = self._extract_code_blocks(tree, content)
|
|
449
|
+
|
|
450
|
+
for block in blocks:
|
|
451
|
+
block_hash = hash(block['content'])
|
|
452
|
+
if block_hash not in code_blocks:
|
|
453
|
+
code_blocks[block_hash] = []
|
|
454
|
+
code_blocks[block_hash].append({
|
|
455
|
+
'file': file_path,
|
|
456
|
+
'line': block['line'],
|
|
457
|
+
'content': block['content']
|
|
458
|
+
})
|
|
459
|
+
|
|
460
|
+
except Exception as e:
|
|
461
|
+
print(f"Error analyzing duplication in {file_path}: {e}")
|
|
462
|
+
|
|
463
|
+
# Find duplicated blocks
|
|
464
|
+
for block_hash, occurrences in code_blocks.items():
|
|
465
|
+
if len(occurrences) > 1:
|
|
466
|
+
# This is duplicated code
|
|
467
|
+
for occ in occurrences:
|
|
468
|
+
debt_item = TechnicalDebtItem(
|
|
469
|
+
type=TechnicalDebtType.DUPLICATION,
|
|
470
|
+
file_path=occ['file'],
|
|
471
|
+
line_number=occ['line'],
|
|
472
|
+
severity="medium",
|
|
473
|
+
description=f"Code block duplicated in {len(occurrences)} locations",
|
|
474
|
+
impact="maintainability",
|
|
475
|
+
estimated_effort="hours",
|
|
476
|
+
code_snippet=occ['content'][:100] + "..." if len(occ['content']) > 100 else occ['content'],
|
|
477
|
+
suggested_fix="Extract duplicated code into a shared function or method",
|
|
478
|
+
dependencies=["unit_tests"]
|
|
479
|
+
)
|
|
480
|
+
debt_items.append(debt_item)
|
|
481
|
+
|
|
482
|
+
return debt_items
|
|
483
|
+
|
|
484
|
+
def _extract_code_blocks(
|
|
485
|
+
self, tree: ast.AST, content: str
|
|
486
|
+
) -> List[Dict[str, Any]]:
|
|
487
|
+
"""Extract logical code blocks from AST."""
|
|
488
|
+
|
|
489
|
+
blocks = []
|
|
490
|
+
lines = content.split('\n')
|
|
491
|
+
|
|
492
|
+
class BlockExtractor(ast.NodeVisitor):
|
|
493
|
+
def visit_FunctionDef(self, node):
|
|
494
|
+
# Extract function content
|
|
495
|
+
start_line = node.lineno
|
|
496
|
+
end_line = start_line
|
|
497
|
+
for child in ast.walk(node):
|
|
498
|
+
if hasattr(child, 'lineno') and child.lineno > end_line:
|
|
499
|
+
end_line = child.lineno
|
|
500
|
+
|
|
501
|
+
if start_line <= len(lines) and end_line <= len(lines):
|
|
502
|
+
block_content = '\n'.join(lines[start_line - 1:end_line])
|
|
503
|
+
blocks.append({
|
|
504
|
+
'type': 'function',
|
|
505
|
+
'name': node.name,
|
|
506
|
+
'line': start_line,
|
|
507
|
+
'content': block_content
|
|
508
|
+
})
|
|
509
|
+
|
|
510
|
+
self.generic_visit(node)
|
|
511
|
+
|
|
512
|
+
def visit_ClassDef(self, node):
|
|
513
|
+
# Extract class content
|
|
514
|
+
start_line = node.lineno
|
|
515
|
+
end_line = start_line
|
|
516
|
+
for child in ast.walk(node):
|
|
517
|
+
if hasattr(child, 'lineno') and child.lineno > end_line:
|
|
518
|
+
end_line = child.lineno
|
|
519
|
+
|
|
520
|
+
if start_line <= len(lines) and end_line <= len(lines):
|
|
521
|
+
block_content = '\n'.join(lines[start_line - 1:end_line])
|
|
522
|
+
blocks.append({
|
|
523
|
+
'type': 'class',
|
|
524
|
+
'name': node.name,
|
|
525
|
+
'line': start_line,
|
|
526
|
+
'content': block_content
|
|
527
|
+
})
|
|
528
|
+
|
|
529
|
+
self.generic_visit(node)
|
|
530
|
+
|
|
531
|
+
extractor = BlockExtractor()
|
|
532
|
+
extractor.visit(tree)
|
|
533
|
+
|
|
534
|
+
return blocks
|
|
535
|
+
|
|
536
|
+
def _prioritize_debt_items(
|
|
537
|
+
self, debt_items: List[TechnicalDebtItem]
|
|
538
|
+
) -> List[TechnicalDebtItem]:
|
|
539
|
+
"""Prioritize technical debt items by severity and impact."""
|
|
540
|
+
|
|
541
|
+
# Sort by severity (critical > high > medium > low) and impact
|
|
542
|
+
severity_order = {'critical': 4, 'high': 3, 'medium': 2, 'low': 1}
|
|
543
|
+
impact_order = {'security': 4, 'performance': 3, 'maintainability': 2, 'readability': 1}
|
|
544
|
+
|
|
545
|
+
return sorted(
|
|
546
|
+
debt_items,
|
|
547
|
+
key=lambda x: (
|
|
548
|
+
severity_order.get(x.severity, 0),
|
|
549
|
+
impact_order.get(x.impact, 0)
|
|
550
|
+
),
|
|
551
|
+
reverse=True
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
def _assess_complexity_severity(self, complexity: int) -> str:
|
|
555
|
+
"""Assess severity based on cyclomatic complexity."""
|
|
556
|
+
if complexity >= 20:
|
|
557
|
+
return "critical"
|
|
558
|
+
elif complexity >= 15:
|
|
559
|
+
return "high"
|
|
560
|
+
elif complexity >= 10:
|
|
561
|
+
return "medium"
|
|
562
|
+
else:
|
|
563
|
+
return "low"
|
|
564
|
+
|
|
565
|
+
def _assess_nesting_severity(self, depth: int) -> str:
|
|
566
|
+
"""Assess severity based on nesting depth."""
|
|
567
|
+
if depth >= 6:
|
|
568
|
+
return "critical"
|
|
569
|
+
elif depth >= 5:
|
|
570
|
+
return "high"
|
|
571
|
+
elif depth >= 4:
|
|
572
|
+
return "medium"
|
|
573
|
+
else:
|
|
574
|
+
return "low"
|
|
575
|
+
|
|
576
|
+
def _assess_length_severity(self, length: int) -> str:
|
|
577
|
+
"""Assess severity based on method length."""
|
|
578
|
+
if length >= 100:
|
|
579
|
+
return "critical"
|
|
580
|
+
elif length >= 75:
|
|
581
|
+
return "high"
|
|
582
|
+
elif length >= 50:
|
|
583
|
+
return "medium"
|
|
584
|
+
else:
|
|
585
|
+
return "low"
|
|
586
|
+
|
|
587
|
+
class AIRefactorer:
|
|
588
|
+
"""AI-powered refactoring with technical debt management."""
|
|
589
|
+
|
|
590
|
+
def __init__(self, context7_client=None):
|
|
591
|
+
self.context7 = context7_client
|
|
592
|
+
self.technical_debt_analyzer = TechnicalDebtAnalyzer()
|
|
593
|
+
self.rope_project = None
|
|
594
|
+
|
|
595
|
+
async def refactor_with_intelligence(
|
|
596
|
+
self, codebase_path: str, refactor_options: Dict = None
|
|
597
|
+
) -> RefactorPlan:
|
|
598
|
+
"""AI-driven code transformation with technical debt quantification."""
|
|
599
|
+
|
|
600
|
+
# Initialize Rope project
|
|
601
|
+
self.rope_project = rope.base.project.Project(codebase_path)
|
|
602
|
+
|
|
603
|
+
# Analyze technical debt
|
|
604
|
+
debt_analysis = await self.technical_debt_analyzer.analyze(codebase_path)
|
|
605
|
+
|
|
606
|
+
# Get Context7 refactoring patterns
|
|
607
|
+
context7_patterns = {}
|
|
608
|
+
if self.context7:
|
|
609
|
+
context7_patterns = await self._get_context7_refactoring_patterns()
|
|
610
|
+
|
|
611
|
+
# AI analysis of refactoring opportunities
|
|
612
|
+
refactor_opportunities = await self._identify_refactor_opportunities(
|
|
613
|
+
codebase_path, debt_analysis, context7_patterns
|
|
614
|
+
)
|
|
615
|
+
|
|
616
|
+
# Generate safe refactor plan using Rope + AI
|
|
617
|
+
refactor_plan = self._create_safe_refactor_plan(
|
|
618
|
+
refactor_opportunities, debt_analysis, context7_patterns
|
|
619
|
+
)
|
|
620
|
+
|
|
621
|
+
return refactor_plan
|
|
622
|
+
|
|
623
|
+
async def _get_context7_refactoring_patterns(self) -> Dict[str, Any]:
|
|
624
|
+
"""Get latest refactoring patterns from Context7."""
|
|
625
|
+
|
|
626
|
+
patterns = {}
|
|
627
|
+
if self.context7:
|
|
628
|
+
try:
|
|
629
|
+
# Rope patterns
|
|
630
|
+
rope_patterns = await self.context7.get_library_docs(
|
|
631
|
+
context7_library_id="/python-rope/rope",
|
|
632
|
+
topic="safe refactoring patterns technical debt 2025",
|
|
633
|
+
tokens=4000
|
|
634
|
+
)
|
|
635
|
+
patterns['rope'] = rope_patterns
|
|
636
|
+
|
|
637
|
+
# General refactoring best practices
|
|
638
|
+
refactoring_patterns = await self.context7.get_library_docs(
|
|
639
|
+
context7_library_id="/refactoring/guru",
|
|
640
|
+
topic="code refactoring best practices design patterns 2025",
|
|
641
|
+
tokens=3000
|
|
642
|
+
)
|
|
643
|
+
patterns['general'] = refactoring_patterns
|
|
644
|
+
|
|
645
|
+
except Exception as e:
|
|
646
|
+
print(f"Failed to get Context7 patterns: {e}")
|
|
647
|
+
|
|
648
|
+
return patterns
|
|
649
|
+
|
|
650
|
+
async def _identify_refactor_opportunities(
|
|
651
|
+
self, codebase_path: str, debt_items: List[TechnicalDebtItem],
|
|
652
|
+
context7_patterns: Dict[str, Any]
|
|
653
|
+
) -> List[RefactorOpportunity]:
|
|
654
|
+
"""Identify refactoring opportunities using AI analysis."""
|
|
655
|
+
|
|
656
|
+
opportunities = []
|
|
657
|
+
|
|
658
|
+
# Group debt items by file
|
|
659
|
+
debt_by_file = {}
|
|
660
|
+
for item in debt_items:
|
|
661
|
+
if item.file_path not in debt_by_file:
|
|
662
|
+
debt_by_file[item.file_path] = []
|
|
663
|
+
debt_by_file[item.file_path].append(item)
|
|
664
|
+
|
|
665
|
+
# Analyze each file for refactoring opportunities
|
|
666
|
+
for file_path, file_debt in debt_by_file.items():
|
|
667
|
+
file_opportunities = await self._analyze_file_for_refactoring(
|
|
668
|
+
file_path, file_debt, context7_patterns
|
|
669
|
+
)
|
|
670
|
+
opportunities.extend(file_opportunities)
|
|
671
|
+
|
|
672
|
+
# Sort by confidence and complexity reduction
|
|
673
|
+
opportunities.sort(
|
|
674
|
+
key=lambda x: (x.confidence, x.complexity_reduction),
|
|
675
|
+
reverse=True
|
|
676
|
+
)
|
|
677
|
+
|
|
678
|
+
return opportunities
|
|
679
|
+
|
|
680
|
+
async def _analyze_file_for_refactoring(
|
|
681
|
+
self, file_path: str, debt_items: List[TechnicalDebtItem],
|
|
682
|
+
context7_patterns: Dict[str, Any]
|
|
683
|
+
) -> List[RefactorOpportunity]:
|
|
684
|
+
"""Analyze specific file for refactoring opportunities."""
|
|
685
|
+
|
|
686
|
+
opportunities = []
|
|
687
|
+
|
|
688
|
+
try:
|
|
689
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
690
|
+
content = f.read()
|
|
691
|
+
|
|
692
|
+
tree = ast.parse(content)
|
|
693
|
+
|
|
694
|
+
# Extract method opportunities
|
|
695
|
+
method_opportunities = self._identify_method_refactoring(
|
|
696
|
+
tree, file_path, debt_items, content
|
|
697
|
+
)
|
|
698
|
+
opportunities.extend(method_opportunities)
|
|
699
|
+
|
|
700
|
+
# Extract variable opportunities
|
|
701
|
+
variable_opportunities = self._identify_variable_refactoring(
|
|
702
|
+
tree, file_path, content
|
|
703
|
+
)
|
|
704
|
+
opportunities.extend(variable_opportunities)
|
|
705
|
+
|
|
706
|
+
# Extract import opportunities
|
|
707
|
+
import_opportunities = self._identify_import_refactoring(
|
|
708
|
+
tree, file_path, content
|
|
709
|
+
)
|
|
710
|
+
opportunities.extend(import_opportunities)
|
|
711
|
+
|
|
712
|
+
except Exception as e:
|
|
713
|
+
print(f"Error analyzing file {file_path}: {e}")
|
|
714
|
+
|
|
715
|
+
return opportunities
|
|
716
|
+
|
|
717
|
+
def _identify_method_refactoring(
|
|
718
|
+
self, tree: ast.AST, file_path: str, debt_items: List[TechnicalDebtItem],
|
|
719
|
+
content: str
|
|
720
|
+
) -> List[RefactorOpportunity]:
|
|
721
|
+
"""Identify method-level refactoring opportunities."""
|
|
722
|
+
|
|
723
|
+
opportunities = []
|
|
724
|
+
lines = content.split('\n')
|
|
725
|
+
|
|
726
|
+
class MethodAnalyzer(ast.NodeVisitor):
|
|
727
|
+
def __init__(self):
|
|
728
|
+
self.methods = []
|
|
729
|
+
self.current_class = None
|
|
730
|
+
|
|
731
|
+
def visit_ClassDef(self, node):
|
|
732
|
+
self.current_class = node.name
|
|
733
|
+
self.generic_visit(node)
|
|
734
|
+
self.current_class = None
|
|
735
|
+
|
|
736
|
+
def visit_FunctionDef(self, node):
|
|
737
|
+
# Calculate method metrics
|
|
738
|
+
start_line = node.lineno
|
|
739
|
+
end_line = start_line
|
|
740
|
+
|
|
741
|
+
for child in ast.walk(node):
|
|
742
|
+
if hasattr(child, 'lineno') and child.lineno > end_line:
|
|
743
|
+
end_line = child.lineno
|
|
744
|
+
|
|
745
|
+
method_lines = lines[start_line - 1:end_line]
|
|
746
|
+
method_content = '\n'.join(method_lines)
|
|
747
|
+
|
|
748
|
+
# Calculate complexity
|
|
749
|
+
complexity = 1 # Base complexity
|
|
750
|
+
for child in ast.walk(node):
|
|
751
|
+
if isinstance(child, (ast.If, ast.While, ast.For, ast.AsyncFor)):
|
|
752
|
+
complexity += 1
|
|
753
|
+
elif isinstance(child, ast.ExceptHandler):
|
|
754
|
+
complexity += 1
|
|
755
|
+
|
|
756
|
+
self.methods.append({
|
|
757
|
+
'name': node.name,
|
|
758
|
+
'class': self.current_class,
|
|
759
|
+
'line': start_line,
|
|
760
|
+
'end_line': end_line,
|
|
761
|
+
'content': method_content,
|
|
762
|
+
'complexity': complexity,
|
|
763
|
+
'param_count': len(node.args.args),
|
|
764
|
+
'lines_count': len([l for l in method_lines if l.strip() and not l.strip().startswith('#')])
|
|
765
|
+
})
|
|
766
|
+
|
|
767
|
+
self.generic_visit(node)
|
|
768
|
+
|
|
769
|
+
analyzer = MethodAnalyzer()
|
|
770
|
+
analyzer.visit(tree)
|
|
771
|
+
|
|
772
|
+
# Generate refactoring opportunities
|
|
773
|
+
for method in analyzer.methods:
|
|
774
|
+
# Extract method opportunity
|
|
775
|
+
if method['lines_count'] > 30 or method['complexity'] > 8:
|
|
776
|
+
opportunity = RefactorOpportunity(
|
|
777
|
+
type=RefactorType.EXTRACT_METHOD,
|
|
778
|
+
file_path=file_path,
|
|
779
|
+
line_range=(method['line'], method['end_line']),
|
|
780
|
+
confidence=min(0.9, method['complexity'] / 10),
|
|
781
|
+
complexity_reduction=max(0.3, method['complexity'] / 20),
|
|
782
|
+
risk_level="medium" if method['complexity'] > 15 else "low",
|
|
783
|
+
description=f"Extract parts of method '{method['name']}' to reduce complexity",
|
|
784
|
+
before_code=method['content'][:200] + "..." if len(method['content']) > 200 else method['content'],
|
|
785
|
+
after_code="# Extracted sub-method calls would go here",
|
|
786
|
+
technical_debt_addresses=[TechnicalDebtType.CODE_COMPLEXITY, TechnicalDebtType.LONG_METHODS]
|
|
787
|
+
)
|
|
788
|
+
opportunities.append(opportunity)
|
|
789
|
+
|
|
790
|
+
# Extract variable opportunities for complex expressions
|
|
791
|
+
if self._has_complex_expressions(method['content']):
|
|
792
|
+
opportunity = RefactorOpportunity(
|
|
793
|
+
type=RefactorType.EXTRACT_VARIABLE,
|
|
794
|
+
file_path=file_path,
|
|
795
|
+
line_range=(method['line'], method['end_line']),
|
|
796
|
+
confidence=0.7,
|
|
797
|
+
complexity_reduction=0.2,
|
|
798
|
+
risk_level="low",
|
|
799
|
+
description=f"Extract complex expressions in method '{method['name']}' to variables",
|
|
800
|
+
before_code=method['content'][:200] + "..." if len(method['content']) > 200 else method['content'],
|
|
801
|
+
after_code="# Extracted variables would improve readability",
|
|
802
|
+
technical_debt_addresses=[TechnicalDebtType.CODE_COMPLEXITY]
|
|
803
|
+
)
|
|
804
|
+
opportunities.append(opportunity)
|
|
805
|
+
|
|
806
|
+
return opportunities
|
|
807
|
+
|
|
808
|
+
def _identify_variable_refactoring(
|
|
809
|
+
self, tree: ast.AST, file_path: str, content: str
|
|
810
|
+
) -> List[RefactorOpportunity]:
|
|
811
|
+
"""Identify variable-level refactoring opportunities."""
|
|
812
|
+
|
|
813
|
+
opportunities = []
|
|
814
|
+
|
|
815
|
+
class VariableAnalyzer(ast.NodeVisitor):
|
|
816
|
+
def __init__(self):
|
|
817
|
+
self.variables = {}
|
|
818
|
+
self.assignments = []
|
|
819
|
+
|
|
820
|
+
def visit_Assign(self, node):
|
|
821
|
+
for target in node.targets:
|
|
822
|
+
if isinstance(target, ast.Name):
|
|
823
|
+
var_name = target.id
|
|
824
|
+
|
|
825
|
+
if var_name not in self.variables:
|
|
826
|
+
self.variables[var_name] = []
|
|
827
|
+
|
|
828
|
+
self.variables[var_name].append({
|
|
829
|
+
'line': node.lineno,
|
|
830
|
+
'type': 'assignment'
|
|
831
|
+
})
|
|
832
|
+
|
|
833
|
+
# Check for complex expressions
|
|
834
|
+
if self._is_complex_expression(node.value):
|
|
835
|
+
self.assignments.append({
|
|
836
|
+
'name': var_name,
|
|
837
|
+
'line': node.lineno,
|
|
838
|
+
'value': node.value
|
|
839
|
+
})
|
|
840
|
+
|
|
841
|
+
self.generic_visit(node)
|
|
842
|
+
|
|
843
|
+
def _is_complex_expression(self, node):
|
|
844
|
+
"""Check if expression is complex enough to extract."""
|
|
845
|
+
complexity = 0
|
|
846
|
+
for child in ast.walk(node):
|
|
847
|
+
if isinstance(child, (ast.BinOp, ast.BoolOp, ast.Call)):
|
|
848
|
+
complexity += 1
|
|
849
|
+
elif isinstance(child, ast.Compare):
|
|
850
|
+
complexity += len(child.ops)
|
|
851
|
+
return complexity > 3
|
|
852
|
+
|
|
853
|
+
analyzer = VariableAnalyzer()
|
|
854
|
+
analyzer.visit(tree)
|
|
855
|
+
|
|
856
|
+
# Generate extraction opportunities
|
|
857
|
+
for assignment in analyzer.assignments:
|
|
858
|
+
opportunity = RefactorOpportunity(
|
|
859
|
+
type=RefactorType.EXTRACT_VARIABLE,
|
|
860
|
+
file_path=file_path,
|
|
861
|
+
line_range=(assignment['line'], assignment['line']),
|
|
862
|
+
confidence=0.8,
|
|
863
|
+
complexity_reduction=0.15,
|
|
864
|
+
risk_level="low",
|
|
865
|
+
description=f"Extract complex expression for variable '{assignment['name']}'",
|
|
866
|
+
before_code=f"complex_assignment = ...",
|
|
867
|
+
after_code=f"extracted_value = calculate_complex_logic()\n{assignment['name']} = extracted_value",
|
|
868
|
+
technical_debt_addresses=[TechnicalDebtType.CODE_COMPLEXITY]
|
|
869
|
+
)
|
|
870
|
+
opportunities.append(opportunity)
|
|
871
|
+
|
|
872
|
+
return opportunities
|
|
873
|
+
|
|
874
|
+
def _identify_import_refactoring(
|
|
875
|
+
self, tree: ast.AST, file_path: str, content: str
|
|
876
|
+
) -> List[RefactorOpportunity]:
|
|
877
|
+
"""Identify import-level refactoring opportunities."""
|
|
878
|
+
|
|
879
|
+
opportunities = []
|
|
880
|
+
lines = content.split('\n')
|
|
881
|
+
|
|
882
|
+
class ImportAnalyzer(ast.NodeVisitor):
|
|
883
|
+
def __init__(self):
|
|
884
|
+
self.imports = []
|
|
885
|
+
self.import_lines = set()
|
|
886
|
+
|
|
887
|
+
def visit_Import(self, node):
|
|
888
|
+
for alias in node.names:
|
|
889
|
+
self.imports.append({
|
|
890
|
+
'type': 'import',
|
|
891
|
+
'module': alias.name,
|
|
892
|
+
'alias': alias.asname,
|
|
893
|
+
'line': node.lineno
|
|
894
|
+
})
|
|
895
|
+
self.import_lines.add(node.lineno)
|
|
896
|
+
self.generic_visit(node)
|
|
897
|
+
|
|
898
|
+
def visit_ImportFrom(self, node):
|
|
899
|
+
for alias in node.names:
|
|
900
|
+
self.imports.append({
|
|
901
|
+
'type': 'from_import',
|
|
902
|
+
'module': node.module,
|
|
903
|
+
'name': alias.name,
|
|
904
|
+
'alias': alias.asname,
|
|
905
|
+
'line': node.lineno
|
|
906
|
+
})
|
|
907
|
+
self.import_lines.add(node.lineno)
|
|
908
|
+
self.generic_visit(node)
|
|
909
|
+
|
|
910
|
+
analyzer = ImportAnalyzer()
|
|
911
|
+
analyzer.visit(tree)
|
|
912
|
+
|
|
913
|
+
# Check for import optimization opportunities
|
|
914
|
+
if len(analyzer.imports) > 10: # Too many imports
|
|
915
|
+
opportunity = RefactorOpportunity(
|
|
916
|
+
type=RefactorType.REORGANIZE_IMPORTS,
|
|
917
|
+
file_path=file_path,
|
|
918
|
+
line_range=(min(imp['line'] for imp in analyzer.imports),
|
|
919
|
+
max(imp['line'] for imp in analyzer.imports)),
|
|
920
|
+
confidence=0.9,
|
|
921
|
+
complexity_reduction=0.1,
|
|
922
|
+
risk_level="low",
|
|
923
|
+
description="Reorganize and optimize imports structure",
|
|
924
|
+
before_code="# Multiple scattered imports",
|
|
925
|
+
after_code="# Organized imports with proper grouping",
|
|
926
|
+
technical_debt_addresses=[]
|
|
927
|
+
)
|
|
928
|
+
opportunities.append(opportunity)
|
|
929
|
+
|
|
930
|
+
return opportunities
|
|
931
|
+
|
|
932
|
+
def _has_complex_expressions(self, method_content: str) -> bool:
|
|
933
|
+
"""Check if method contains complex expressions that could be extracted."""
|
|
934
|
+
|
|
935
|
+
# Simple heuristic for complex expressions
|
|
936
|
+
complexity_indicators = [
|
|
937
|
+
' and ' in method_content,
|
|
938
|
+
' or ' in method_content,
|
|
939
|
+
method_content.count('(') > 10,
|
|
940
|
+
method_content.count('.') > 15,
|
|
941
|
+
len(method_content.split('\n')) > 20
|
|
942
|
+
]
|
|
943
|
+
|
|
944
|
+
return sum(complexity_indicators) >= 2
|
|
945
|
+
|
|
946
|
+
def _create_safe_refactor_plan(
|
|
947
|
+
self, opportunities: List[RefactorOpportunity],
|
|
948
|
+
debt_items: List[TechnicalDebtItem],
|
|
949
|
+
context7_patterns: Dict[str, Any]
|
|
950
|
+
) -> RefactorPlan:
|
|
951
|
+
"""Create safe refactor plan with execution strategy."""
|
|
952
|
+
|
|
953
|
+
# Filter opportunities by confidence and risk
|
|
954
|
+
safe_opportunities = [
|
|
955
|
+
opp for opp in opportunities
|
|
956
|
+
if opp.confidence > 0.6 and opp.risk_level != "high"
|
|
957
|
+
]
|
|
958
|
+
|
|
959
|
+
# Create execution order (low-risk first, then high-impact)
|
|
960
|
+
execution_order = self._create_execution_order(safe_opportunities)
|
|
961
|
+
|
|
962
|
+
# Estimate total time
|
|
963
|
+
total_time = self._estimate_refactoring_time(safe_opportunities)
|
|
964
|
+
|
|
965
|
+
# Assess overall risk
|
|
966
|
+
risk_assessment = self._assess_overall_risk(safe_opportunities)
|
|
967
|
+
|
|
968
|
+
# Identify prerequisites
|
|
969
|
+
prerequisites = self._identify_prerequisites(safe_opportunities)
|
|
970
|
+
|
|
971
|
+
# Create rollback strategy
|
|
972
|
+
rollback_strategy = self._create_rollback_strategy(safe_opportunities)
|
|
973
|
+
|
|
974
|
+
return RefactorPlan(
|
|
975
|
+
opportunities=safe_opportunities,
|
|
976
|
+
technical_debt_items=debt_items,
|
|
977
|
+
execution_order=execution_order,
|
|
978
|
+
estimated_time=total_time,
|
|
979
|
+
risk_assessment=risk_assessment,
|
|
980
|
+
prerequisites=prerequisites,
|
|
981
|
+
rollback_strategy=rollback_strategy
|
|
982
|
+
)
|
|
983
|
+
|
|
984
|
+
def _create_execution_order(
|
|
985
|
+
self, opportunities: List[RefactorOpportunity]
|
|
986
|
+
) -> List[int]:
|
|
987
|
+
"""Create optimal execution order for refactoring operations."""
|
|
988
|
+
|
|
989
|
+
# Sort by: risk level (low first), then by confidence (high first), then by impact (high first)
|
|
990
|
+
risk_order = {'low': 1, 'medium': 2, 'high': 3}
|
|
991
|
+
|
|
992
|
+
sorted_opportunities = sorted(
|
|
993
|
+
enumerate(opportunities),
|
|
994
|
+
key=lambda x: (
|
|
995
|
+
risk_order.get(x[1].risk_level, 3),
|
|
996
|
+
-x[1].confidence,
|
|
997
|
+
-x[1].complexity_reduction
|
|
998
|
+
)
|
|
999
|
+
)
|
|
1000
|
+
|
|
1001
|
+
return [idx for idx, _ in sorted_opportunities]
|
|
1002
|
+
|
|
1003
|
+
def _estimate_refactoring_time(
|
|
1004
|
+
self, opportunities: List[RefactorOpportunity]
|
|
1005
|
+
) -> str:
|
|
1006
|
+
"""Estimate total time required for refactoring."""
|
|
1007
|
+
|
|
1008
|
+
total_minutes = 0
|
|
1009
|
+
|
|
1010
|
+
for opp in opportunities:
|
|
1011
|
+
# Base time by type
|
|
1012
|
+
type_times = {
|
|
1013
|
+
RefactorType.EXTRACT_METHOD: 30,
|
|
1014
|
+
RefactorType.EXTRACT_VARIABLE: 10,
|
|
1015
|
+
RefactorType.REORGANIZE_IMPORTS: 15,
|
|
1016
|
+
RefactorType.INLINE_VARIABLE: 5,
|
|
1017
|
+
RefactorType.RENAME: 20,
|
|
1018
|
+
RefactorType.MOVE_MODULE: 45
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
base_time = type_times.get(opp.type, 20)
|
|
1022
|
+
|
|
1023
|
+
# Adjust by risk level
|
|
1024
|
+
risk_multipliers = {'low': 1.0, 'medium': 1.5, 'high': 2.0}
|
|
1025
|
+
risk_multiplier = risk_multipliers.get(opp.risk_level, 1.0)
|
|
1026
|
+
|
|
1027
|
+
# Adjust by complexity reduction
|
|
1028
|
+
complexity_multiplier = 1.0 + (opp.complexity_reduction * 0.5)
|
|
1029
|
+
|
|
1030
|
+
total_minutes += base_time * risk_multiplier * complexity_multiplier
|
|
1031
|
+
|
|
1032
|
+
# Convert to human-readable format
|
|
1033
|
+
if total_minutes < 60:
|
|
1034
|
+
return f"{int(total_minutes)} minutes"
|
|
1035
|
+
elif total_minutes < 480: # 8 hours
|
|
1036
|
+
hours = total_minutes / 60
|
|
1037
|
+
return f"{int(hours)} hours"
|
|
1038
|
+
else:
|
|
1039
|
+
days = total_minutes / 480
|
|
1040
|
+
return f"{int(days)} days"
|
|
1041
|
+
|
|
1042
|
+
def _assess_overall_risk(
|
|
1043
|
+
self, opportunities: List[RefactorOpportunity]
|
|
1044
|
+
) -> str:
|
|
1045
|
+
"""Assess overall risk of refactoring plan."""
|
|
1046
|
+
|
|
1047
|
+
if not opportunities:
|
|
1048
|
+
return "no_risk"
|
|
1049
|
+
|
|
1050
|
+
high_risk_count = sum(1 for opp in opportunities if opp.risk_level == "high")
|
|
1051
|
+
medium_risk_count = sum(1 for opp in opportunities if opp.risk_level == "medium")
|
|
1052
|
+
|
|
1053
|
+
if high_risk_count > 2:
|
|
1054
|
+
return "high"
|
|
1055
|
+
elif high_risk_count > 0 or medium_risk_count > 5:
|
|
1056
|
+
return "medium"
|
|
1057
|
+
else:
|
|
1058
|
+
return "low"
|
|
1059
|
+
|
|
1060
|
+
def _identify_prerequisites(
|
|
1061
|
+
self, opportunities: List[RefactorOpportunity]
|
|
1062
|
+
) -> List[str]:
|
|
1063
|
+
"""Identify prerequisites for safe refactoring."""
|
|
1064
|
+
|
|
1065
|
+
prerequisites = [
|
|
1066
|
+
"Create comprehensive test suite",
|
|
1067
|
+
"Ensure version control is properly configured",
|
|
1068
|
+
"Create backup of current codebase"
|
|
1069
|
+
]
|
|
1070
|
+
|
|
1071
|
+
# Add specific prerequisites based on opportunities
|
|
1072
|
+
if any(opp.type == RefactorType.MOVE_MODULE for opp in opportunities):
|
|
1073
|
+
prerequisites.append("Update import statements in dependent modules")
|
|
1074
|
+
|
|
1075
|
+
if any(opp.type == RefactorType.EXTRACT_METHOD for opp in opportunities):
|
|
1076
|
+
prerequisites.append("Verify extracted methods maintain original functionality")
|
|
1077
|
+
|
|
1078
|
+
return prerequisites
|
|
1079
|
+
|
|
1080
|
+
def _create_rollback_strategy(
|
|
1081
|
+
self, opportunities: List[RefactorOpportunity]
|
|
1082
|
+
) -> str:
|
|
1083
|
+
"""Create rollback strategy for refactoring operations."""
|
|
1084
|
+
|
|
1085
|
+
return """
|
|
1086
|
+
Rollback Strategy:
|
|
1087
|
+
1. Create git commit before each major refactoring step
|
|
1088
|
+
2. Run full test suite after each operation
|
|
1089
|
+
3. Maintain detailed change log with timestamps
|
|
1090
|
+
4. Use git revert for individual operation rollbacks
|
|
1091
|
+
5. Automated tests to verify functionality preservation
|
|
1092
|
+
"""
|
|
1093
|
+
|
|
1094
|
+
# Usage Examples
|
|
1095
|
+
"""
|
|
1096
|
+
# Initialize refactoring system
|
|
1097
|
+
refactorer = AIRefactorer(context7_client=context7)
|
|
1098
|
+
|
|
1099
|
+
# Analyze and create refactoring plan
|
|
1100
|
+
refactor_plan = await refactorer.refactor_with_intelligence(
|
|
1101
|
+
codebase_path="/project/src",
|
|
1102
|
+
refactor_options={
|
|
1103
|
+
'max_risk_level': 'medium',
|
|
1104
|
+
'include_tests': True,
|
|
1105
|
+
'focus_on': ['complexity', 'duplication']
|
|
1106
|
+
}
|
|
1107
|
+
)
|
|
1108
|
+
|
|
1109
|
+
print(f"Found {len(refactor_plan.opportunities)} refactoring opportunities")
|
|
1110
|
+
print(f"Estimated time: {refactor_plan.estimated_time}")
|
|
1111
|
+
print(f"Risk assessment: {refactor_plan.risk_assessment}")
|
|
1112
|
+
|
|
1113
|
+
# Execute refactoring plan
|
|
1114
|
+
for i, opp_index in enumerate(refactor_plan.execution_order):
|
|
1115
|
+
opportunity = refactor_plan.opportunities[opp_index]
|
|
1116
|
+
print(f"\nStep {i+1}: {opportunity.description}")
|
|
1117
|
+
print(f"Type: {opportunity.type.value}")
|
|
1118
|
+
print(f"Risk: {opportunity.risk_level}")
|
|
1119
|
+
print(f"Confidence: {opportunity.confidence}")
|
|
1120
|
+
|
|
1121
|
+
# Here you would implement the actual refactoring using Rope
|
|
1122
|
+
# This is a simplified example
|
|
1123
|
+
if opportunity.type == RefactorType.EXTRACT_METHOD:
|
|
1124
|
+
print("Would extract method using Rope...")
|
|
1125
|
+
elif opportunity.type == RefactorType.REORGANIZE_IMPORTS:
|
|
1126
|
+
print("Would reorganize imports using Rope...")
|
|
1127
|
+
|
|
1128
|
+
# After refactoring, verify with tests
|
|
1129
|
+
print("\nRunning tests to verify refactoring...")
|
|
1130
|
+
# test_results = run_test_suite()
|
|
1131
|
+
# print(f"Tests passed: {test_results.passed}/{test_results.total}")
|
|
1132
|
+
"""
|
|
1133
|
+
```
|
|
1134
|
+
|
|
1135
|
+
## Advanced Features
|
|
1136
|
+
|
|
1137
|
+
### Context-Aware Refactoring
|
|
1138
|
+
|
|
1139
|
+
Intelligent Refactoring Context:
|
|
1140
|
+
```python
|
|
1141
|
+
class ContextAwareRefactorer(AIRefactorer):
|
|
1142
|
+
"""Refactorer that considers project context and conventions."""
|
|
1143
|
+
|
|
1144
|
+
def __init__(self, context7_client=None):
|
|
1145
|
+
super().__init__(context7_client)
|
|
1146
|
+
self.project_conventions = {}
|
|
1147
|
+
self.api_boundaries = set()
|
|
1148
|
+
|
|
1149
|
+
async def analyze_project_context(self, codebase_path: str):
|
|
1150
|
+
"""Analyze project-specific context and conventions."""
|
|
1151
|
+
|
|
1152
|
+
# Detect naming conventions
|
|
1153
|
+
await self._detect_naming_conventions(codebase_path)
|
|
1154
|
+
|
|
1155
|
+
# Identify API boundaries
|
|
1156
|
+
await self._identify_api_boundaries(codebase_path)
|
|
1157
|
+
|
|
1158
|
+
# Analyze architectural patterns
|
|
1159
|
+
await self._analyze_architecture_patterns(codebase_path)
|
|
1160
|
+
|
|
1161
|
+
async def _detect_naming_conventions(self, codebase_path: str):
|
|
1162
|
+
"""Detect project-specific naming conventions."""
|
|
1163
|
+
|
|
1164
|
+
naming_patterns = {
|
|
1165
|
+
'variable_names': [],
|
|
1166
|
+
'function_names': [],
|
|
1167
|
+
'class_names': [],
|
|
1168
|
+
'constant_names': []
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
python_files = self._find_python_files(codebase_path)
|
|
1172
|
+
|
|
1173
|
+
for file_path in python_files[:50]: # Sample files for analysis
|
|
1174
|
+
try:
|
|
1175
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
1176
|
+
content = f.read()
|
|
1177
|
+
|
|
1178
|
+
tree = ast.parse(content)
|
|
1179
|
+
|
|
1180
|
+
class NamingConventionVisitor(ast.NodeVisitor):
|
|
1181
|
+
def visit_Name(self, node):
|
|
1182
|
+
if isinstance(node.ctx, ast.Store):
|
|
1183
|
+
if node.id.isupper():
|
|
1184
|
+
naming_patterns['constant_names'].append(node.id)
|
|
1185
|
+
else:
|
|
1186
|
+
naming_patterns['variable_names'].append(node.id)
|
|
1187
|
+
self.generic_visit(node)
|
|
1188
|
+
|
|
1189
|
+
def visit_FunctionDef(self, node):
|
|
1190
|
+
naming_patterns['function_names'].append(node.name)
|
|
1191
|
+
self.generic_visit(node)
|
|
1192
|
+
|
|
1193
|
+
def visit_ClassDef(self, node):
|
|
1194
|
+
naming_patterns['class_names'].append(node.name)
|
|
1195
|
+
self.generic_visit(node)
|
|
1196
|
+
|
|
1197
|
+
visitor = NamingConventionVisitor()
|
|
1198
|
+
visitor.visit(tree)
|
|
1199
|
+
|
|
1200
|
+
except Exception as e:
|
|
1201
|
+
print(f"Error analyzing {file_path}: {e}")
|
|
1202
|
+
|
|
1203
|
+
# Analyze patterns
|
|
1204
|
+
self.project_conventions = self._analyze_naming_patterns(naming_patterns)
|
|
1205
|
+
|
|
1206
|
+
def _analyze_naming_patterns(self, patterns: Dict[str, List[str]]) -> Dict[str, Any]:
|
|
1207
|
+
"""Analyze naming patterns to extract conventions."""
|
|
1208
|
+
|
|
1209
|
+
conventions = {}
|
|
1210
|
+
|
|
1211
|
+
# Analyze variable naming
|
|
1212
|
+
snake_case_vars = sum(1 for name in patterns['variable_names'] if '_' in name)
|
|
1213
|
+
camel_case_vars = sum(1 for name in patterns['variable_names'] if name[0].islower() and any(c.isupper() for c in name[1:]))
|
|
1214
|
+
|
|
1215
|
+
if snake_case_vars > camel_case_vars:
|
|
1216
|
+
conventions['variable_naming'] = 'snake_case'
|
|
1217
|
+
else:
|
|
1218
|
+
conventions['variable_naming'] = 'camelCase'
|
|
1219
|
+
|
|
1220
|
+
# Analyze function naming
|
|
1221
|
+
snake_case_funcs = sum(1 for name in patterns['function_names'] if '_' in name)
|
|
1222
|
+
camel_case_funcs = sum(1 for name in patterns['function_names'] if name[0].islower() and any(c.isupper() for c in name[1:]))
|
|
1223
|
+
|
|
1224
|
+
if snake_case_funcs > camel_case_funcs:
|
|
1225
|
+
conventions['function_naming'] = 'snake_case'
|
|
1226
|
+
else:
|
|
1227
|
+
conventions['function_naming'] = 'camelCase'
|
|
1228
|
+
|
|
1229
|
+
return conventions
|
|
1230
|
+
```
|
|
1231
|
+
|
|
1232
|
+
## Best Practices
|
|
1233
|
+
|
|
1234
|
+
1. Incremental Refactoring: Apply changes incrementally with testing at each step
|
|
1235
|
+
2. Test Coverage: Ensure comprehensive test coverage before major refactoring
|
|
1236
|
+
3. Version Control: Commit changes before and after each major refactoring step
|
|
1237
|
+
4. Documentation: Update documentation to reflect refactored code structure
|
|
1238
|
+
5. Performance Monitoring: Monitor performance impact of refactoring changes
|
|
1239
|
+
|
|
1240
|
+
---
|
|
1241
|
+
|
|
1242
|
+
Module: `modules/smart-refactoring.md`
|
|
1243
|
+
Related: [AI Debugging](./ai-debugging.md) | [Performance Optimization](./performance-optimization.md)
|