moai-adk 0.34.0__py3-none-any.whl → 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- moai_adk/__main__.py +136 -5
- moai_adk/astgrep/__init__.py +37 -0
- moai_adk/astgrep/analyzer.py +522 -0
- moai_adk/astgrep/models.py +124 -0
- moai_adk/astgrep/rules.py +179 -0
- moai_adk/cli/commands/analyze.py +11 -2
- moai_adk/cli/commands/doctor.py +7 -1
- moai_adk/cli/commands/init.py +321 -11
- moai_adk/cli/commands/language.py +7 -1
- moai_adk/cli/commands/rank.py +449 -0
- moai_adk/cli/commands/status.py +7 -1
- moai_adk/cli/commands/switch.py +325 -0
- moai_adk/cli/commands/update.py +296 -23
- moai_adk/cli/prompts/init_prompts.py +362 -66
- moai_adk/cli/prompts/translations/__init__.py +573 -0
- moai_adk/cli/ui/prompts.py +61 -2
- moai_adk/cli/worktree/cli.py +106 -1
- moai_adk/cli/worktree/manager.py +155 -0
- moai_adk/core/config/unified.py +244 -63
- moai_adk/core/credentials.py +264 -0
- moai_adk/core/error_recovery_system.py +22 -4
- moai_adk/core/git/conflict_detector.py +10 -1
- moai_adk/core/git/event_detector.py +16 -5
- moai_adk/core/integration/engine.py +2 -2
- moai_adk/core/integration/integration_tester.py +5 -5
- moai_adk/core/language_config_resolver.py +9 -3
- moai_adk/core/merge/analyzer.py +509 -324
- moai_adk/core/migration/alfred_to_moai_migrator.py +7 -1
- moai_adk/core/migration/backup_manager.py +54 -4
- moai_adk/core/migration/file_migrator.py +174 -2
- moai_adk/core/migration/interactive_checkbox_ui.py +42 -31
- moai_adk/core/migration/version_detector.py +123 -19
- moai_adk/core/migration/version_migrator.py +44 -9
- moai_adk/core/model_allocator.py +241 -0
- moai_adk/core/project/backup_utils.py +12 -2
- moai_adk/core/project/initializer.py +44 -87
- moai_adk/core/project/phase_executor.py +95 -33
- moai_adk/core/project/validator.py +16 -1
- moai_adk/core/quality/trust_checker.py +30 -10
- moai_adk/core/rollback_manager.py +60 -25
- moai_adk/core/template/backup.py +88 -6
- moai_adk/core/template/config.py +33 -9
- moai_adk/core/template/merger.py +34 -8
- moai_adk/core/template/processor.py +334 -11
- moai_adk/core/template_engine.py +10 -1
- moai_adk/core/template_variable_synchronizer.py +16 -2
- moai_adk/core/version_sync.py +54 -6
- moai_adk/foundation/__init__.py +1 -20
- moai_adk/foundation/testing.py +1 -1
- moai_adk/loop/__init__.py +54 -0
- moai_adk/loop/controller.py +305 -0
- moai_adk/loop/feedback.py +230 -0
- moai_adk/loop/state.py +209 -0
- moai_adk/loop/storage.py +220 -0
- moai_adk/lsp/__init__.py +70 -0
- moai_adk/lsp/client.py +320 -0
- moai_adk/lsp/models.py +261 -0
- moai_adk/lsp/protocol.py +404 -0
- moai_adk/lsp/server_manager.py +248 -0
- moai_adk/project/configuration.py +8 -1
- moai_adk/py.typed +0 -0
- moai_adk/ralph/__init__.py +37 -0
- moai_adk/ralph/engine.py +307 -0
- moai_adk/rank/__init__.py +21 -0
- moai_adk/rank/auth.py +425 -0
- moai_adk/rank/client.py +557 -0
- moai_adk/rank/config.py +147 -0
- moai_adk/rank/hook.py +1503 -0
- moai_adk/rank/py.typed +0 -0
- moai_adk/statusline/__init__.py +3 -0
- moai_adk/statusline/enhanced_output_style_detector.py +5 -5
- moai_adk/statusline/main.py +20 -1
- moai_adk/statusline/memory_collector.py +268 -0
- moai_adk/statusline/renderer.py +54 -38
- moai_adk/tag_system/__init__.py +48 -0
- moai_adk/tag_system/atomic_ops.py +117 -0
- moai_adk/tag_system/linkage.py +335 -0
- moai_adk/tag_system/parser.py +176 -0
- moai_adk/tag_system/validator.py +200 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +19 -3
- moai_adk/templates/.claude/agents/moai/builder-command.md +62 -16
- moai_adk/templates/.claude/agents/moai/builder-plugin.md +763 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +21 -5
- moai_adk/templates/.claude/agents/moai/expert-backend.md +103 -39
- moai_adk/templates/.claude/agents/moai/expert-debug.md +9 -3
- moai_adk/templates/.claude/agents/moai/expert-devops.md +16 -14
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +45 -31
- moai_adk/templates/.claude/agents/moai/expert-performance.md +13 -9
- moai_adk/templates/.claude/agents/moai/expert-refactoring.md +228 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +19 -3
- moai_adk/templates/.claude/agents/moai/expert-testing.md +13 -9
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +8 -2
- moai_adk/templates/.claude/agents/moai/manager-docs.md +10 -5
- moai_adk/templates/.claude/agents/moai/manager-git.md +99 -27
- moai_adk/templates/.claude/agents/moai/manager-project.md +87 -7
- moai_adk/templates/.claude/agents/moai/manager-quality.md +22 -5
- moai_adk/templates/.claude/agents/moai/manager-spec.md +8 -2
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +45 -14
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +16 -3
- moai_adk/templates/.claude/commands/moai/0-project.md +239 -1185
- moai_adk/templates/.claude/commands/moai/1-plan.md +383 -363
- moai_adk/templates/.claude/commands/moai/2-run.md +254 -347
- moai_adk/templates/.claude/commands/moai/3-sync.md +174 -100
- moai_adk/templates/.claude/commands/moai/9-feedback.md +49 -33
- moai_adk/templates/.claude/commands/moai/alfred.md +339 -0
- moai_adk/templates/.claude/commands/moai/cancel-loop.md +163 -0
- moai_adk/templates/.claude/commands/moai/fix.md +264 -0
- moai_adk/templates/.claude/commands/moai/loop.md +363 -0
- moai_adk/templates/.claude/hooks/moai/lib/README.md +143 -0
- moai_adk/templates/.claude/hooks/moai/lib/__init__.py +37 -81
- moai_adk/templates/.claude/hooks/moai/lib/alfred_detector.py +105 -0
- moai_adk/templates/.claude/hooks/moai/lib/atomic_write.py +122 -0
- moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +4 -1
- moai_adk/templates/.claude/hooks/moai/lib/common.py +35 -5
- moai_adk/templates/.claude/hooks/moai/lib/config.py +376 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +24 -28
- moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +14 -14
- moai_adk/templates/.claude/hooks/moai/lib/enhanced_output_style_detector.py +372 -0
- moai_adk/templates/.claude/hooks/moai/lib/exceptions.py +171 -0
- moai_adk/templates/.claude/hooks/moai/lib/file_utils.py +95 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_collector.py +190 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +15 -13
- moai_adk/templates/.claude/hooks/moai/lib/language_detector.py +298 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +125 -25
- moai_adk/templates/.claude/hooks/moai/lib/main.py +341 -0
- moai_adk/templates/.claude/hooks/moai/lib/memory_collector.py +268 -0
- moai_adk/templates/.claude/hooks/moai/lib/metrics_tracker.py +78 -0
- moai_adk/templates/.claude/hooks/moai/lib/models.py +9 -7
- moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +204 -13
- moai_adk/templates/.claude/hooks/moai/lib/project.py +23 -14
- moai_adk/templates/.claude/hooks/moai/lib/renderer.py +359 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_linkage.py +333 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_parser.py +176 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_validator.py +200 -0
- moai_adk/templates/.claude/hooks/moai/lib/timeout.py +5 -5
- moai_adk/templates/.claude/hooks/moai/lib/tool_registry.py +896 -0
- moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +30 -18
- moai_adk/templates/.claude/hooks/moai/lib/update_checker.py +129 -0
- moai_adk/templates/.claude/hooks/moai/lib/version_reader.py +741 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__ast_grep_scan.py +276 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__code_formatter.py +255 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__coverage_guard.py +325 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__linter.py +315 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__lsp_diagnostic.py +508 -0
- moai_adk/templates/.claude/hooks/moai/pre_commit__tag_validator.py +287 -0
- moai_adk/templates/.claude/hooks/moai/pre_tool__security_guard.py +268 -0
- moai_adk/templates/.claude/hooks/moai/pre_tool__tdd_enforcer.py +208 -0
- moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +93 -61
- moai_adk/templates/.claude/hooks/moai/session_end__rank_submit.py +69 -0
- moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +165 -70
- moai_adk/templates/.claude/hooks/moai/shared/utils/announcement_translator.py +206 -0
- moai_adk/templates/.claude/hooks/moai/stop__loop_controller.py +621 -0
- moai_adk/templates/.claude/output-styles/moai/alfred.md +758 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +86 -3
- moai_adk/templates/.claude/output-styles/moai/yoda.md +2 -2
- moai_adk/templates/.claude/settings.json +154 -77
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +252 -198
- moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +169 -323
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +39 -27
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +115 -125
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +150 -150
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +182 -175
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +198 -138
- moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +226 -320
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +43 -222
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +75 -219
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +103 -463
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/component-architecture.md +723 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/nextjs16-patterns.md +713 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/performance-optimization.md +694 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/react19-patterns.md +591 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/state-management.md +680 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/vue35-patterns.md +802 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +118 -339
- moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +74 -377
- moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +299 -70
- moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +205 -182
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/advanced-agent-patterns.md +370 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-cli-reference-official.md +420 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +32 -22
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-devcontainers-official.md +381 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-discover-plugins-official.md +379 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-headless-official.md +378 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +110 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-plugin-marketplaces-official.md +308 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-plugins-official.md +640 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sandboxing-official.md +282 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +425 -71
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-statusline-official.md +293 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +325 -143
- moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +96 -316
- moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +116 -294
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-advanced.md +279 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-implementation.md +267 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +121 -650
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/patterns.md +22 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-ears-format.md +200 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +37 -730
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-tdd-implementation.md +275 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +77 -819
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-implementation.md +244 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-validation.md +219 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +14 -18
- moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +86 -270
- moai_adk/templates/.claude/skills/moai-framework-electron/SKILL.md +288 -0
- moai_adk/templates/.claude/skills/moai-framework-electron/examples.md +2082 -0
- moai_adk/templates/.claude/skills/moai-framework-electron/reference.md +1649 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +76 -582
- moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +1239 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/modules/advanced-patterns.md +401 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +1136 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +82 -436
- moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +585 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/aspnet-core.md +627 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/blazor-components.md +767 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/cqrs-validation.md +626 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/csharp12-features.md +580 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/efcore-patterns.md +622 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +403 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +65 -542
- moai_adk/templates/.claude/skills/moai-lang-elixir/examples.md +1171 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/modules/advanced-patterns.md +531 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/reference.md +889 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +32 -405
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +114 -293
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +83 -307
- moai_adk/templates/.claude/skills/moai-lang-javascript/SKILL.md +179 -0
- moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +973 -0
- moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +1543 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +42 -279
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +94 -556
- moai_adk/templates/.claude/skills/moai-lang-php/examples.md +1608 -0
- moai_adk/templates/.claude/skills/moai-lang-php/modules/advanced-patterns.md +538 -0
- moai_adk/templates/.claude/skills/moai-lang-php/reference.md +1323 -0
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +108 -358
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +84 -482
- moai_adk/templates/.claude/skills/moai-lang-r/examples.md +1154 -0
- moai_adk/templates/.claude/skills/moai-lang-r/modules/advanced-patterns.md +489 -0
- moai_adk/templates/.claude/skills/moai-lang-r/reference.md +1087 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +106 -610
- moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +1106 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/modules/advanced-patterns.md +309 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/modules/testing-patterns.md +306 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +1024 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +51 -265
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +106 -442
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/akka-actors.md +479 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/cats-effect.md +489 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/functional-programming.md +460 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/spark-data.md +498 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/zio-patterns.md +541 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +88 -457
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/combine-reactive.md +256 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/concurrency.md +270 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/swift6-features.md +265 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/swiftui-patterns.md +314 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +75 -283
- moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +97 -252
- moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +64 -240
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +331 -12
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +330 -37
- moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +90 -287
- moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +200 -206
- moai_adk/templates/.claude/skills/moai-platform-auth0/examples.md +2446 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/adaptive-mfa.md +233 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/akamai-integration.md +214 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/application-credentials.md +280 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/attack-protection-log-events.md +224 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/attack-protection-overview.md +140 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/bot-detection.md +144 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/breached-password-detection.md +187 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/brute-force-protection.md +189 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/certifications.md +282 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/compliance-overview.md +263 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/continuous-session-protection.md +307 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/customize-mfa.md +177 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/dpop-implementation.md +283 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/fapi-implementation.md +259 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/gdpr-compliance.md +313 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/guardian-configuration.md +269 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/highly-regulated-identity.md +272 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/jwt-fundamentals.md +248 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mdl-verification.md +210 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-api-management.md +278 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-factors.md +226 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-overview.md +174 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mtls-sender-constraining.md +316 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/ropg-flow-mfa.md +216 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/security-center.md +325 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/security-guidance.md +277 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/state-parameters.md +177 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/step-up-authentication.md +251 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/suspicious-ip-throttling.md +240 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/tenant-access-control.md +179 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/webauthn-fido.md +235 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/reference.md +224 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +75 -330
- moai_adk/templates/.claude/skills/moai-platform-clerk/examples.md +1426 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/modules/advanced-patterns.md +417 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/reference.md +273 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +100 -340
- moai_adk/templates/.claude/skills/moai-platform-convex/examples.md +506 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/auth-integration.md +421 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/file-storage.md +474 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/reactive-queries.md +302 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/server-functions.md +452 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/reference.md +385 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +113 -326
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/examples.md +514 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/custom-claims.md +374 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/phone-auth.md +372 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/social-auth.md +339 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/reference.md +382 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +71 -302
- moai_adk/templates/.claude/skills/moai-platform-firestore/examples.md +445 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/offline-cache.md +392 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/realtime-listeners.md +441 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/security-rules.md +352 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/transactions.md +452 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/reference.md +322 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +101 -412
- moai_adk/templates/.claude/skills/moai-platform-neon/examples.md +470 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/auto-scaling.md +349 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/branching-workflows.md +354 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/connection-pooling.md +412 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/pitr-backups.md +458 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/reference.md +272 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +96 -327
- moai_adk/templates/.claude/skills/moai-platform-railway/examples.md +539 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/docker-deployment.md +261 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/multi-service.md +291 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/networking-domains.md +338 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/volumes-storage.md +353 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/reference.md +374 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +103 -428
- moai_adk/templates/.claude/skills/moai-platform-supabase/examples.md +502 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/auth-integration.md +384 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/edge-functions.md +371 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/postgresql-pgvector.md +231 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/realtime-presence.md +354 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/row-level-security.md +286 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/storage-cdn.md +319 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/typescript-patterns.md +453 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/reference.md +284 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +96 -446
- moai_adk/templates/.claude/skills/moai-platform-vercel/examples.md +502 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/analytics-speed.md +348 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/deployment-config.md +344 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/edge-functions.md +222 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/isr-caching.md +306 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/kv-storage.md +399 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/reference.md +360 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/SKILL.md +193 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/examples.md +1099 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/language-specific.md +307 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/pattern-syntax.md +237 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/refactoring-patterns.md +260 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/security-rules.md +239 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/reference.md +288 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/go.yml +90 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/python.yml +101 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/typescript.yml +83 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/quality/complexity-check.yml +94 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/quality/deprecated-apis.yml +84 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/secrets-detection.yml +89 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/sql-injection.yml +45 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/xss-prevention.yml +50 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/sgconfig.yml +54 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +225 -423
- moai_adk/templates/.claude/skills/moai-workflow-loop/SKILL.md +197 -0
- moai_adk/templates/.claude/skills/moai-workflow-loop/examples.md +1063 -0
- moai_adk/templates/.claude/skills/moai-workflow-loop/reference.md +1414 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +211 -314
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +15 -43
- moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +119 -316
- moai_adk/templates/.claude/skills/moai-workflow-spec/modules/advanced-patterns.md +237 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +96 -203
- moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +201 -388
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +52 -3
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +263 -806
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/context7-integration.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/review-workflows.md +500 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/relevance-analysis.md +154 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/safety-analysis.md +148 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/scoring-algorithms.md +196 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/timeliness-analysis.md +168 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/truthfulness-analysis.md +136 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/usability-analysis.md +153 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework.md +257 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +191 -1344
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/analysis-patterns.md +340 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/core-classes.md +299 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/tool-integration.md +380 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/debugging/debugging-workflows.md +451 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/debugging/error-analysis.md +442 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance/optimization-patterns.md +473 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance/profiling-techniques.md +481 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/ai-optimization.md +241 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/bottleneck-detection.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/optimization-plan.md +315 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/profiler-core.md +277 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/real-time-monitoring.md +187 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +287 -1194
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/quality-metrics.md +415 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/refactoring/ai-workflows.md +620 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/refactoring/patterns.md +692 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/security-analysis.md +429 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +262 -1192
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/static-analysis.md +438 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd/core-classes.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/advanced-features.md +494 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/red-green-refactor.md +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/test-generation.md +471 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/test-patterns.md +371 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +227 -1222
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/trust5-validation.md +428 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/SKILL.md +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/integration-patterns.md +149 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/moai-adk-integration.md +245 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-advanced.md +310 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-development.md +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-workflows.md +302 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/registry-architecture.md +271 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/resource-optimization.md +300 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/tools-integration.md +280 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/troubleshooting.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/worktree-commands.md +296 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/worktree-management.md +217 -0
- moai_adk/templates/.git-hooks/pre-push +162 -59
- moai_adk/templates/.github/workflows/ci-universal.yml +934 -133
- moai_adk/templates/.gitignore +65 -107
- moai_adk/templates/.lsp.json +152 -0
- moai_adk/templates/.mcp.json +2 -20
- moai_adk/templates/.moai/announcements/en.json +18 -0
- moai_adk/templates/.moai/announcements/ja.json +18 -0
- moai_adk/templates/.moai/announcements/ko.json +18 -0
- moai_adk/templates/.moai/announcements/zh.json +18 -0
- moai_adk/templates/.moai/config/config.yaml +8 -2
- moai_adk/templates/.moai/config/multilingual-triggers.yaml +213 -0
- moai_adk/templates/.moai/config/sections/language.yaml +2 -2
- moai_adk/templates/.moai/config/sections/llm.yaml +41 -0
- moai_adk/templates/.moai/config/sections/pricing.yaml +30 -0
- moai_adk/templates/.moai/config/sections/project.yaml +2 -2
- moai_adk/templates/.moai/config/sections/quality.yaml +43 -5
- moai_adk/templates/.moai/config/sections/ralph.yaml +55 -0
- moai_adk/templates/.moai/config/sections/system.yaml +46 -1
- moai_adk/templates/.moai/config/sections/user.yaml +1 -1
- moai_adk/templates/.moai/config/statusline-config.yaml +2 -2
- moai_adk/templates/.moai/llm-configs/glm.json +22 -0
- moai_adk/templates/CLAUDE.ja.md +343 -0
- moai_adk/templates/CLAUDE.ko.md +343 -0
- moai_adk/templates/CLAUDE.md +200 -499
- moai_adk/templates/CLAUDE.zh.md +343 -0
- moai_adk/utils/common.py +37 -0
- moai_adk/version.py +1 -1
- moai_adk-1.1.0.dist-info/METADATA +2443 -0
- moai_adk-1.1.0.dist-info/RECORD +701 -0
- {moai_adk-0.34.0.dist-info → moai_adk-1.1.0.dist-info}/entry_points.txt +2 -0
- moai_adk-1.1.0.dist-info/licenses/LICENSE +99 -0
- moai_adk/core/config/auto_spec_config.py +0 -340
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +0 -901
- moai_adk/core/spec/confidence_scoring.py +0 -680
- moai_adk/core/spec/ears_template_engine.py +0 -1247
- moai_adk/core/spec/quality_validator.py +0 -687
- moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +0 -670
- moai_adk/templates/.claude/agents/moai/expert-database.md +0 -777
- moai_adk/templates/.claude/agents/moai/expert-uiux.md +0 -1041
- moai_adk/templates/.claude/agents/moai/mcp-context7.md +0 -458
- moai_adk/templates/.claude/agents/moai/mcp-figma.md +0 -1607
- moai_adk/templates/.claude/agents/moai/mcp-notion.md +0 -789
- moai_adk/templates/.claude/agents/moai/mcp-playwright.md +0 -469
- moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +0 -1032
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +0 -438
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +0 -431
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/design-system-tokens.md +0 -405
- moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +0 -336
- moai_adk/templates/.claude/skills/moai-mcp-figma/SKILL.md +0 -402
- moai_adk/templates/.claude/skills/moai-mcp-figma/advanced-patterns.md +0 -607
- moai_adk/templates/.claude/skills/moai-mcp-notion/SKILL.md +0 -300
- moai_adk/templates/.claude/skills/moai-mcp-notion/advanced-patterns.md +0 -537
- moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +0 -520
- moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +0 -574
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +0 -317
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +0 -663
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +0 -190
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +0 -175
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +0 -196
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +0 -17
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +0 -158
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +0 -340
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +0 -713
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +0 -538
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +0 -1336
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +0 -730
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +0 -608
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +0 -1005
- moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +0 -436
- moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +0 -411
- moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +0 -982
- moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +0 -778
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +0 -646
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +0 -782
- moai_adk/templates/.moai/config/questions/_schema.yaml +0 -151
- moai_adk/templates/.moai/config/questions/tab0-init.yaml +0 -251
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +0 -108
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +0 -81
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +0 -634
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +0 -170
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +0 -87
- moai_adk/templates/.moai/scripts/setup-glm.py +0 -136
- moai_adk-0.34.0.dist-info/METADATA +0 -2999
- moai_adk-0.34.0.dist-info/RECORD +0 -463
- moai_adk-0.34.0.dist-info/licenses/LICENSE +0 -21
- /moai_adk/foundation/{git.py → git/__init__.py} +0 -0
- /moai_adk/templates/.claude/skills/moai-library-mermaid/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-library-mermaid/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-library-nextra/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-jit-docs/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-jit-docs/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-testing/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-testing/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/{moai-worktree → moai-workflow-worktree}/examples.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-worktree → moai-workflow-worktree}/reference.md +0 -0
- {moai_adk-0.34.0.dist-info → moai_adk-1.1.0.dist-info}/WHEEL +0 -0
|
@@ -5,1230 +5,278 @@
|
|
|
5
5
|
> Time: 25+ minutes
|
|
6
6
|
> Dependencies: Python 3.8+, Rope, AST, Context7 MCP, asyncio, dataclasses
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Smart refactoring combines AI analysis with traditional refactoring tools to identify, prioritize, and safely execute code transformations while quantifying and reducing technical debt.
|
|
11
|
+
|
|
12
|
+
### Core Capabilities
|
|
13
|
+
|
|
14
|
+
Technical Debt Analysis:
|
|
15
|
+
- Automated code complexity detection (cyclomatic, cognitive, nesting depth)
|
|
16
|
+
- Code duplication identification across files
|
|
17
|
+
- Method length and parameter count analysis
|
|
18
|
+
- Naming convention violation detection
|
|
19
|
+
- Severity-based prioritization (critical, high, medium, low)
|
|
20
|
+
|
|
21
|
+
AI-Powered Refactoring:
|
|
22
|
+
- Context-aware refactoring opportunity identification
|
|
23
|
+
- Safe transformation planning with risk assessment
|
|
24
|
+
- Execution order optimization (low-risk first, then high-impact)
|
|
25
|
+
- Rollback strategy generation
|
|
26
|
+
- Integration with Rope for safe code transformations
|
|
27
|
+
|
|
28
|
+
Intelligent Analysis:
|
|
29
|
+
- Project-specific convention detection
|
|
30
|
+
- API boundary identification
|
|
31
|
+
- Architectural pattern recognition
|
|
32
|
+
- Cross-file dependency analysis
|
|
33
|
+
- Impact estimation and effort calculation
|
|
34
|
+
|
|
35
|
+
### Key Components
|
|
36
|
+
|
|
37
|
+
TechnicalDebtAnalyzer:
|
|
38
|
+
- Analyzes Python codebases for technical debt patterns
|
|
39
|
+
- Calculates complexity metrics using AST analysis
|
|
40
|
+
- Detects code duplication using similarity algorithms
|
|
41
|
+
- Generates prioritized debt items with suggested fixes
|
|
42
|
+
|
|
43
|
+
AIRefactorer:
|
|
44
|
+
- Integrates technical debt analysis with refactoring opportunities
|
|
45
|
+
- Creates safe execution plans with risk assessment
|
|
46
|
+
- Leverages Context7 MCP for latest refactoring patterns
|
|
47
|
+
- Uses Rope library for safe code transformations
|
|
48
|
+
|
|
49
|
+
RefactorPlan:
|
|
50
|
+
- Comprehensive refactoring roadmap with execution strategy
|
|
51
|
+
- Time estimation and risk assessment
|
|
52
|
+
- Prerequisites and rollback strategies
|
|
53
|
+
- Technical debt impact tracking
|
|
9
54
|
|
|
10
|
-
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Quick Reference
|
|
58
|
+
|
|
59
|
+
### Installation
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Install required dependencies
|
|
63
|
+
pip install rope ast-visitor
|
|
64
|
+
|
|
65
|
+
# For Context7 integration (optional but recommended)
|
|
66
|
+
pip install context7-client
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Basic Usage
|
|
11
70
|
|
|
12
71
|
```python
|
|
13
|
-
import ast
|
|
14
72
|
import asyncio
|
|
15
|
-
from
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
"""
|
|
73
|
+
from smart_refactoring import AIRefactorer
|
|
74
|
+
|
|
75
|
+
async def main():
|
|
76
|
+
# Initialize refactoring system
|
|
77
|
+
refactorer = AIRefactorer(context7_client=None)
|
|
78
|
+
|
|
79
|
+
# Analyze and create refactoring plan
|
|
80
|
+
refactor_plan = await refactorer.refactor_with_intelligence(
|
|
81
|
+
codebase_path="/project/src",
|
|
82
|
+
refactor_options={
|
|
83
|
+
'max_risk_level': 'medium',
|
|
84
|
+
'include_tests': True,
|
|
85
|
+
'focus_on': ['complexity', 'duplication']
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
print(f"Found {len(refactor_plan.opportunities)} opportunities")
|
|
90
|
+
print(f"Estimated time: {refactor_plan.estimated_time}")
|
|
91
|
+
print(f"Risk assessment: {refactor_plan.risk_assessment}")
|
|
92
|
+
|
|
93
|
+
asyncio.run(main())
|
|
1133
94
|
```
|
|
1134
95
|
|
|
1135
|
-
|
|
96
|
+
### Technical Debt Categories
|
|
1136
97
|
|
|
1137
|
-
|
|
98
|
+
Code Complexity:
|
|
99
|
+
- Cyclomatic complexity > 10 (medium), > 15 (high), > 20 (critical)
|
|
100
|
+
- Cognitive complexity > 15
|
|
101
|
+
- Nesting depth > 4 levels
|
|
1138
102
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
103
|
+
Duplication:
|
|
104
|
+
- Similar code blocks across files
|
|
105
|
+
- Repeated patterns with > 80% similarity
|
|
106
|
+
- Copied and pasted code segments
|
|
1143
107
|
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
108
|
+
Method Issues:
|
|
109
|
+
- Methods > 50 lines
|
|
110
|
+
- Functions with > 7 parameters
|
|
111
|
+
- Multiple responsibilities in single method
|
|
1148
112
|
|
|
1149
|
-
|
|
1150
|
-
|
|
113
|
+
Naming:
|
|
114
|
+
- Single-letter variables (except loop counters)
|
|
115
|
+
- Temp/tmp prefix variables
|
|
116
|
+
- Non-descriptive abbreviations
|
|
1151
117
|
|
|
1152
|
-
|
|
1153
|
-
await self._detect_naming_conventions(codebase_path)
|
|
118
|
+
### Refactoring Types
|
|
1154
119
|
|
|
1155
|
-
|
|
1156
|
-
|
|
120
|
+
Extract Method:
|
|
121
|
+
- Trigger: Method > 30 lines or complexity > 8
|
|
122
|
+
- Risk: Low to medium
|
|
123
|
+
- Impact: Reduces complexity, improves readability
|
|
1157
124
|
|
|
1158
|
-
|
|
1159
|
-
|
|
125
|
+
Extract Variable:
|
|
126
|
+
- Trigger: Complex expressions with multiple operations
|
|
127
|
+
- Risk: Low
|
|
128
|
+
- Impact: Improves code comprehension
|
|
1160
129
|
|
|
1161
|
-
|
|
1162
|
-
|
|
130
|
+
Reorganize Imports:
|
|
131
|
+
- Trigger: > 10 imports in single file
|
|
132
|
+
- Risk: Low
|
|
133
|
+
- Impact: Better dependency management
|
|
1163
134
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
'constant_names': []
|
|
1169
|
-
}
|
|
135
|
+
Inline Variable:
|
|
136
|
+
- Trigger: Variables used once with simple values
|
|
137
|
+
- Risk: Low
|
|
138
|
+
- Impact: Reduces unnecessary indirection
|
|
1170
139
|
|
|
1171
|
-
|
|
140
|
+
Move Module:
|
|
141
|
+
- Trigger: Logical grouping opportunities
|
|
142
|
+
- Risk: Medium to high
|
|
143
|
+
- Impact: Better architecture, reduced coupling
|
|
1172
144
|
|
|
1173
|
-
|
|
1174
|
-
try:
|
|
1175
|
-
with open(file_path, 'r', encoding='utf-8') as f:
|
|
1176
|
-
content = f.read()
|
|
145
|
+
---
|
|
1177
146
|
|
|
1178
|
-
|
|
147
|
+
## Implementation Guide
|
|
1179
148
|
|
|
1180
|
-
|
|
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)
|
|
149
|
+
### Workflow Overview
|
|
1188
150
|
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
151
|
+
Step 1 - Analyze Technical Debt:
|
|
152
|
+
```python
|
|
153
|
+
from smart_refactoring import TechnicalDebtAnalyzer
|
|
1192
154
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
self.generic_visit(node)
|
|
155
|
+
analyzer = TechnicalDebtAnalyzer()
|
|
156
|
+
debt_items = await analyzer.analyze("/project/src")
|
|
1196
157
|
|
|
1197
|
-
|
|
1198
|
-
|
|
158
|
+
for item in debt_items[:5]: # Top 5 priority items
|
|
159
|
+
print(f"[{item.severity.upper()}] {item.description}")
|
|
160
|
+
print(f" File: {item.file_path}:{item.line_number}")
|
|
161
|
+
print(f" Impact: {item.impact}")
|
|
162
|
+
print(f" Estimated effort: {item.estimated_effort}")
|
|
163
|
+
print(f" Suggested: {item.suggested_fix}")
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Step 2 - Identify Refactoring Opportunities:
|
|
167
|
+
```python
|
|
168
|
+
# AIRefactorer automatically analyzes opportunities
|
|
169
|
+
opportunities = refactor_plan.opportunities
|
|
170
|
+
|
|
171
|
+
for opp in opportunities[:3]:
|
|
172
|
+
print(f"\n{opp.type.value}")
|
|
173
|
+
print(f" Description: {opp.description}")
|
|
174
|
+
print(f" Confidence: {opp.confidence:.0%}")
|
|
175
|
+
print(f" Risk: {opp.risk_level}")
|
|
176
|
+
print(f" Complexity reduction: {opp.complexity_reduction:.0%}")
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Step 3 - Execute Safe Refactoring:
|
|
180
|
+
```python
|
|
181
|
+
# Execute refactoring plan in optimal order
|
|
182
|
+
for i, opp_index in enumerate(refactor_plan.execution_order):
|
|
183
|
+
opportunity = refactor_plan.opportunities[opp_index]
|
|
184
|
+
|
|
185
|
+
print(f"\nStep {i+1}: {opportunity.description}")
|
|
186
|
+
print(f"Type: {opportunity.type.value}")
|
|
187
|
+
print(f"Risk: {opportunity.risk_level}")
|
|
188
|
+
|
|
189
|
+
# Create git commit before each operation
|
|
190
|
+
# git commit -m "Before refactoring: {opportunity.description}"
|
|
191
|
+
|
|
192
|
+
# Execute refactoring using Rope
|
|
193
|
+
# (Implementation depends on refactoring type)
|
|
194
|
+
|
|
195
|
+
# Run tests to verify
|
|
196
|
+
# if tests_pass:
|
|
197
|
+
# git commit -m "After refactoring: {opportunity.description}"
|
|
198
|
+
# else:
|
|
199
|
+
# git revert HEAD
|
|
200
|
+
```
|
|
1199
201
|
|
|
1200
|
-
|
|
1201
|
-
print(f"Error analyzing {file_path}: {e}")
|
|
202
|
+
### Configuration Options
|
|
1202
203
|
|
|
1203
|
-
|
|
1204
|
-
|
|
204
|
+
Refactor Options:
|
|
205
|
+
```python
|
|
206
|
+
refactor_options = {
|
|
207
|
+
'max_risk_level': 'medium', # low, medium, high
|
|
208
|
+
'include_tests': True,
|
|
209
|
+
'focus_on': ['complexity', 'duplication', 'naming'],
|
|
210
|
+
'exclude_patterns': ['*_test.py', 'test_*.py'],
|
|
211
|
+
'min_confidence': 0.6,
|
|
212
|
+
'complexity_threshold': 10,
|
|
213
|
+
'duplication_threshold': 0.8
|
|
214
|
+
}
|
|
215
|
+
```
|
|
1205
216
|
|
|
1206
|
-
|
|
1207
|
-
"""Analyze naming patterns to extract conventions."""
|
|
217
|
+
### Integration with Testing
|
|
1208
218
|
|
|
1209
|
-
|
|
219
|
+
Pre-Refactoring Checklist:
|
|
220
|
+
- Comprehensive test suite exists
|
|
221
|
+
- All tests passing
|
|
222
|
+
- Test coverage > 80%
|
|
223
|
+
- Performance benchmarks recorded
|
|
1210
224
|
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
225
|
+
Post-Refactoring Verification:
|
|
226
|
+
- Run full test suite
|
|
227
|
+
- Verify performance benchmarks
|
|
228
|
+
- Check for breaking changes
|
|
229
|
+
- Update documentation
|
|
1214
230
|
|
|
1215
|
-
|
|
1216
|
-
conventions['variable_naming'] = 'snake_case'
|
|
1217
|
-
else:
|
|
1218
|
-
conventions['variable_naming'] = 'camelCase'
|
|
231
|
+
### Rollback Strategy
|
|
1219
232
|
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
233
|
+
Safe Refactoring Protocol:
|
|
234
|
+
1. Create git commit before each operation
|
|
235
|
+
2. Run automated tests after each change
|
|
236
|
+
3. Maintain detailed change log
|
|
237
|
+
4. Use git revert for individual rollbacks
|
|
238
|
+
5. Keep backup of original codebase
|
|
1223
239
|
|
|
1224
|
-
|
|
1225
|
-
conventions['function_naming'] = 'snake_case'
|
|
1226
|
-
else:
|
|
1227
|
-
conventions['function_naming'] = 'camelCase'
|
|
240
|
+
---
|
|
1228
241
|
|
|
1229
|
-
|
|
242
|
+
## Advanced Features
|
|
243
|
+
|
|
244
|
+
### Context-Aware Refactoring
|
|
245
|
+
|
|
246
|
+
The AIRefactorer can detect and respect project-specific conventions:
|
|
247
|
+
|
|
248
|
+
- Naming conventions (snake_case, camelCase)
|
|
249
|
+
- Architectural patterns (MVC, microservices)
|
|
250
|
+
- API boundaries (public, internal)
|
|
251
|
+
- Code organization preferences
|
|
252
|
+
|
|
253
|
+
See [refactoring/context-aware.md](refactoring/context-aware.md) for advanced context-aware patterns.
|
|
254
|
+
|
|
255
|
+
### Technical Debt Quantification
|
|
256
|
+
|
|
257
|
+
Track technical debt reduction over time:
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
# Before refactoring
|
|
261
|
+
initial_debt = await analyzer.analyze("/project/src")
|
|
262
|
+
initial_score = calculate_technical_debt_score(initial_debt)
|
|
263
|
+
|
|
264
|
+
# After refactoring
|
|
265
|
+
final_debt = await analyzer.analyze("/project/src")
|
|
266
|
+
final_score = calculate_technical_debt_score(final_debt)
|
|
267
|
+
|
|
268
|
+
improvement = initial_score - final_score
|
|
269
|
+
print(f"Technical debt reduced by {improvement:.1%}")
|
|
1230
270
|
```
|
|
1231
271
|
|
|
272
|
+
### Safe Refactoring Patterns
|
|
273
|
+
|
|
274
|
+
For detailed refactoring techniques and best practices, see:
|
|
275
|
+
- [refactoring/patterns.md](refactoring/patterns.md) - Specific refactoring techniques
|
|
276
|
+
- [refactoring/ai-workflows.md](refactoring/ai-workflows.md) - AI-assisted refactoring workflows
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
1232
280
|
## Best Practices
|
|
1233
281
|
|
|
1234
282
|
1. Incremental Refactoring: Apply changes incrementally with testing at each step
|
|
@@ -1239,5 +287,27 @@ class ContextAwareRefactorer(AIRefactorer):
|
|
|
1239
287
|
|
|
1240
288
|
---
|
|
1241
289
|
|
|
290
|
+
## Resources
|
|
291
|
+
|
|
292
|
+
### Dependencies
|
|
293
|
+
|
|
294
|
+
- Rope: Python refactoring library
|
|
295
|
+
- AST: Python built-in AST module
|
|
296
|
+
- Context7 MCP: Latest refactoring patterns (optional)
|
|
297
|
+
|
|
298
|
+
### Related Modules
|
|
299
|
+
|
|
300
|
+
- [AI Debugging](./ai-debugging.md) - Debugging with AI assistance
|
|
301
|
+
- [Performance Optimization](./performance-optimization.md) - Performance improvement techniques
|
|
302
|
+
- [Code Review](./code-review/) - Automated code review patterns
|
|
303
|
+
|
|
304
|
+
### External References
|
|
305
|
+
|
|
306
|
+
- Refactoring Guru: https://refactoring.guru/
|
|
307
|
+
- Python AST Documentation: https://docs.python.org/3/library/ast.html
|
|
308
|
+
- Rope Documentation: https://github.com/python-rope/rope
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
1242
312
|
Module: `modules/smart-refactoring.md`
|
|
1243
|
-
Related: [
|
|
313
|
+
Related: [refactoring/patterns.md](refactoring/patterns.md) | [refactoring/ai-workflows.md](refactoring/ai-workflows.md) | [AI Debugging](./ai-debugging.md)
|