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,275 @@
|
|
|
1
|
+
"""Retry utilities for handling API connection errors and other transient failures.
|
|
2
|
+
|
|
3
|
+
This module provides a general-purpose retry decorator that can be used across
|
|
4
|
+
the Crackerjack codebase to handle API connection errors and other transient failures.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import functools
|
|
9
|
+
import random
|
|
10
|
+
import time
|
|
11
|
+
from collections.abc import Callable
|
|
12
|
+
from typing import Any, TypeVar, cast
|
|
13
|
+
|
|
14
|
+
from loguru import logger
|
|
15
|
+
|
|
16
|
+
T = TypeVar("T")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _calculate_delay(current_delay: float, jitter: bool, backoff: float) -> float:
|
|
20
|
+
"""Calculate the delay for the next retry attempt."""
|
|
21
|
+
if jitter:
|
|
22
|
+
return current_delay * (0.5 + random.random() * 0.5) # nosec B311 # Not used for cryptographic purposes
|
|
23
|
+
return current_delay * backoff
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _prepare_next_attempt(
|
|
27
|
+
current_delay: float,
|
|
28
|
+
max_delay: float | None,
|
|
29
|
+
backoff: float,
|
|
30
|
+
jitter: bool,
|
|
31
|
+
attempt: int,
|
|
32
|
+
max_attempts: int,
|
|
33
|
+
e: BaseException,
|
|
34
|
+
logger_func: Callable[[str], None] | None,
|
|
35
|
+
) -> float:
|
|
36
|
+
"""Prepare for the next retry attempt by calculating delay and logging."""
|
|
37
|
+
current_delay = _calculate_delay(current_delay, jitter, backoff)
|
|
38
|
+
|
|
39
|
+
if max_delay:
|
|
40
|
+
current_delay = min(current_delay, max_delay)
|
|
41
|
+
|
|
42
|
+
log_msg = (
|
|
43
|
+
f"Attempt {attempt + 1}/{max_attempts} failed: {type(e).__name__}: {e}. "
|
|
44
|
+
f"Retrying in {current_delay:.2f}s..."
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if logger_func:
|
|
48
|
+
logger_func(log_msg)
|
|
49
|
+
else:
|
|
50
|
+
logger.warning(log_msg)
|
|
51
|
+
|
|
52
|
+
return current_delay
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _should_retry(attempt: int, max_attempts: int) -> bool:
|
|
56
|
+
"""Determine if we should make another retry attempt."""
|
|
57
|
+
return attempt != max_attempts - 1 # Continue unless it's the last attempt
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def retry(
|
|
61
|
+
max_attempts: int = 3,
|
|
62
|
+
delay: float = 1.0,
|
|
63
|
+
backoff: float = 2.0,
|
|
64
|
+
max_delay: float | None = None,
|
|
65
|
+
jitter: bool = True,
|
|
66
|
+
exceptions: tuple[type[BaseException], ...] = (Exception,),
|
|
67
|
+
logger_func: Callable[[str], None] | None = None,
|
|
68
|
+
) -> Callable[[Callable[..., T]], Callable[..., T]]:
|
|
69
|
+
"""Decorator to retry a function when specific exceptions are raised.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
max_attempts: Maximum number of attempts (including initial call)
|
|
73
|
+
delay: Initial delay between retries in seconds
|
|
74
|
+
backoff: Multiplier for delay between attempts (exponential backoff)
|
|
75
|
+
max_delay: Maximum delay between retries (caps exponential growth)
|
|
76
|
+
jitter: Add random jitter to delay to prevent thundering herd
|
|
77
|
+
exceptions: Tuple of exception types to catch and retry on
|
|
78
|
+
logger_func: Optional logger function to use for retry messages
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
Decorator function
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def decorator(func: Callable[..., T]) -> Callable[..., T]:
|
|
85
|
+
@functools.wraps(func)
|
|
86
|
+
async def async_wrapper(*args: Any, **kwargs: Any) -> T:
|
|
87
|
+
return await _retry_async(
|
|
88
|
+
func,
|
|
89
|
+
args,
|
|
90
|
+
kwargs,
|
|
91
|
+
max_attempts,
|
|
92
|
+
delay,
|
|
93
|
+
backoff,
|
|
94
|
+
max_delay,
|
|
95
|
+
jitter,
|
|
96
|
+
exceptions,
|
|
97
|
+
logger_func,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
@functools.wraps(func)
|
|
101
|
+
def sync_wrapper(*args: Any, **kwargs: Any) -> T:
|
|
102
|
+
return _retry_sync(
|
|
103
|
+
func,
|
|
104
|
+
args,
|
|
105
|
+
kwargs,
|
|
106
|
+
max_attempts,
|
|
107
|
+
delay,
|
|
108
|
+
backoff,
|
|
109
|
+
max_delay,
|
|
110
|
+
jitter,
|
|
111
|
+
exceptions,
|
|
112
|
+
logger_func,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
if asyncio.iscoroutinefunction(func):
|
|
116
|
+
return cast(Callable[..., T], async_wrapper)
|
|
117
|
+
return cast(Callable[..., T], sync_wrapper)
|
|
118
|
+
|
|
119
|
+
return decorator
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
async def _retry_async[T](
|
|
123
|
+
func: Callable[..., T],
|
|
124
|
+
args: tuple[Any, ...],
|
|
125
|
+
kwargs: dict[str, Any],
|
|
126
|
+
max_attempts: int,
|
|
127
|
+
delay: float,
|
|
128
|
+
backoff: float,
|
|
129
|
+
max_delay: float | None,
|
|
130
|
+
jitter: bool,
|
|
131
|
+
exceptions: tuple[type[BaseException], ...],
|
|
132
|
+
logger_func: Callable[[str], None] | None,
|
|
133
|
+
) -> T:
|
|
134
|
+
"""Execute async function with retry logic."""
|
|
135
|
+
last_exception: BaseException | None = None
|
|
136
|
+
current_delay = delay
|
|
137
|
+
|
|
138
|
+
for attempt in range(max_attempts):
|
|
139
|
+
try:
|
|
140
|
+
result = await func(*args, **kwargs) # type: ignore[misc]
|
|
141
|
+
return result # type: ignore[no-any-return]
|
|
142
|
+
|
|
143
|
+
except exceptions as e:
|
|
144
|
+
last_exception = e
|
|
145
|
+
|
|
146
|
+
if not _should_retry(attempt, max_attempts):
|
|
147
|
+
break
|
|
148
|
+
|
|
149
|
+
current_delay = _prepare_next_attempt(
|
|
150
|
+
current_delay,
|
|
151
|
+
max_delay,
|
|
152
|
+
backoff,
|
|
153
|
+
jitter,
|
|
154
|
+
attempt,
|
|
155
|
+
max_attempts,
|
|
156
|
+
e,
|
|
157
|
+
logger_func,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
await asyncio.sleep(current_delay)
|
|
161
|
+
|
|
162
|
+
if last_exception is not None:
|
|
163
|
+
raise last_exception
|
|
164
|
+
raise RuntimeError("Retry failed but no exception was captured")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _retry_sync[T](
|
|
168
|
+
func: Callable[..., T],
|
|
169
|
+
args: tuple[Any, ...],
|
|
170
|
+
kwargs: dict[str, Any],
|
|
171
|
+
max_attempts: int,
|
|
172
|
+
delay: float,
|
|
173
|
+
backoff: float,
|
|
174
|
+
max_delay: float | None,
|
|
175
|
+
jitter: bool,
|
|
176
|
+
exceptions: tuple[type[BaseException], ...],
|
|
177
|
+
logger_func: Callable[[str], None] | None,
|
|
178
|
+
) -> T:
|
|
179
|
+
"""Execute sync function with retry logic."""
|
|
180
|
+
last_exception: BaseException | None = None
|
|
181
|
+
current_delay = delay
|
|
182
|
+
|
|
183
|
+
for attempt in range(max_attempts):
|
|
184
|
+
try:
|
|
185
|
+
result = func(*args, **kwargs)
|
|
186
|
+
return result # type: ignore[no-any-return]
|
|
187
|
+
|
|
188
|
+
except exceptions as e:
|
|
189
|
+
last_exception = e
|
|
190
|
+
|
|
191
|
+
if not _should_retry(attempt, max_attempts):
|
|
192
|
+
break
|
|
193
|
+
|
|
194
|
+
current_delay = _prepare_next_attempt(
|
|
195
|
+
current_delay,
|
|
196
|
+
max_delay,
|
|
197
|
+
backoff,
|
|
198
|
+
jitter,
|
|
199
|
+
attempt,
|
|
200
|
+
max_attempts,
|
|
201
|
+
e,
|
|
202
|
+
logger_func,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
time.sleep(current_delay)
|
|
206
|
+
|
|
207
|
+
if last_exception is not None:
|
|
208
|
+
raise last_exception
|
|
209
|
+
raise RuntimeError("Retry failed but no exception was captured")
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# Common exception types for API connection retries
|
|
213
|
+
API_CONNECTION_EXCEPTIONS = (
|
|
214
|
+
ConnectionError,
|
|
215
|
+
TimeoutError,
|
|
216
|
+
ConnectionResetError,
|
|
217
|
+
ConnectionAbortedError,
|
|
218
|
+
BrokenPipeError,
|
|
219
|
+
OSError, # Network-related OS errors
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# Convenience decorator for API calls with common settings
|
|
224
|
+
def retry_api_call(
|
|
225
|
+
max_attempts: int = 3,
|
|
226
|
+
delay: float = 1.0,
|
|
227
|
+
backoff: float = 2.0,
|
|
228
|
+
max_delay: float | None = 30.0, # Cap at 30 seconds
|
|
229
|
+
jitter: bool = True,
|
|
230
|
+
) -> Callable[[Callable[..., T]], Callable[..., T]]:
|
|
231
|
+
"""Convenience decorator for API calls with sensible defaults.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
max_attempts: Maximum number of attempts (default: 3)
|
|
235
|
+
delay: Initial delay in seconds (default: 1.0)
|
|
236
|
+
backoff: Exponential backoff multiplier (default: 2.0)
|
|
237
|
+
max_delay: Maximum delay between retries (default: 30.0)
|
|
238
|
+
jitter: Add jitter to prevent thundering herd (default: True)
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
Decorator function configured for API calls
|
|
242
|
+
"""
|
|
243
|
+
return retry(
|
|
244
|
+
max_attempts=max_attempts,
|
|
245
|
+
delay=delay,
|
|
246
|
+
backoff=backoff,
|
|
247
|
+
max_delay=max_delay,
|
|
248
|
+
jitter=jitter,
|
|
249
|
+
exceptions=API_CONNECTION_EXCEPTIONS,
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
# Example usage functions for testing purposes
|
|
254
|
+
@retry_api_call(max_attempts=3, delay=0.5)
|
|
255
|
+
async def example_api_call_async(url: str) -> str:
|
|
256
|
+
"""Example async API call that might fail with network issues."""
|
|
257
|
+
# Simulate an API call that might fail
|
|
258
|
+
# import random # Already imported at the top of the file
|
|
259
|
+
|
|
260
|
+
if random.random() < 0.7: # 70% chance of failure for testing # nosec B311
|
|
261
|
+
raise ConnectionError("Simulated network error")
|
|
262
|
+
|
|
263
|
+
return f"Success: {url}"
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
@retry_api_call(max_attempts=3, delay=0.5)
|
|
267
|
+
def example_api_call_sync(url: str) -> str:
|
|
268
|
+
"""Example sync API call that might fail with network issues."""
|
|
269
|
+
# Simulate an API call that might fail
|
|
270
|
+
# import random # Already imported at the top of file
|
|
271
|
+
|
|
272
|
+
if random.random() < 0.7: # 70% chance of failure for testing # nosec B311
|
|
273
|
+
raise ConnectionError("Simulated network error")
|
|
274
|
+
|
|
275
|
+
return f"Success: {url}"
|