crackerjack 0.37.9__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 +30 -1
- crackerjack/__main__.py +342 -1263
- crackerjack/adapters/README.md +18 -0
- crackerjack/adapters/__init__.py +27 -5
- 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/{rust_tool_manager.py → lsp/_manager.py} +3 -3
- crackerjack/adapters/{skylos_adapter.py → lsp/skylos.py} +59 -7
- crackerjack/adapters/{zuban_adapter.py → lsp/zuban.py} +3 -6
- 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 +40 -12
- crackerjack/agents/base.py +1 -0
- crackerjack/agents/claude_code_bridge.py +641 -0
- crackerjack/agents/coordinator.py +49 -53
- crackerjack/agents/dry_agent.py +187 -3
- 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 +6 -8
- 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/performance_agent.py +121 -1152
- crackerjack/agents/refactoring_agent.py +156 -655
- crackerjack/agents/semantic_agent.py +479 -0
- crackerjack/agents/semantic_helpers.py +356 -0
- crackerjack/agents/test_creation_agent.py +19 -1605
- crackerjack/api.py +5 -7
- crackerjack/cli/README.md +394 -0
- crackerjack/cli/__init__.py +1 -1
- crackerjack/cli/cache_handlers.py +23 -18
- crackerjack/cli/cache_handlers_enhanced.py +1 -4
- crackerjack/cli/facade.py +70 -8
- 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 +249 -49
- crackerjack/cli/interactive.py +8 -5
- crackerjack/cli/options.py +203 -110
- crackerjack/cli/semantic_handlers.py +292 -0
- crackerjack/cli/version.py +19 -0
- crackerjack/code_cleaner.py +60 -24
- crackerjack/config/README.md +472 -0
- crackerjack/config/__init__.py +256 -0
- crackerjack/config/global_lock_config.py +191 -54
- crackerjack/config/hooks.py +188 -16
- 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/async_workflow_orchestrator.py +79 -53
- crackerjack/core/autofix_coordinator.py +22 -9
- crackerjack/core/container.py +10 -9
- crackerjack/core/enhanced_container.py +9 -9
- crackerjack/core/performance.py +1 -1
- crackerjack/core/performance_monitor.py +5 -3
- crackerjack/core/phase_coordinator.py +1018 -634
- crackerjack/core/proactive_workflow.py +3 -3
- crackerjack/core/retry.py +275 -0
- crackerjack/core/service_watchdog.py +167 -23
- crackerjack/core/session_coordinator.py +187 -382
- crackerjack/core/timeout_manager.py +161 -44
- 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 +1247 -953
- 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/README.md +11 -0
- crackerjack/docs/generated/api/CLI_REFERENCE.md +1 -1
- crackerjack/documentation/README.md +11 -0
- crackerjack/documentation/ai_templates.py +1 -1
- crackerjack/documentation/dual_output_generator.py +11 -9
- crackerjack/documentation/reference_generator.py +104 -59
- crackerjack/dynamic_config.py +52 -61
- crackerjack/errors.py +1 -1
- 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 +2 -0
- crackerjack/executors/async_hook_executor.py +539 -77
- crackerjack/executors/cached_hook_executor.py +3 -3
- crackerjack/executors/hook_executor.py +967 -102
- crackerjack/executors/hook_lock_manager.py +31 -22
- crackerjack/executors/individual_hook_executor.py +66 -32
- crackerjack/executors/lsp_aware_hook_executor.py +136 -57
- crackerjack/executors/progress_hook_executor.py +282 -0
- crackerjack/executors/tool_proxy.py +23 -7
- crackerjack/hooks/README.md +485 -0
- crackerjack/hooks/lsp_hook.py +8 -9
- crackerjack/intelligence/README.md +557 -0
- crackerjack/interactive.py +37 -10
- crackerjack/managers/README.md +369 -0
- crackerjack/managers/async_hook_manager.py +41 -57
- crackerjack/managers/hook_manager.py +449 -79
- crackerjack/managers/publish_manager.py +81 -36
- crackerjack/managers/test_command_builder.py +290 -12
- crackerjack/managers/test_executor.py +93 -8
- crackerjack/managers/test_manager.py +1082 -75
- crackerjack/managers/test_progress.py +118 -26
- crackerjack/mcp/README.md +374 -0
- crackerjack/mcp/cache.py +25 -2
- crackerjack/mcp/client_runner.py +35 -18
- crackerjack/mcp/context.py +9 -9
- crackerjack/mcp/dashboard.py +24 -8
- crackerjack/mcp/enhanced_progress_monitor.py +34 -23
- crackerjack/mcp/file_monitor.py +27 -6
- crackerjack/mcp/progress_components.py +45 -34
- crackerjack/mcp/progress_monitor.py +6 -9
- crackerjack/mcp/rate_limiter.py +11 -7
- crackerjack/mcp/server.py +2 -0
- crackerjack/mcp/server_core.py +187 -55
- crackerjack/mcp/service_watchdog.py +12 -9
- crackerjack/mcp/task_manager.py +2 -2
- crackerjack/mcp/tools/README.md +27 -0
- crackerjack/mcp/tools/__init__.py +2 -0
- crackerjack/mcp/tools/core_tools.py +75 -52
- crackerjack/mcp/tools/execution_tools.py +87 -31
- crackerjack/mcp/tools/intelligence_tools.py +2 -2
- crackerjack/mcp/tools/proactive_tools.py +1 -1
- crackerjack/mcp/tools/semantic_tools.py +584 -0
- crackerjack/mcp/tools/utility_tools.py +180 -132
- crackerjack/mcp/tools/workflow_executor.py +87 -46
- crackerjack/mcp/websocket/README.md +31 -0
- crackerjack/mcp/websocket/app.py +11 -1
- crackerjack/mcp/websocket/event_bridge.py +188 -0
- crackerjack/mcp/websocket/jobs.py +27 -4
- 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 +16 -2930
- crackerjack/mcp/websocket/server.py +1 -3
- crackerjack/mcp/websocket/websocket_handler.py +107 -6
- crackerjack/models/README.md +308 -0
- crackerjack/models/__init__.py +10 -1
- crackerjack/models/config.py +639 -22
- crackerjack/models/config_adapter.py +6 -6
- crackerjack/models/protocols.py +1167 -23
- crackerjack/models/pydantic_models.py +320 -0
- crackerjack/models/qa_config.py +145 -0
- crackerjack/models/qa_results.py +134 -0
- crackerjack/models/results.py +35 -0
- crackerjack/models/semantic_models.py +258 -0
- crackerjack/models/task.py +19 -3
- crackerjack/models/test_models.py +60 -0
- crackerjack/monitoring/README.md +11 -0
- crackerjack/monitoring/ai_agent_watchdog.py +5 -4
- crackerjack/monitoring/metrics_collector.py +4 -3
- crackerjack/monitoring/regression_prevention.py +4 -3
- crackerjack/monitoring/websocket_server.py +4 -241
- crackerjack/orchestration/README.md +340 -0
- crackerjack/orchestration/__init__.py +43 -0
- crackerjack/orchestration/advanced_orchestrator.py +20 -67
- 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 +13 -6
- crackerjack/orchestration/execution_strategies.py +6 -6
- 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 +1 -1
- crackerjack/plugins/README.md +11 -0
- crackerjack/plugins/hooks.py +3 -2
- crackerjack/plugins/loader.py +3 -3
- crackerjack/plugins/managers.py +1 -1
- crackerjack/py313.py +191 -0
- crackerjack/security/README.md +11 -0
- crackerjack/services/README.md +374 -0
- crackerjack/services/__init__.py +8 -21
- crackerjack/services/ai/README.md +295 -0
- crackerjack/services/ai/__init__.py +7 -0
- crackerjack/services/ai/advanced_optimizer.py +878 -0
- crackerjack/services/{contextual_ai_assistant.py → ai/contextual_ai_assistant.py} +5 -3
- 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/api_extractor.py +5 -3
- crackerjack/services/bounded_status_operations.py +45 -5
- crackerjack/services/cache.py +249 -318
- crackerjack/services/changelog_automation.py +7 -3
- crackerjack/services/command_execution_service.py +305 -0
- crackerjack/services/config_integrity.py +83 -39
- crackerjack/services/config_merge.py +9 -6
- crackerjack/services/config_service.py +198 -0
- crackerjack/services/config_template.py +13 -26
- crackerjack/services/coverage_badge_service.py +6 -4
- crackerjack/services/coverage_ratchet.py +53 -27
- crackerjack/services/debug.py +18 -7
- crackerjack/services/dependency_analyzer.py +4 -4
- crackerjack/services/dependency_monitor.py +13 -13
- crackerjack/services/documentation_generator.py +4 -2
- crackerjack/services/documentation_service.py +62 -33
- crackerjack/services/enhanced_filesystem.py +81 -27
- crackerjack/services/enterprise_optimizer.py +1 -1
- crackerjack/services/error_pattern_analyzer.py +10 -10
- crackerjack/services/file_filter.py +221 -0
- crackerjack/services/file_hasher.py +5 -7
- crackerjack/services/file_io_service.py +361 -0
- crackerjack/services/file_modifier.py +615 -0
- crackerjack/services/filesystem.py +80 -109
- crackerjack/services/git.py +99 -5
- crackerjack/services/health_metrics.py +4 -6
- crackerjack/services/heatmap_generator.py +12 -3
- crackerjack/services/incremental_executor.py +380 -0
- crackerjack/services/initialization.py +101 -49
- crackerjack/services/log_manager.py +2 -2
- crackerjack/services/logging.py +120 -68
- crackerjack/services/lsp_client.py +12 -12
- crackerjack/services/memory_optimizer.py +27 -22
- 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/{performance_benchmarks.py → monitoring/performance_benchmarks.py} +100 -14
- crackerjack/services/{performance_cache.py → monitoring/performance_cache.py} +21 -15
- crackerjack/services/{performance_monitor.py → monitoring/performance_monitor.py} +10 -6
- crackerjack/services/parallel_executor.py +166 -55
- 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 +21 -8
- 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_baseline.py → quality/quality_baseline.py} +163 -2
- crackerjack/services/{quality_baseline_enhanced.py → quality/quality_baseline_enhanced.py} +4 -1
- crackerjack/services/{quality_intelligence.py → quality/quality_intelligence.py} +180 -16
- crackerjack/services/regex_patterns.py +58 -2987
- crackerjack/services/regex_utils.py +55 -29
- crackerjack/services/secure_status_formatter.py +42 -15
- crackerjack/services/secure_subprocess.py +35 -2
- crackerjack/services/security.py +16 -8
- crackerjack/services/server_manager.py +40 -51
- crackerjack/services/smart_scheduling.py +46 -6
- crackerjack/services/status_authentication.py +3 -3
- crackerjack/services/thread_safe_status_collector.py +1 -0
- crackerjack/services/tool_filter.py +368 -0
- crackerjack/services/tool_version_service.py +9 -5
- crackerjack/services/unified_config.py +43 -351
- crackerjack/services/vector_store.py +689 -0
- crackerjack/services/version_analyzer.py +6 -4
- crackerjack/services/version_checker.py +14 -8
- crackerjack/services/zuban_lsp_service.py +5 -4
- crackerjack/slash_commands/README.md +11 -0
- crackerjack/slash_commands/init.md +2 -12
- crackerjack/slash_commands/run.md +84 -50
- 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_regex_patterns.py +7 -3
- crackerjack/ui/README.md +11 -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.37.9.dist-info → crackerjack-0.45.2.dist-info}/METADATA +678 -98
- crackerjack-0.45.2.dist-info/RECORD +478 -0
- {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
- crackerjack/managers/test_manager_backup.py +0 -1075
- crackerjack/mcp/tools/execution_tools_backup.py +0 -1011
- crackerjack/mixins/__init__.py +0 -3
- crackerjack/mixins/error_handling.py +0 -145
- crackerjack/services/config.py +0 -358
- crackerjack/ui/server_panels.py +0 -125
- crackerjack-0.37.9.dist-info/RECORD +0 -231
- /crackerjack/adapters/{rust_tool_adapter.py → lsp/_base.py} +0 -0
- /crackerjack/adapters/{lsp_client.py → lsp/_client.py} +0 -0
- {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/entry_points.txt +0 -0
- {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
"""Refurb adapter for ACB QA framework - Python refactoring suggestions.
|
|
2
|
+
|
|
3
|
+
Refurb is a tool for refactoring Python code, suggesting modern Python idioms
|
|
4
|
+
and best practices. It identifies:
|
|
5
|
+
- Outdated syntax patterns
|
|
6
|
+
- Inefficient constructs
|
|
7
|
+
- Opportunities to use modern Python features
|
|
8
|
+
- Code that can be simplified
|
|
9
|
+
|
|
10
|
+
ACB Patterns:
|
|
11
|
+
- MODULE_ID and MODULE_STATUS at module level
|
|
12
|
+
- depends.set() registration after class definition
|
|
13
|
+
- Extends BaseToolAdapter for tool execution
|
|
14
|
+
- Async execution with output parsing
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import logging
|
|
20
|
+
import typing as t
|
|
21
|
+
from contextlib import suppress
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from uuid import UUID
|
|
24
|
+
|
|
25
|
+
from acb.depends import depends
|
|
26
|
+
from pydantic import Field
|
|
27
|
+
|
|
28
|
+
from crackerjack.adapters._tool_adapter_base import (
|
|
29
|
+
BaseToolAdapter,
|
|
30
|
+
ToolAdapterSettings,
|
|
31
|
+
ToolExecutionResult,
|
|
32
|
+
ToolIssue,
|
|
33
|
+
)
|
|
34
|
+
from crackerjack.models.qa_results import QACheckType
|
|
35
|
+
|
|
36
|
+
if t.TYPE_CHECKING:
|
|
37
|
+
from crackerjack.models.qa_config import QACheckConfig
|
|
38
|
+
|
|
39
|
+
# ACB Module Registration (REQUIRED)
|
|
40
|
+
MODULE_ID = UUID(
|
|
41
|
+
"01937d86-7c3d-8e4f-9a5b-c6d7e8f9a0b1"
|
|
42
|
+
) # Static UUID7 for reproducible module identity
|
|
43
|
+
MODULE_STATUS = "stable"
|
|
44
|
+
|
|
45
|
+
# Module-level logger for structured logging
|
|
46
|
+
logger = logging.getLogger(__name__)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class RefurbSettings(ToolAdapterSettings):
|
|
50
|
+
"""Settings for Refurb adapter."""
|
|
51
|
+
|
|
52
|
+
tool_name: str = "refurb"
|
|
53
|
+
use_json_output: bool = False # Refurb doesn't support JSON output
|
|
54
|
+
enable_all: bool = False # Enable all checks
|
|
55
|
+
disable_checks: list[str] = Field(default_factory=list)
|
|
56
|
+
enable_checks: list[str] = Field(default_factory=list)
|
|
57
|
+
python_version: str | None = None # e.g., "3.13"
|
|
58
|
+
explain: bool = False # Show detailed explanations
|
|
59
|
+
timeout_seconds: int = (
|
|
60
|
+
660 # 11 minutes to allow for comprehensive refactoring analysis
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class RefurbAdapter(BaseToolAdapter):
|
|
65
|
+
"""Adapter for Refurb - Python refactoring suggestions.
|
|
66
|
+
|
|
67
|
+
Suggests modern Python idioms and refactoring opportunities:
|
|
68
|
+
- Replace outdated constructs with modern equivalents
|
|
69
|
+
- Simplify complex expressions
|
|
70
|
+
- Use built-in functions more effectively
|
|
71
|
+
- Apply Python best practices
|
|
72
|
+
|
|
73
|
+
Features:
|
|
74
|
+
- Configurable check selection
|
|
75
|
+
- Python version-specific suggestions
|
|
76
|
+
- Detailed explanations for suggestions
|
|
77
|
+
- Non-destructive analysis only
|
|
78
|
+
|
|
79
|
+
Example:
|
|
80
|
+
```python
|
|
81
|
+
settings = RefurbSettings(
|
|
82
|
+
enable_all=False,
|
|
83
|
+
enable_checks=["FURB101", "FURB109"],
|
|
84
|
+
python_version="3.13",
|
|
85
|
+
)
|
|
86
|
+
adapter = RefurbAdapter(settings=settings)
|
|
87
|
+
await adapter.init()
|
|
88
|
+
result = await adapter.check(files=[Path("src/")])
|
|
89
|
+
```
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
settings: RefurbSettings | None = None
|
|
93
|
+
|
|
94
|
+
def __init__(self, settings: RefurbSettings | None = None) -> None:
|
|
95
|
+
"""Initialize Refurb adapter.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
settings: Optional settings override
|
|
99
|
+
"""
|
|
100
|
+
super().__init__(settings=settings)
|
|
101
|
+
logger.debug(
|
|
102
|
+
"RefurbAdapter initialized", extra={"has_settings": settings is not None}
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
async def init(self) -> None:
|
|
106
|
+
"""Initialize adapter with default settings."""
|
|
107
|
+
if not self.settings:
|
|
108
|
+
self.settings = RefurbSettings()
|
|
109
|
+
logger.info("Using default RefurbSettings")
|
|
110
|
+
await super().init()
|
|
111
|
+
logger.debug(
|
|
112
|
+
"RefurbAdapter initialization complete",
|
|
113
|
+
extra={
|
|
114
|
+
"enable_all": self.settings.enable_all,
|
|
115
|
+
"enable_checks_count": len(self.settings.enable_checks),
|
|
116
|
+
"disable_checks_count": len(self.settings.disable_checks),
|
|
117
|
+
"has_python_version": self.settings.python_version is not None,
|
|
118
|
+
},
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def adapter_name(self) -> str:
|
|
123
|
+
"""Human-readable adapter name."""
|
|
124
|
+
return "Refurb (Refactoring)"
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def module_id(self) -> UUID:
|
|
128
|
+
"""Reference to module-level MODULE_ID."""
|
|
129
|
+
return MODULE_ID
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def tool_name(self) -> str:
|
|
133
|
+
"""CLI tool name."""
|
|
134
|
+
return "refurb"
|
|
135
|
+
|
|
136
|
+
def build_command(
|
|
137
|
+
self,
|
|
138
|
+
files: list[Path],
|
|
139
|
+
config: QACheckConfig | None = None,
|
|
140
|
+
) -> list[str]:
|
|
141
|
+
"""Build Refurb command.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
files: Files/directories to analyze
|
|
145
|
+
config: Optional configuration override
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
Command as list of strings
|
|
149
|
+
"""
|
|
150
|
+
if not self.settings:
|
|
151
|
+
raise RuntimeError("Settings not initialized")
|
|
152
|
+
|
|
153
|
+
cmd = [self.tool_name]
|
|
154
|
+
|
|
155
|
+
# Enable all checks
|
|
156
|
+
if self.settings.enable_all:
|
|
157
|
+
cmd.append("--enable-all")
|
|
158
|
+
|
|
159
|
+
# Disable specific checks
|
|
160
|
+
if self.settings.disable_checks:
|
|
161
|
+
for check in self.settings.disable_checks:
|
|
162
|
+
cmd.extend(["--ignore", check])
|
|
163
|
+
|
|
164
|
+
# Enable specific checks
|
|
165
|
+
if self.settings.enable_checks:
|
|
166
|
+
for check in self.settings.enable_checks:
|
|
167
|
+
cmd.extend(["--enable", check])
|
|
168
|
+
|
|
169
|
+
# Python version
|
|
170
|
+
if self.settings.python_version:
|
|
171
|
+
cmd.extend(["--python-version", self.settings.python_version])
|
|
172
|
+
|
|
173
|
+
# Show explanations
|
|
174
|
+
if self.settings.explain:
|
|
175
|
+
cmd.append("--explain")
|
|
176
|
+
|
|
177
|
+
# Add targets
|
|
178
|
+
cmd.extend([str(f) for f in files])
|
|
179
|
+
|
|
180
|
+
logger.info(
|
|
181
|
+
"Built Refurb command",
|
|
182
|
+
extra={
|
|
183
|
+
"file_count": len(files),
|
|
184
|
+
"enable_all": self.settings.enable_all,
|
|
185
|
+
"enable_checks_count": len(self.settings.enable_checks),
|
|
186
|
+
"disable_checks_count": len(self.settings.disable_checks),
|
|
187
|
+
"explain": self.settings.explain,
|
|
188
|
+
},
|
|
189
|
+
)
|
|
190
|
+
return cmd
|
|
191
|
+
|
|
192
|
+
async def parse_output(
|
|
193
|
+
self,
|
|
194
|
+
result: ToolExecutionResult,
|
|
195
|
+
) -> list[ToolIssue]:
|
|
196
|
+
"""Parse Refurb text output into standardized issues.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
result: Raw execution result from Refurb
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
List of parsed issues
|
|
203
|
+
"""
|
|
204
|
+
if not result.raw_output:
|
|
205
|
+
logger.debug("No output to parse")
|
|
206
|
+
return []
|
|
207
|
+
|
|
208
|
+
issues = []
|
|
209
|
+
lines = result.raw_output.strip().split("\n")
|
|
210
|
+
logger.debug("Parsing Refurb text output", extra={"line_count": len(lines)})
|
|
211
|
+
|
|
212
|
+
for line in lines:
|
|
213
|
+
# Refurb format: "file.py:10:5 [FURB101]: Use dict comprehension..."
|
|
214
|
+
if "[FURB" not in line:
|
|
215
|
+
continue
|
|
216
|
+
|
|
217
|
+
issue = self._parse_refurb_line(line)
|
|
218
|
+
if issue:
|
|
219
|
+
issues.append(issue)
|
|
220
|
+
|
|
221
|
+
logger.info(
|
|
222
|
+
"Parsed Refurb output",
|
|
223
|
+
extra={
|
|
224
|
+
"total_issues": len(issues),
|
|
225
|
+
"files_affected": len({str(i.file_path) for i in issues}),
|
|
226
|
+
"unique_codes": len({i.code for i in issues if i.code}),
|
|
227
|
+
},
|
|
228
|
+
)
|
|
229
|
+
return issues
|
|
230
|
+
|
|
231
|
+
def _parse_refurb_line(self, line: str) -> ToolIssue | None:
|
|
232
|
+
"""Parse a single Refurb output line.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
line: Line of Refurb output
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
ToolIssue if parsing successful, None otherwise
|
|
239
|
+
"""
|
|
240
|
+
try:
|
|
241
|
+
if ":" not in line:
|
|
242
|
+
return None
|
|
243
|
+
|
|
244
|
+
parts = line.split(":", maxsplit=3)
|
|
245
|
+
if len(parts) < 3:
|
|
246
|
+
return None
|
|
247
|
+
|
|
248
|
+
file_path = Path(parts[0].strip())
|
|
249
|
+
line_number = int(parts[1].strip())
|
|
250
|
+
|
|
251
|
+
# Parse column and message
|
|
252
|
+
remaining = parts[2].strip()
|
|
253
|
+
column_number = self._extract_column_number(remaining)
|
|
254
|
+
message_part = self._extract_message_part(remaining, column_number)
|
|
255
|
+
|
|
256
|
+
# Extract code and message
|
|
257
|
+
code, message = self._extract_code_and_message(message_part)
|
|
258
|
+
|
|
259
|
+
return ToolIssue(
|
|
260
|
+
file_path=file_path,
|
|
261
|
+
line_number=line_number,
|
|
262
|
+
column_number=column_number,
|
|
263
|
+
message=message,
|
|
264
|
+
code=code,
|
|
265
|
+
severity="warning", # Refurb suggestions are warnings
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
except (ValueError, IndexError):
|
|
269
|
+
return None
|
|
270
|
+
|
|
271
|
+
def _extract_column_number(self, remaining: str) -> int | None:
|
|
272
|
+
"""Extract column number from remaining string.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
remaining: Remaining part after file and line
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
Column number if found, None otherwise
|
|
279
|
+
"""
|
|
280
|
+
if " " in remaining:
|
|
281
|
+
first_part = remaining.split()[0]
|
|
282
|
+
if first_part.isdigit():
|
|
283
|
+
return int(first_part)
|
|
284
|
+
return None
|
|
285
|
+
|
|
286
|
+
def _extract_message_part(self, remaining: str, column_number: int | None) -> str:
|
|
287
|
+
"""Extract message part from remaining string.
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
remaining: Remaining part after file and line
|
|
291
|
+
column_number: Extracted column number if any
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
Message part of the line
|
|
295
|
+
"""
|
|
296
|
+
if column_number is not None and " " in remaining:
|
|
297
|
+
first_part = remaining.split()[0]
|
|
298
|
+
return remaining[len(first_part) :].strip()
|
|
299
|
+
return remaining
|
|
300
|
+
|
|
301
|
+
def _extract_code_and_message(self, message_part: str) -> tuple[str | None, str]:
|
|
302
|
+
"""Extract code and message from message part.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
message_part: Part containing code and message
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
Tuple of (code, message)
|
|
309
|
+
"""
|
|
310
|
+
if "[" in message_part and "]" in message_part:
|
|
311
|
+
code_start = message_part.index("[")
|
|
312
|
+
code_end = message_part.index("]")
|
|
313
|
+
code = message_part[code_start + 1 : code_end]
|
|
314
|
+
message = message_part[code_end + 1 :].strip()
|
|
315
|
+
if message.startswith(":"):
|
|
316
|
+
message = message[1:].strip()
|
|
317
|
+
return code, message
|
|
318
|
+
return None, message_part
|
|
319
|
+
|
|
320
|
+
def _get_check_type(self) -> QACheckType:
|
|
321
|
+
"""Return refactor check type."""
|
|
322
|
+
return QACheckType.REFACTOR
|
|
323
|
+
|
|
324
|
+
def _detect_package_directory(self) -> str:
|
|
325
|
+
"""Detect the package directory name from pyproject.toml.
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
Package directory name (e.g., 'crackerjack', 'session_mgmt_mcp')
|
|
329
|
+
"""
|
|
330
|
+
from contextlib import suppress
|
|
331
|
+
|
|
332
|
+
current_dir = Path.cwd()
|
|
333
|
+
|
|
334
|
+
# Try to read package name from pyproject.toml
|
|
335
|
+
pyproject_path = current_dir / "pyproject.toml"
|
|
336
|
+
if pyproject_path.exists():
|
|
337
|
+
with suppress(Exception):
|
|
338
|
+
import tomllib
|
|
339
|
+
|
|
340
|
+
with pyproject_path.open("rb") as f:
|
|
341
|
+
data = tomllib.load(f)
|
|
342
|
+
|
|
343
|
+
if "project" in data and "name" in data["project"]:
|
|
344
|
+
# Convert package name to directory name (replace - with _)
|
|
345
|
+
package_name = str(data["project"]["name"]).replace("-", "_")
|
|
346
|
+
|
|
347
|
+
# Verify directory exists
|
|
348
|
+
if (current_dir / package_name).exists():
|
|
349
|
+
return package_name
|
|
350
|
+
|
|
351
|
+
# Fallback to directory name if package dir exists
|
|
352
|
+
if (current_dir / current_dir.name).exists():
|
|
353
|
+
return current_dir.name
|
|
354
|
+
|
|
355
|
+
# Default fallback
|
|
356
|
+
return "src"
|
|
357
|
+
|
|
358
|
+
def get_default_config(self) -> QACheckConfig:
|
|
359
|
+
"""Get default configuration for Refurb adapter.
|
|
360
|
+
|
|
361
|
+
Returns:
|
|
362
|
+
QACheckConfig with sensible defaults
|
|
363
|
+
"""
|
|
364
|
+
from crackerjack.models.qa_config import QACheckConfig
|
|
365
|
+
|
|
366
|
+
# Dynamically detect package directory
|
|
367
|
+
package_dir = self._detect_package_directory()
|
|
368
|
+
|
|
369
|
+
return QACheckConfig(
|
|
370
|
+
check_id=MODULE_ID,
|
|
371
|
+
check_name=self.adapter_name,
|
|
372
|
+
check_type=QACheckType.REFACTOR,
|
|
373
|
+
enabled=True,
|
|
374
|
+
file_patterns=[
|
|
375
|
+
f"{package_dir}/**/*.py"
|
|
376
|
+
], # Dynamically detected package directory
|
|
377
|
+
exclude_patterns=[
|
|
378
|
+
"**/test_*.py",
|
|
379
|
+
"**/tests/**",
|
|
380
|
+
"**/.venv/**",
|
|
381
|
+
"**/venv/**",
|
|
382
|
+
"**/build/**",
|
|
383
|
+
"**/dist/**",
|
|
384
|
+
"**/__pycache__/**",
|
|
385
|
+
"**/.git/**",
|
|
386
|
+
"**/node_modules/**",
|
|
387
|
+
"**/.tox/**",
|
|
388
|
+
"**/.pytest_cache/**",
|
|
389
|
+
"**/htmlcov/**",
|
|
390
|
+
"**/.coverage*",
|
|
391
|
+
],
|
|
392
|
+
timeout_seconds=240,
|
|
393
|
+
parallel_safe=True,
|
|
394
|
+
stage="comprehensive", # Refactoring suggestions in comprehensive stage
|
|
395
|
+
settings={
|
|
396
|
+
"enable_all": False,
|
|
397
|
+
"disable_checks": [],
|
|
398
|
+
"enable_checks": [],
|
|
399
|
+
"explain": False,
|
|
400
|
+
},
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
# ACB Registration (REQUIRED at module level)
|
|
405
|
+
with suppress(Exception):
|
|
406
|
+
depends.set(RefurbAdapter)
|