crackerjack 0.18.2__py3-none-any.whl → 0.45.2__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.
- crackerjack/README.md +19 -0
- crackerjack/__init__.py +96 -2
- crackerjack/__main__.py +637 -138
- crackerjack/adapters/README.md +18 -0
- crackerjack/adapters/__init__.py +39 -0
- crackerjack/adapters/_output_paths.py +167 -0
- crackerjack/adapters/_qa_adapter_base.py +309 -0
- crackerjack/adapters/_tool_adapter_base.py +706 -0
- crackerjack/adapters/ai/README.md +65 -0
- crackerjack/adapters/ai/__init__.py +5 -0
- crackerjack/adapters/ai/claude.py +853 -0
- crackerjack/adapters/complexity/README.md +53 -0
- crackerjack/adapters/complexity/__init__.py +10 -0
- crackerjack/adapters/complexity/complexipy.py +641 -0
- crackerjack/adapters/dependency/__init__.py +22 -0
- crackerjack/adapters/dependency/pip_audit.py +418 -0
- crackerjack/adapters/format/README.md +72 -0
- crackerjack/adapters/format/__init__.py +11 -0
- crackerjack/adapters/format/mdformat.py +313 -0
- crackerjack/adapters/format/ruff.py +516 -0
- crackerjack/adapters/lint/README.md +47 -0
- crackerjack/adapters/lint/__init__.py +11 -0
- crackerjack/adapters/lint/codespell.py +273 -0
- crackerjack/adapters/lsp/README.md +49 -0
- crackerjack/adapters/lsp/__init__.py +27 -0
- crackerjack/adapters/lsp/_base.py +194 -0
- crackerjack/adapters/lsp/_client.py +358 -0
- crackerjack/adapters/lsp/_manager.py +193 -0
- crackerjack/adapters/lsp/skylos.py +283 -0
- crackerjack/adapters/lsp/zuban.py +557 -0
- crackerjack/adapters/refactor/README.md +59 -0
- crackerjack/adapters/refactor/__init__.py +12 -0
- crackerjack/adapters/refactor/creosote.py +318 -0
- crackerjack/adapters/refactor/refurb.py +406 -0
- crackerjack/adapters/refactor/skylos.py +494 -0
- crackerjack/adapters/sast/README.md +132 -0
- crackerjack/adapters/sast/__init__.py +32 -0
- crackerjack/adapters/sast/_base.py +201 -0
- crackerjack/adapters/sast/bandit.py +423 -0
- crackerjack/adapters/sast/pyscn.py +405 -0
- crackerjack/adapters/sast/semgrep.py +241 -0
- crackerjack/adapters/security/README.md +111 -0
- crackerjack/adapters/security/__init__.py +17 -0
- crackerjack/adapters/security/gitleaks.py +339 -0
- crackerjack/adapters/type/README.md +52 -0
- crackerjack/adapters/type/__init__.py +12 -0
- crackerjack/adapters/type/pyrefly.py +402 -0
- crackerjack/adapters/type/ty.py +402 -0
- crackerjack/adapters/type/zuban.py +522 -0
- crackerjack/adapters/utility/README.md +51 -0
- crackerjack/adapters/utility/__init__.py +10 -0
- crackerjack/adapters/utility/checks.py +884 -0
- crackerjack/agents/README.md +264 -0
- crackerjack/agents/__init__.py +66 -0
- crackerjack/agents/architect_agent.py +238 -0
- crackerjack/agents/base.py +167 -0
- crackerjack/agents/claude_code_bridge.py +641 -0
- crackerjack/agents/coordinator.py +600 -0
- crackerjack/agents/documentation_agent.py +520 -0
- crackerjack/agents/dry_agent.py +585 -0
- crackerjack/agents/enhanced_coordinator.py +279 -0
- crackerjack/agents/enhanced_proactive_agent.py +185 -0
- crackerjack/agents/error_middleware.py +53 -0
- crackerjack/agents/formatting_agent.py +230 -0
- crackerjack/agents/helpers/__init__.py +9 -0
- crackerjack/agents/helpers/performance/__init__.py +22 -0
- crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
- crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
- crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
- crackerjack/agents/helpers/refactoring/__init__.py +22 -0
- crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
- crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
- crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
- crackerjack/agents/helpers/test_creation/__init__.py +19 -0
- crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
- crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
- crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
- crackerjack/agents/import_optimization_agent.py +1181 -0
- crackerjack/agents/performance_agent.py +325 -0
- crackerjack/agents/performance_helpers.py +205 -0
- crackerjack/agents/proactive_agent.py +55 -0
- crackerjack/agents/refactoring_agent.py +511 -0
- crackerjack/agents/refactoring_helpers.py +247 -0
- crackerjack/agents/security_agent.py +793 -0
- crackerjack/agents/semantic_agent.py +479 -0
- crackerjack/agents/semantic_helpers.py +356 -0
- crackerjack/agents/test_creation_agent.py +570 -0
- crackerjack/agents/test_specialist_agent.py +526 -0
- crackerjack/agents/tracker.py +110 -0
- crackerjack/api.py +647 -0
- crackerjack/cli/README.md +394 -0
- crackerjack/cli/__init__.py +24 -0
- crackerjack/cli/cache_handlers.py +209 -0
- crackerjack/cli/cache_handlers_enhanced.py +680 -0
- crackerjack/cli/facade.py +162 -0
- crackerjack/cli/formatting.py +13 -0
- crackerjack/cli/handlers/__init__.py +85 -0
- crackerjack/cli/handlers/advanced.py +103 -0
- crackerjack/cli/handlers/ai_features.py +62 -0
- crackerjack/cli/handlers/analytics.py +479 -0
- crackerjack/cli/handlers/changelog.py +271 -0
- crackerjack/cli/handlers/config_handlers.py +16 -0
- crackerjack/cli/handlers/coverage.py +84 -0
- crackerjack/cli/handlers/documentation.py +280 -0
- crackerjack/cli/handlers/main_handlers.py +497 -0
- crackerjack/cli/handlers/monitoring.py +371 -0
- crackerjack/cli/handlers.py +700 -0
- crackerjack/cli/interactive.py +488 -0
- crackerjack/cli/options.py +1216 -0
- crackerjack/cli/semantic_handlers.py +292 -0
- crackerjack/cli/utils.py +19 -0
- crackerjack/cli/version.py +19 -0
- crackerjack/code_cleaner.py +1307 -0
- crackerjack/config/README.md +472 -0
- crackerjack/config/__init__.py +275 -0
- crackerjack/config/global_lock_config.py +207 -0
- crackerjack/config/hooks.py +390 -0
- crackerjack/config/loader.py +239 -0
- crackerjack/config/settings.py +141 -0
- crackerjack/config/tool_commands.py +331 -0
- crackerjack/core/README.md +393 -0
- crackerjack/core/__init__.py +0 -0
- crackerjack/core/async_workflow_orchestrator.py +738 -0
- crackerjack/core/autofix_coordinator.py +282 -0
- crackerjack/core/container.py +105 -0
- crackerjack/core/enhanced_container.py +583 -0
- crackerjack/core/file_lifecycle.py +472 -0
- crackerjack/core/performance.py +244 -0
- crackerjack/core/performance_monitor.py +357 -0
- crackerjack/core/phase_coordinator.py +1227 -0
- crackerjack/core/proactive_workflow.py +267 -0
- crackerjack/core/resource_manager.py +425 -0
- crackerjack/core/retry.py +275 -0
- crackerjack/core/service_watchdog.py +601 -0
- crackerjack/core/session_coordinator.py +239 -0
- crackerjack/core/timeout_manager.py +563 -0
- crackerjack/core/websocket_lifecycle.py +410 -0
- crackerjack/core/workflow/__init__.py +21 -0
- crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
- crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
- crackerjack/core/workflow/workflow_issue_parser.py +714 -0
- crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
- crackerjack/core/workflow/workflow_security_gates.py +400 -0
- crackerjack/core/workflow_orchestrator.py +2243 -0
- crackerjack/data/README.md +11 -0
- crackerjack/data/__init__.py +8 -0
- crackerjack/data/models.py +79 -0
- crackerjack/data/repository.py +210 -0
- crackerjack/decorators/README.md +180 -0
- crackerjack/decorators/__init__.py +35 -0
- crackerjack/decorators/error_handling.py +649 -0
- crackerjack/decorators/error_handling_decorators.py +334 -0
- crackerjack/decorators/helpers.py +58 -0
- crackerjack/decorators/patterns.py +281 -0
- crackerjack/decorators/utils.py +58 -0
- crackerjack/docs/INDEX.md +11 -0
- crackerjack/docs/README.md +11 -0
- crackerjack/docs/generated/api/API_REFERENCE.md +10895 -0
- crackerjack/docs/generated/api/CLI_REFERENCE.md +109 -0
- crackerjack/docs/generated/api/CROSS_REFERENCES.md +1755 -0
- crackerjack/docs/generated/api/PROTOCOLS.md +3 -0
- crackerjack/docs/generated/api/SERVICES.md +1252 -0
- crackerjack/documentation/README.md +11 -0
- crackerjack/documentation/__init__.py +31 -0
- crackerjack/documentation/ai_templates.py +756 -0
- crackerjack/documentation/dual_output_generator.py +767 -0
- crackerjack/documentation/mkdocs_integration.py +518 -0
- crackerjack/documentation/reference_generator.py +1065 -0
- crackerjack/dynamic_config.py +678 -0
- crackerjack/errors.py +378 -0
- crackerjack/events/README.md +11 -0
- crackerjack/events/__init__.py +16 -0
- crackerjack/events/telemetry.py +175 -0
- crackerjack/events/workflow_bus.py +346 -0
- crackerjack/exceptions/README.md +301 -0
- crackerjack/exceptions/__init__.py +5 -0
- crackerjack/exceptions/config.py +4 -0
- crackerjack/exceptions/tool_execution_error.py +245 -0
- crackerjack/executors/README.md +591 -0
- crackerjack/executors/__init__.py +13 -0
- crackerjack/executors/async_hook_executor.py +938 -0
- crackerjack/executors/cached_hook_executor.py +316 -0
- crackerjack/executors/hook_executor.py +1295 -0
- crackerjack/executors/hook_lock_manager.py +708 -0
- crackerjack/executors/individual_hook_executor.py +739 -0
- crackerjack/executors/lsp_aware_hook_executor.py +349 -0
- crackerjack/executors/progress_hook_executor.py +282 -0
- crackerjack/executors/tool_proxy.py +433 -0
- crackerjack/hooks/README.md +485 -0
- crackerjack/hooks/lsp_hook.py +93 -0
- crackerjack/intelligence/README.md +557 -0
- crackerjack/intelligence/__init__.py +37 -0
- crackerjack/intelligence/adaptive_learning.py +693 -0
- crackerjack/intelligence/agent_orchestrator.py +485 -0
- crackerjack/intelligence/agent_registry.py +377 -0
- crackerjack/intelligence/agent_selector.py +439 -0
- crackerjack/intelligence/integration.py +250 -0
- crackerjack/interactive.py +719 -0
- crackerjack/managers/README.md +369 -0
- crackerjack/managers/__init__.py +11 -0
- crackerjack/managers/async_hook_manager.py +135 -0
- crackerjack/managers/hook_manager.py +585 -0
- crackerjack/managers/publish_manager.py +631 -0
- crackerjack/managers/test_command_builder.py +391 -0
- crackerjack/managers/test_executor.py +474 -0
- crackerjack/managers/test_manager.py +1357 -0
- crackerjack/managers/test_progress.py +187 -0
- crackerjack/mcp/README.md +374 -0
- crackerjack/mcp/__init__.py +0 -0
- crackerjack/mcp/cache.py +352 -0
- crackerjack/mcp/client_runner.py +121 -0
- crackerjack/mcp/context.py +802 -0
- crackerjack/mcp/dashboard.py +657 -0
- crackerjack/mcp/enhanced_progress_monitor.py +493 -0
- crackerjack/mcp/file_monitor.py +394 -0
- crackerjack/mcp/progress_components.py +607 -0
- crackerjack/mcp/progress_monitor.py +1016 -0
- crackerjack/mcp/rate_limiter.py +336 -0
- crackerjack/mcp/server.py +24 -0
- crackerjack/mcp/server_core.py +526 -0
- crackerjack/mcp/service_watchdog.py +505 -0
- crackerjack/mcp/state.py +407 -0
- crackerjack/mcp/task_manager.py +259 -0
- crackerjack/mcp/tools/README.md +27 -0
- crackerjack/mcp/tools/__init__.py +19 -0
- crackerjack/mcp/tools/core_tools.py +469 -0
- crackerjack/mcp/tools/error_analyzer.py +283 -0
- crackerjack/mcp/tools/execution_tools.py +384 -0
- crackerjack/mcp/tools/intelligence_tool_registry.py +46 -0
- crackerjack/mcp/tools/intelligence_tools.py +264 -0
- crackerjack/mcp/tools/monitoring_tools.py +628 -0
- crackerjack/mcp/tools/proactive_tools.py +367 -0
- crackerjack/mcp/tools/progress_tools.py +222 -0
- crackerjack/mcp/tools/semantic_tools.py +584 -0
- crackerjack/mcp/tools/utility_tools.py +358 -0
- crackerjack/mcp/tools/workflow_executor.py +699 -0
- crackerjack/mcp/websocket/README.md +31 -0
- crackerjack/mcp/websocket/__init__.py +14 -0
- crackerjack/mcp/websocket/app.py +54 -0
- crackerjack/mcp/websocket/endpoints.py +492 -0
- crackerjack/mcp/websocket/event_bridge.py +188 -0
- crackerjack/mcp/websocket/jobs.py +406 -0
- crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
- crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
- crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
- crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
- crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
- crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
- crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
- crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
- crackerjack/mcp/websocket/monitoring/factory.py +109 -0
- crackerjack/mcp/websocket/monitoring/filters.py +10 -0
- crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
- crackerjack/mcp/websocket/monitoring/models.py +90 -0
- crackerjack/mcp/websocket/monitoring/utils.py +171 -0
- crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
- crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
- crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
- crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
- crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
- crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
- crackerjack/mcp/websocket/monitoring_endpoints.py +21 -0
- crackerjack/mcp/websocket/server.py +174 -0
- crackerjack/mcp/websocket/websocket_handler.py +276 -0
- crackerjack/mcp/websocket_server.py +10 -0
- crackerjack/models/README.md +308 -0
- crackerjack/models/__init__.py +40 -0
- crackerjack/models/config.py +730 -0
- crackerjack/models/config_adapter.py +265 -0
- crackerjack/models/protocols.py +1535 -0
- crackerjack/models/pydantic_models.py +320 -0
- crackerjack/models/qa_config.py +145 -0
- crackerjack/models/qa_results.py +134 -0
- crackerjack/models/resource_protocols.py +299 -0
- crackerjack/models/results.py +35 -0
- crackerjack/models/semantic_models.py +258 -0
- crackerjack/models/task.py +173 -0
- crackerjack/models/test_models.py +60 -0
- crackerjack/monitoring/README.md +11 -0
- crackerjack/monitoring/__init__.py +0 -0
- crackerjack/monitoring/ai_agent_watchdog.py +405 -0
- crackerjack/monitoring/metrics_collector.py +427 -0
- crackerjack/monitoring/regression_prevention.py +580 -0
- crackerjack/monitoring/websocket_server.py +406 -0
- crackerjack/orchestration/README.md +340 -0
- crackerjack/orchestration/__init__.py +43 -0
- crackerjack/orchestration/advanced_orchestrator.py +894 -0
- crackerjack/orchestration/cache/README.md +312 -0
- crackerjack/orchestration/cache/__init__.py +37 -0
- crackerjack/orchestration/cache/memory_cache.py +338 -0
- crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
- crackerjack/orchestration/config.py +297 -0
- crackerjack/orchestration/coverage_improvement.py +180 -0
- crackerjack/orchestration/execution_strategies.py +361 -0
- crackerjack/orchestration/hook_orchestrator.py +1398 -0
- crackerjack/orchestration/strategies/README.md +401 -0
- crackerjack/orchestration/strategies/__init__.py +39 -0
- crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
- crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
- crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
- crackerjack/orchestration/test_progress_streamer.py +647 -0
- crackerjack/plugins/README.md +11 -0
- crackerjack/plugins/__init__.py +15 -0
- crackerjack/plugins/base.py +200 -0
- crackerjack/plugins/hooks.py +254 -0
- crackerjack/plugins/loader.py +335 -0
- crackerjack/plugins/managers.py +264 -0
- crackerjack/py313.py +191 -0
- crackerjack/security/README.md +11 -0
- crackerjack/security/__init__.py +0 -0
- crackerjack/security/audit.py +197 -0
- crackerjack/services/README.md +374 -0
- crackerjack/services/__init__.py +9 -0
- crackerjack/services/ai/README.md +295 -0
- crackerjack/services/ai/__init__.py +7 -0
- crackerjack/services/ai/advanced_optimizer.py +878 -0
- crackerjack/services/ai/contextual_ai_assistant.py +542 -0
- crackerjack/services/ai/embeddings.py +444 -0
- crackerjack/services/ai/intelligent_commit.py +328 -0
- crackerjack/services/ai/predictive_analytics.py +510 -0
- crackerjack/services/anomaly_detector.py +392 -0
- crackerjack/services/api_extractor.py +617 -0
- crackerjack/services/backup_service.py +467 -0
- crackerjack/services/bounded_status_operations.py +530 -0
- crackerjack/services/cache.py +369 -0
- crackerjack/services/changelog_automation.py +399 -0
- crackerjack/services/command_execution_service.py +305 -0
- crackerjack/services/config_integrity.py +132 -0
- crackerjack/services/config_merge.py +546 -0
- crackerjack/services/config_service.py +198 -0
- crackerjack/services/config_template.py +493 -0
- crackerjack/services/coverage_badge_service.py +173 -0
- crackerjack/services/coverage_ratchet.py +381 -0
- crackerjack/services/debug.py +733 -0
- crackerjack/services/dependency_analyzer.py +460 -0
- crackerjack/services/dependency_monitor.py +622 -0
- crackerjack/services/documentation_generator.py +493 -0
- crackerjack/services/documentation_service.py +704 -0
- crackerjack/services/enhanced_filesystem.py +497 -0
- crackerjack/services/enterprise_optimizer.py +865 -0
- crackerjack/services/error_pattern_analyzer.py +676 -0
- crackerjack/services/file_filter.py +221 -0
- crackerjack/services/file_hasher.py +149 -0
- crackerjack/services/file_io_service.py +361 -0
- crackerjack/services/file_modifier.py +615 -0
- crackerjack/services/filesystem.py +381 -0
- crackerjack/services/git.py +422 -0
- crackerjack/services/health_metrics.py +615 -0
- crackerjack/services/heatmap_generator.py +744 -0
- crackerjack/services/incremental_executor.py +380 -0
- crackerjack/services/initialization.py +823 -0
- crackerjack/services/input_validator.py +668 -0
- crackerjack/services/intelligent_commit.py +327 -0
- crackerjack/services/log_manager.py +289 -0
- crackerjack/services/logging.py +228 -0
- crackerjack/services/lsp_client.py +628 -0
- crackerjack/services/memory_optimizer.py +414 -0
- crackerjack/services/metrics.py +587 -0
- crackerjack/services/monitoring/README.md +30 -0
- crackerjack/services/monitoring/__init__.py +9 -0
- crackerjack/services/monitoring/dependency_monitor.py +678 -0
- crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
- crackerjack/services/monitoring/health_metrics.py +716 -0
- crackerjack/services/monitoring/metrics.py +587 -0
- crackerjack/services/monitoring/performance_benchmarks.py +410 -0
- crackerjack/services/monitoring/performance_cache.py +388 -0
- crackerjack/services/monitoring/performance_monitor.py +569 -0
- crackerjack/services/parallel_executor.py +527 -0
- crackerjack/services/pattern_cache.py +333 -0
- crackerjack/services/pattern_detector.py +478 -0
- crackerjack/services/patterns/__init__.py +142 -0
- crackerjack/services/patterns/agents.py +107 -0
- crackerjack/services/patterns/code/__init__.py +15 -0
- crackerjack/services/patterns/code/detection.py +118 -0
- crackerjack/services/patterns/code/imports.py +107 -0
- crackerjack/services/patterns/code/paths.py +159 -0
- crackerjack/services/patterns/code/performance.py +119 -0
- crackerjack/services/patterns/code/replacement.py +36 -0
- crackerjack/services/patterns/core.py +212 -0
- crackerjack/services/patterns/documentation/__init__.py +14 -0
- crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
- crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
- crackerjack/services/patterns/documentation/docstrings.py +89 -0
- crackerjack/services/patterns/formatting.py +226 -0
- crackerjack/services/patterns/operations.py +339 -0
- crackerjack/services/patterns/security/__init__.py +23 -0
- crackerjack/services/patterns/security/code_injection.py +122 -0
- crackerjack/services/patterns/security/credentials.py +190 -0
- crackerjack/services/patterns/security/path_traversal.py +221 -0
- crackerjack/services/patterns/security/unsafe_operations.py +216 -0
- crackerjack/services/patterns/templates.py +62 -0
- crackerjack/services/patterns/testing/__init__.py +18 -0
- crackerjack/services/patterns/testing/error_patterns.py +107 -0
- crackerjack/services/patterns/testing/pytest_output.py +126 -0
- crackerjack/services/patterns/tool_output/__init__.py +16 -0
- crackerjack/services/patterns/tool_output/bandit.py +72 -0
- crackerjack/services/patterns/tool_output/other.py +97 -0
- crackerjack/services/patterns/tool_output/pyright.py +67 -0
- crackerjack/services/patterns/tool_output/ruff.py +44 -0
- crackerjack/services/patterns/url_sanitization.py +114 -0
- crackerjack/services/patterns/utilities.py +42 -0
- crackerjack/services/patterns/utils.py +339 -0
- crackerjack/services/patterns/validation.py +46 -0
- crackerjack/services/patterns/versioning.py +62 -0
- crackerjack/services/predictive_analytics.py +523 -0
- crackerjack/services/profiler.py +280 -0
- crackerjack/services/quality/README.md +415 -0
- crackerjack/services/quality/__init__.py +11 -0
- crackerjack/services/quality/anomaly_detector.py +392 -0
- crackerjack/services/quality/pattern_cache.py +333 -0
- crackerjack/services/quality/pattern_detector.py +479 -0
- crackerjack/services/quality/qa_orchestrator.py +491 -0
- crackerjack/services/quality/quality_baseline.py +395 -0
- crackerjack/services/quality/quality_baseline_enhanced.py +649 -0
- crackerjack/services/quality/quality_intelligence.py +949 -0
- crackerjack/services/regex_patterns.py +58 -0
- crackerjack/services/regex_utils.py +483 -0
- crackerjack/services/secure_path_utils.py +524 -0
- crackerjack/services/secure_status_formatter.py +450 -0
- crackerjack/services/secure_subprocess.py +635 -0
- crackerjack/services/security.py +239 -0
- crackerjack/services/security_logger.py +495 -0
- crackerjack/services/server_manager.py +411 -0
- crackerjack/services/smart_scheduling.py +167 -0
- crackerjack/services/status_authentication.py +460 -0
- crackerjack/services/status_security_manager.py +315 -0
- crackerjack/services/terminal_utils.py +0 -0
- crackerjack/services/thread_safe_status_collector.py +441 -0
- crackerjack/services/tool_filter.py +368 -0
- crackerjack/services/tool_version_service.py +43 -0
- crackerjack/services/unified_config.py +115 -0
- crackerjack/services/validation_rate_limiter.py +220 -0
- crackerjack/services/vector_store.py +689 -0
- crackerjack/services/version_analyzer.py +461 -0
- crackerjack/services/version_checker.py +223 -0
- crackerjack/services/websocket_resource_limiter.py +438 -0
- crackerjack/services/zuban_lsp_service.py +391 -0
- crackerjack/slash_commands/README.md +11 -0
- crackerjack/slash_commands/__init__.py +59 -0
- crackerjack/slash_commands/init.md +112 -0
- crackerjack/slash_commands/run.md +197 -0
- crackerjack/slash_commands/status.md +127 -0
- crackerjack/tools/README.md +11 -0
- crackerjack/tools/__init__.py +30 -0
- crackerjack/tools/_git_utils.py +105 -0
- crackerjack/tools/check_added_large_files.py +139 -0
- crackerjack/tools/check_ast.py +105 -0
- crackerjack/tools/check_json.py +103 -0
- crackerjack/tools/check_jsonschema.py +297 -0
- crackerjack/tools/check_toml.py +103 -0
- crackerjack/tools/check_yaml.py +110 -0
- crackerjack/tools/codespell_wrapper.py +72 -0
- crackerjack/tools/end_of_file_fixer.py +202 -0
- crackerjack/tools/format_json.py +128 -0
- crackerjack/tools/mdformat_wrapper.py +114 -0
- crackerjack/tools/trailing_whitespace.py +198 -0
- crackerjack/tools/validate_input_validator_patterns.py +236 -0
- crackerjack/tools/validate_regex_patterns.py +188 -0
- crackerjack/ui/README.md +11 -0
- crackerjack/ui/__init__.py +1 -0
- crackerjack/ui/dashboard_renderer.py +28 -0
- crackerjack/ui/templates/README.md +11 -0
- crackerjack/utils/console_utils.py +13 -0
- crackerjack/utils/dependency_guard.py +230 -0
- crackerjack/utils/retry_utils.py +275 -0
- crackerjack/workflows/README.md +590 -0
- crackerjack/workflows/__init__.py +46 -0
- crackerjack/workflows/actions.py +811 -0
- crackerjack/workflows/auto_fix.py +444 -0
- crackerjack/workflows/container_builder.py +499 -0
- crackerjack/workflows/definitions.py +443 -0
- crackerjack/workflows/engine.py +177 -0
- crackerjack/workflows/event_bridge.py +242 -0
- crackerjack-0.45.2.dist-info/METADATA +1678 -0
- crackerjack-0.45.2.dist-info/RECORD +478 -0
- {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
- crackerjack-0.45.2.dist-info/entry_points.txt +2 -0
- crackerjack/.gitignore +0 -14
- crackerjack/.libcst.codemod.yaml +0 -18
- crackerjack/.pdm.toml +0 -1
- crackerjack/.pre-commit-config.yaml +0 -91
- crackerjack/.pytest_cache/.gitignore +0 -2
- crackerjack/.pytest_cache/CACHEDIR.TAG +0 -4
- crackerjack/.pytest_cache/README.md +0 -8
- crackerjack/.pytest_cache/v/cache/nodeids +0 -1
- crackerjack/.pytest_cache/v/cache/stepwise +0 -1
- crackerjack/.ruff_cache/.gitignore +0 -1
- crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
- crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
- crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
- crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
- crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
- crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
- crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
- crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
- crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
- crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
- crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
- crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
- crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
- crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
- crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
- crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
- crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
- crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
- crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
- crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
- crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
- crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
- crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
- crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
- crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
- crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
- crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
- crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
- crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
- crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
- crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
- crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
- crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
- crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
- crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
- crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
- crackerjack/.ruff_cache/CACHEDIR.TAG +0 -1
- crackerjack/crackerjack.py +0 -855
- crackerjack/pyproject.toml +0 -214
- crackerjack-0.18.2.dist-info/METADATA +0 -420
- crackerjack-0.18.2.dist-info/RECORD +0 -59
- crackerjack-0.18.2.dist-info/entry_points.txt +0 -4
- {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
import typing as t
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from .base import (
|
|
6
|
+
AgentContext,
|
|
7
|
+
FixResult,
|
|
8
|
+
Issue,
|
|
9
|
+
IssueType,
|
|
10
|
+
SubAgent,
|
|
11
|
+
agent_registry,
|
|
12
|
+
)
|
|
13
|
+
from .helpers.refactoring.code_transformer import CodeTransformer
|
|
14
|
+
from .helpers.refactoring.complexity_analyzer import ComplexityAnalyzer
|
|
15
|
+
from .helpers.refactoring.dead_code_detector import DeadCodeDetector
|
|
16
|
+
from .semantic_helpers import (
|
|
17
|
+
SemanticInsight,
|
|
18
|
+
create_semantic_enhancer,
|
|
19
|
+
get_session_enhanced_recommendations,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class RefactoringAgent(SubAgent):
|
|
24
|
+
def __init__(self, context: AgentContext) -> None:
|
|
25
|
+
super().__init__(context)
|
|
26
|
+
self.semantic_enhancer = create_semantic_enhancer(context.project_path)
|
|
27
|
+
self.semantic_insights: dict[str, SemanticInsight] = {}
|
|
28
|
+
|
|
29
|
+
# Initialize helper modules
|
|
30
|
+
self._complexity_analyzer = ComplexityAnalyzer(context)
|
|
31
|
+
self._code_transformer = CodeTransformer(context)
|
|
32
|
+
self._dead_code_detector = DeadCodeDetector(context)
|
|
33
|
+
|
|
34
|
+
def get_supported_types(self) -> set[IssueType]:
|
|
35
|
+
return {IssueType.COMPLEXITY, IssueType.DEAD_CODE}
|
|
36
|
+
|
|
37
|
+
async def can_handle(self, issue: Issue) -> float:
|
|
38
|
+
if issue.type == IssueType.COMPLEXITY:
|
|
39
|
+
return 0.9 if self._has_complexity_markers(issue) else 0.85
|
|
40
|
+
if issue.type == IssueType.DEAD_CODE:
|
|
41
|
+
return 0.8 if self._has_dead_code_markers(issue) else 0.75
|
|
42
|
+
return 0.0
|
|
43
|
+
|
|
44
|
+
def _has_complexity_markers(self, issue: Issue) -> bool:
|
|
45
|
+
if not issue.message:
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
complexity_indicators = [
|
|
49
|
+
"cognitive complexity",
|
|
50
|
+
"too complex",
|
|
51
|
+
"nested",
|
|
52
|
+
"cyclomatic",
|
|
53
|
+
"long function",
|
|
54
|
+
"too many branches",
|
|
55
|
+
"too many conditions",
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
return any(
|
|
59
|
+
indicator in issue.message.lower() for indicator in complexity_indicators
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def _has_dead_code_markers(self, issue: Issue) -> bool:
|
|
63
|
+
if not issue.message:
|
|
64
|
+
return False
|
|
65
|
+
|
|
66
|
+
dead_code_indicators = [
|
|
67
|
+
"unused",
|
|
68
|
+
"imported but unused",
|
|
69
|
+
"defined but not used",
|
|
70
|
+
"unreachable",
|
|
71
|
+
"dead code",
|
|
72
|
+
"never used",
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
return any(
|
|
76
|
+
indicator in issue.message.lower() for indicator in dead_code_indicators
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
async def analyze_and_fix(self, issue: Issue) -> FixResult:
|
|
80
|
+
self.log(f"Analyzing {issue.type.value} issue: {issue.message}")
|
|
81
|
+
|
|
82
|
+
if issue.type == IssueType.COMPLEXITY:
|
|
83
|
+
return await self._reduce_complexity(issue)
|
|
84
|
+
if issue.type == IssueType.DEAD_CODE:
|
|
85
|
+
return await self._remove_dead_code(issue)
|
|
86
|
+
|
|
87
|
+
return FixResult(
|
|
88
|
+
success=False,
|
|
89
|
+
confidence=0.0,
|
|
90
|
+
remaining_issues=[f"RefactoringAgent cannot handle {issue.type.value}"],
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
async def _reduce_complexity(self, issue: Issue) -> FixResult:
|
|
94
|
+
validation_result = self._validate_complexity_issue(issue)
|
|
95
|
+
if validation_result:
|
|
96
|
+
return validation_result
|
|
97
|
+
|
|
98
|
+
if issue.file_path is None:
|
|
99
|
+
return FixResult(
|
|
100
|
+
success=False,
|
|
101
|
+
confidence=0.0,
|
|
102
|
+
remaining_issues=["No file path provided for complexity issue"],
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
file_path = Path(issue.file_path)
|
|
106
|
+
|
|
107
|
+
if "detect_agent_needs" in issue.message:
|
|
108
|
+
return await self._apply_known_complexity_fix(file_path, issue)
|
|
109
|
+
|
|
110
|
+
try:
|
|
111
|
+
return await self._process_complexity_reduction(file_path)
|
|
112
|
+
except SyntaxError as e:
|
|
113
|
+
return self._create_syntax_error_result(e)
|
|
114
|
+
except Exception as e:
|
|
115
|
+
return self._create_general_error_result(e)
|
|
116
|
+
|
|
117
|
+
async def _apply_known_complexity_fix(
|
|
118
|
+
self, file_path: Path, issue: Issue
|
|
119
|
+
) -> FixResult:
|
|
120
|
+
content = self.context.get_file_content(file_path)
|
|
121
|
+
if not content:
|
|
122
|
+
return FixResult(
|
|
123
|
+
success=False,
|
|
124
|
+
confidence=0.0,
|
|
125
|
+
remaining_issues=[f"Could not read file: {file_path}"],
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Delegate to code transformer helper
|
|
129
|
+
refactored_content = self._code_transformer.refactor_detect_agent_needs_pattern(
|
|
130
|
+
content
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
if refactored_content != content:
|
|
134
|
+
success = self.context.write_file_content(file_path, refactored_content)
|
|
135
|
+
if success:
|
|
136
|
+
return FixResult(
|
|
137
|
+
success=True,
|
|
138
|
+
confidence=0.9,
|
|
139
|
+
fixes_applied=[
|
|
140
|
+
"Applied proven complexity reduction pattern for detect_agent_needs"
|
|
141
|
+
],
|
|
142
|
+
files_modified=[str(file_path)],
|
|
143
|
+
recommendations=await self._enhance_recommendations_with_semantic(
|
|
144
|
+
["Verify functionality after complexity reduction"]
|
|
145
|
+
),
|
|
146
|
+
)
|
|
147
|
+
else:
|
|
148
|
+
return FixResult(
|
|
149
|
+
success=False,
|
|
150
|
+
confidence=0.0,
|
|
151
|
+
remaining_issues=[
|
|
152
|
+
f"Failed to write refactored content to {file_path}"
|
|
153
|
+
],
|
|
154
|
+
)
|
|
155
|
+
else:
|
|
156
|
+
return FixResult(
|
|
157
|
+
success=False,
|
|
158
|
+
confidence=0.3,
|
|
159
|
+
remaining_issues=[
|
|
160
|
+
"Refactoring pattern did not apply to current file content"
|
|
161
|
+
],
|
|
162
|
+
recommendations=[
|
|
163
|
+
"File may have been modified since pattern was created"
|
|
164
|
+
],
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def _validate_complexity_issue(self, issue: Issue) -> FixResult | None:
|
|
168
|
+
if not issue.file_path:
|
|
169
|
+
return FixResult(
|
|
170
|
+
success=False,
|
|
171
|
+
confidence=0.0,
|
|
172
|
+
remaining_issues=["No file path specified for complexity issue"],
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
file_path = Path(issue.file_path)
|
|
176
|
+
if not file_path.exists():
|
|
177
|
+
return FixResult(
|
|
178
|
+
success=False,
|
|
179
|
+
confidence=0.0,
|
|
180
|
+
remaining_issues=[f"File not found: {file_path}"],
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
return None
|
|
184
|
+
|
|
185
|
+
async def _process_complexity_reduction(self, file_path: Path) -> FixResult:
|
|
186
|
+
content = self.context.get_file_content(file_path)
|
|
187
|
+
if not content:
|
|
188
|
+
return FixResult(
|
|
189
|
+
success=False,
|
|
190
|
+
confidence=0.0,
|
|
191
|
+
remaining_issues=[f"Could not read file: {file_path}"],
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
tree = ast.parse(content)
|
|
195
|
+
# Delegate to complexity analyzer helper
|
|
196
|
+
complex_functions = self._complexity_analyzer.find_complex_functions(
|
|
197
|
+
tree, content
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
# Enhance complex function detection with semantic analysis
|
|
201
|
+
semantic_complex_functions = await self._find_semantic_complex_patterns(
|
|
202
|
+
content, file_path
|
|
203
|
+
)
|
|
204
|
+
if semantic_complex_functions:
|
|
205
|
+
complex_functions.extend(semantic_complex_functions)
|
|
206
|
+
|
|
207
|
+
if not complex_functions:
|
|
208
|
+
return FixResult(
|
|
209
|
+
success=True,
|
|
210
|
+
confidence=0.7,
|
|
211
|
+
recommendations=["No overly complex functions found"],
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
return await self._apply_and_save_refactoring(
|
|
215
|
+
file_path, content, complex_functions
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
async def _apply_and_save_refactoring(
|
|
219
|
+
self,
|
|
220
|
+
file_path: Path,
|
|
221
|
+
content: str,
|
|
222
|
+
complex_functions: list[dict[str, t.Any]],
|
|
223
|
+
) -> FixResult:
|
|
224
|
+
# Delegate refactoring to code transformer helper
|
|
225
|
+
refactored_content = self._code_transformer.refactor_complex_functions(
|
|
226
|
+
content, complex_functions
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
if refactored_content == content:
|
|
230
|
+
# Try enhanced strategies if basic refactoring didn't work
|
|
231
|
+
refactored_content = self._code_transformer.apply_enhanced_strategies(
|
|
232
|
+
content
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
if refactored_content == content:
|
|
236
|
+
return self._create_no_changes_result()
|
|
237
|
+
|
|
238
|
+
success = self.context.write_file_content(file_path, refactored_content)
|
|
239
|
+
if not success:
|
|
240
|
+
return FixResult(
|
|
241
|
+
success=False,
|
|
242
|
+
confidence=0.0,
|
|
243
|
+
remaining_issues=[f"Failed to write refactored file: {file_path}"],
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
return FixResult(
|
|
247
|
+
success=True,
|
|
248
|
+
confidence=0.8,
|
|
249
|
+
fixes_applied=[f"Reduced complexity in {len(complex_functions)} functions"],
|
|
250
|
+
files_modified=[str(file_path)],
|
|
251
|
+
recommendations=await self._enhance_recommendations_with_semantic(
|
|
252
|
+
["Verify functionality after complexity reduction"]
|
|
253
|
+
),
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
def _create_no_changes_result(self) -> FixResult:
|
|
257
|
+
return FixResult(
|
|
258
|
+
success=False,
|
|
259
|
+
confidence=0.5,
|
|
260
|
+
remaining_issues=["Could not automatically reduce complexity"],
|
|
261
|
+
recommendations=[
|
|
262
|
+
"Manual refactoring required",
|
|
263
|
+
"Consider breaking down complex conditionals",
|
|
264
|
+
"Extract helper methods for repeated patterns",
|
|
265
|
+
],
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
def _create_syntax_error_result(self, error: SyntaxError) -> FixResult:
|
|
269
|
+
return FixResult(
|
|
270
|
+
success=False,
|
|
271
|
+
confidence=0.0,
|
|
272
|
+
remaining_issues=[f"Syntax error in file: {error}"],
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
def _create_general_error_result(self, error: Exception) -> FixResult:
|
|
276
|
+
return FixResult(
|
|
277
|
+
success=False,
|
|
278
|
+
confidence=0.0,
|
|
279
|
+
remaining_issues=[f"Error processing file: {error}"],
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
async def _remove_dead_code(self, issue: Issue) -> FixResult:
|
|
283
|
+
validation_result = self._validate_dead_code_issue(issue)
|
|
284
|
+
if validation_result:
|
|
285
|
+
return validation_result
|
|
286
|
+
|
|
287
|
+
if issue.file_path is None:
|
|
288
|
+
return FixResult(
|
|
289
|
+
success=False,
|
|
290
|
+
confidence=0.0,
|
|
291
|
+
remaining_issues=["No file path provided for dead code issue"],
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
file_path = Path(issue.file_path)
|
|
295
|
+
|
|
296
|
+
try:
|
|
297
|
+
return await self._process_dead_code_removal(file_path)
|
|
298
|
+
except SyntaxError as e:
|
|
299
|
+
return self._create_syntax_error_result(e)
|
|
300
|
+
except Exception as e:
|
|
301
|
+
return self._create_dead_code_error_result(e)
|
|
302
|
+
|
|
303
|
+
def _validate_dead_code_issue(self, issue: Issue) -> FixResult | None:
|
|
304
|
+
if not issue.file_path:
|
|
305
|
+
return FixResult(
|
|
306
|
+
success=False,
|
|
307
|
+
confidence=0.0,
|
|
308
|
+
remaining_issues=["No file path specified for dead code issue"],
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
file_path = Path(issue.file_path)
|
|
312
|
+
if not file_path.exists():
|
|
313
|
+
return FixResult(
|
|
314
|
+
success=False,
|
|
315
|
+
confidence=0.0,
|
|
316
|
+
remaining_issues=[f"File not found: {file_path}"],
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
return None
|
|
320
|
+
|
|
321
|
+
async def _process_dead_code_removal(self, file_path: Path) -> FixResult:
|
|
322
|
+
content = self.context.get_file_content(file_path)
|
|
323
|
+
if not content:
|
|
324
|
+
return FixResult(
|
|
325
|
+
success=False,
|
|
326
|
+
confidence=0.0,
|
|
327
|
+
remaining_issues=[f"Could not read file: {file_path}"],
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
tree = ast.parse(content)
|
|
331
|
+
# Delegate to dead code detector helper
|
|
332
|
+
dead_code_analysis = self._dead_code_detector.analyze_dead_code(tree, content)
|
|
333
|
+
|
|
334
|
+
if not dead_code_analysis["removable_items"]:
|
|
335
|
+
return FixResult(
|
|
336
|
+
success=True,
|
|
337
|
+
confidence=0.7,
|
|
338
|
+
recommendations=["No obvious dead code found"],
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
return self._apply_and_save_cleanup(file_path, content, dead_code_analysis)
|
|
342
|
+
|
|
343
|
+
def _apply_and_save_cleanup(
|
|
344
|
+
self,
|
|
345
|
+
file_path: Path,
|
|
346
|
+
content: str,
|
|
347
|
+
analysis: dict[str, t.Any],
|
|
348
|
+
) -> FixResult:
|
|
349
|
+
# Remove dead code items
|
|
350
|
+
lines = content.split("\n")
|
|
351
|
+
lines_to_remove = self._collect_all_removable_lines(lines, analysis)
|
|
352
|
+
|
|
353
|
+
filtered_lines = [
|
|
354
|
+
line for i, line in enumerate(lines) if i not in lines_to_remove
|
|
355
|
+
]
|
|
356
|
+
cleaned_content = "\n".join(filtered_lines)
|
|
357
|
+
|
|
358
|
+
if cleaned_content == content:
|
|
359
|
+
return self._create_no_cleanup_result()
|
|
360
|
+
|
|
361
|
+
success = self.context.write_file_content(file_path, cleaned_content)
|
|
362
|
+
if not success:
|
|
363
|
+
return FixResult(
|
|
364
|
+
success=False,
|
|
365
|
+
confidence=0.0,
|
|
366
|
+
remaining_issues=[f"Failed to write cleaned file: {file_path}"],
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
removed_count = len(analysis["removable_items"])
|
|
370
|
+
return FixResult(
|
|
371
|
+
success=True,
|
|
372
|
+
confidence=0.8,
|
|
373
|
+
fixes_applied=[f"Removed {removed_count} dead code items"],
|
|
374
|
+
files_modified=[str(file_path)],
|
|
375
|
+
recommendations=["Verify imports and functionality after cleanup"],
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
def _collect_all_removable_lines(
|
|
379
|
+
self, lines: list[str], analysis: dict[str, t.Any]
|
|
380
|
+
) -> set[int]:
|
|
381
|
+
"""Collect all lines to remove from analysis."""
|
|
382
|
+
lines_to_remove: set[int] = set()
|
|
383
|
+
|
|
384
|
+
# Delegate to dead code detector helper for different removal types
|
|
385
|
+
lines_to_remove.update(
|
|
386
|
+
self._dead_code_detector.find_lines_to_remove(lines, analysis)
|
|
387
|
+
)
|
|
388
|
+
lines_to_remove.update(
|
|
389
|
+
self._dead_code_detector._find_unreachable_lines(lines, analysis)
|
|
390
|
+
)
|
|
391
|
+
lines_to_remove.update(
|
|
392
|
+
self._dead_code_detector._find_redundant_lines(lines, analysis)
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
return lines_to_remove
|
|
396
|
+
|
|
397
|
+
def _create_no_cleanup_result(self) -> FixResult:
|
|
398
|
+
return FixResult(
|
|
399
|
+
success=False,
|
|
400
|
+
confidence=0.5,
|
|
401
|
+
remaining_issues=["Could not automatically remove dead code"],
|
|
402
|
+
recommendations=[
|
|
403
|
+
"Manual review required",
|
|
404
|
+
"Check for unused imports with tools like vulture",
|
|
405
|
+
],
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
def _create_dead_code_error_result(self, error: Exception) -> FixResult:
|
|
409
|
+
return FixResult(
|
|
410
|
+
success=False,
|
|
411
|
+
confidence=0.0,
|
|
412
|
+
remaining_issues=[f"Error processing file: {error}"],
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
async def _find_semantic_complex_patterns(
|
|
416
|
+
self, content: str, file_path: Path
|
|
417
|
+
) -> list[dict[str, t.Any]]:
|
|
418
|
+
"""Find semantically complex patterns using vector similarity."""
|
|
419
|
+
semantic_functions = []
|
|
420
|
+
|
|
421
|
+
try:
|
|
422
|
+
# Delegate to complexity analyzer helper
|
|
423
|
+
code_elements = (
|
|
424
|
+
self._complexity_analyzer.extract_code_functions_for_semantic_analysis(
|
|
425
|
+
content
|
|
426
|
+
)
|
|
427
|
+
)
|
|
428
|
+
|
|
429
|
+
for element in code_elements:
|
|
430
|
+
if (
|
|
431
|
+
element["type"] == "function"
|
|
432
|
+
and element["estimated_complexity"] > 10
|
|
433
|
+
):
|
|
434
|
+
# Search for similar complex patterns
|
|
435
|
+
insight = (
|
|
436
|
+
await self.semantic_enhancer.find_refactoring_opportunities(
|
|
437
|
+
element["signature"]
|
|
438
|
+
+ "\n"
|
|
439
|
+
+ element["body"][:150], # Include body sample
|
|
440
|
+
current_file=file_path,
|
|
441
|
+
)
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
if insight.total_matches > 2:
|
|
445
|
+
semantic_functions.append(
|
|
446
|
+
{
|
|
447
|
+
"name": element["name"],
|
|
448
|
+
"line_start": element["start_line"],
|
|
449
|
+
"line_end": element["end_line"],
|
|
450
|
+
"complexity": element["estimated_complexity"],
|
|
451
|
+
"semantic_matches": insight.total_matches,
|
|
452
|
+
"refactor_opportunities": insight.related_patterns[
|
|
453
|
+
:3
|
|
454
|
+
], # Top 3 matches
|
|
455
|
+
"node": element.get("node"),
|
|
456
|
+
}
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
# Store insight for recommendation enhancement
|
|
460
|
+
self.semantic_insights[element["name"]] = insight
|
|
461
|
+
|
|
462
|
+
except Exception as e:
|
|
463
|
+
self.log(f"Warning: Semantic complexity detection failed: {e}")
|
|
464
|
+
|
|
465
|
+
return semantic_functions
|
|
466
|
+
|
|
467
|
+
async def _enhance_recommendations_with_semantic(
|
|
468
|
+
self, base_recommendations: list[str]
|
|
469
|
+
) -> list[str]:
|
|
470
|
+
"""Enhance recommendations with semantic insights."""
|
|
471
|
+
enhanced = base_recommendations.copy()
|
|
472
|
+
|
|
473
|
+
# Add semantic insights if available
|
|
474
|
+
if self.semantic_insights:
|
|
475
|
+
total_semantic_matches = sum(
|
|
476
|
+
insight.total_matches for insight in self.semantic_insights.values()
|
|
477
|
+
)
|
|
478
|
+
high_conf_matches = sum(
|
|
479
|
+
insight.high_confidence_matches
|
|
480
|
+
for insight in self.semantic_insights.values()
|
|
481
|
+
)
|
|
482
|
+
|
|
483
|
+
if high_conf_matches > 0:
|
|
484
|
+
enhanced.append(
|
|
485
|
+
f"Semantic analysis found {high_conf_matches} similar complex patterns - "
|
|
486
|
+
f"consider extracting common refactoring utilities"
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
if total_semantic_matches >= 3:
|
|
490
|
+
enhanced.append(
|
|
491
|
+
f"Found {total_semantic_matches} related complexity patterns across codebase - "
|
|
492
|
+
f"review for consistent refactoring approach"
|
|
493
|
+
)
|
|
494
|
+
|
|
495
|
+
# Store insights for session continuity
|
|
496
|
+
for func_name, insight in self.semantic_insights.items():
|
|
497
|
+
summary = self.semantic_enhancer.get_semantic_context_summary(insight)
|
|
498
|
+
self.log(f"Semantic context for {func_name}: {summary}")
|
|
499
|
+
await self.semantic_enhancer.store_insight_to_session(
|
|
500
|
+
insight, "RefactoringAgent"
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
# Enhance with session-stored insights
|
|
504
|
+
enhanced = await get_session_enhanced_recommendations(
|
|
505
|
+
enhanced, "RefactoringAgent", self.context.project_path
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
return enhanced
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
agent_registry.register(RefactoringAgent)
|