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,258 @@
|
|
|
1
|
+
"""Semantic search data models for crackerjack vector store functionality."""
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field, field_serializer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class EmbeddingVector(BaseModel):
|
|
11
|
+
"""Represents a single embedding vector with metadata."""
|
|
12
|
+
|
|
13
|
+
file_path: Path = Field(..., description="Path to the source file")
|
|
14
|
+
chunk_id: str = Field(..., description="Unique identifier for this chunk")
|
|
15
|
+
content: str = Field(..., description="The text content that was embedded")
|
|
16
|
+
embedding: list[float] = Field(
|
|
17
|
+
..., description="The numerical vector representation"
|
|
18
|
+
)
|
|
19
|
+
created_at: datetime = Field(
|
|
20
|
+
default_factory=datetime.now, description="Creation timestamp"
|
|
21
|
+
)
|
|
22
|
+
file_hash: str = Field(
|
|
23
|
+
..., description="Hash of the source file for change detection"
|
|
24
|
+
)
|
|
25
|
+
start_line: int = Field(..., description="Starting line number in the source file")
|
|
26
|
+
end_line: int = Field(..., description="Ending line number in the source file")
|
|
27
|
+
file_type: str = Field(..., description="File extension or type identifier")
|
|
28
|
+
|
|
29
|
+
model_config = ConfigDict(ser_json_timedelta="iso8601")
|
|
30
|
+
|
|
31
|
+
@field_serializer("file_path")
|
|
32
|
+
def serialize_path(self, value: Path) -> str:
|
|
33
|
+
"""Serialize Path to string."""
|
|
34
|
+
return str(value)
|
|
35
|
+
|
|
36
|
+
@field_serializer("created_at")
|
|
37
|
+
def serialize_datetime(self, value: datetime) -> str:
|
|
38
|
+
"""Serialize datetime to ISO format."""
|
|
39
|
+
return value.isoformat()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class SearchResult(BaseModel):
|
|
43
|
+
"""Represents a semantic search result with similarity score."""
|
|
44
|
+
|
|
45
|
+
file_path: Path = Field(..., description="Path to the matching file")
|
|
46
|
+
chunk_id: str = Field(..., description="Identifier of the matching chunk")
|
|
47
|
+
content: str = Field(..., description="The matching text content")
|
|
48
|
+
similarity_score: float = Field(
|
|
49
|
+
..., ge=0.0, le=1.0, description="Similarity score (0-1)"
|
|
50
|
+
)
|
|
51
|
+
start_line: int = Field(..., description="Starting line number")
|
|
52
|
+
end_line: int = Field(..., description="Ending line number")
|
|
53
|
+
file_type: str = Field(..., description="File type identifier")
|
|
54
|
+
context_lines: list[str] = Field(
|
|
55
|
+
default_factory=list, description="Surrounding context lines"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
@field_serializer("file_path")
|
|
59
|
+
def serialize_path(self, value: Path) -> str:
|
|
60
|
+
"""Serialize Path to string."""
|
|
61
|
+
return str(value)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class IndexStats(BaseModel):
|
|
65
|
+
"""Statistics about the semantic index."""
|
|
66
|
+
|
|
67
|
+
total_files: int = Field(..., description="Total number of indexed files")
|
|
68
|
+
total_chunks: int = Field(..., description="Total number of text chunks")
|
|
69
|
+
index_size_mb: float = Field(..., description="Index size in megabytes")
|
|
70
|
+
last_updated: datetime = Field(..., description="Last index update timestamp")
|
|
71
|
+
file_types: dict[str, int] = Field(
|
|
72
|
+
default_factory=dict, description="Count by file type"
|
|
73
|
+
)
|
|
74
|
+
embedding_model: str = Field(..., description="Name of the embedding model used")
|
|
75
|
+
avg_chunk_size: float = Field(..., description="Average chunk size in characters")
|
|
76
|
+
|
|
77
|
+
@field_serializer("last_updated")
|
|
78
|
+
def serialize_datetime(self, value: datetime) -> str:
|
|
79
|
+
"""Serialize datetime to ISO format."""
|
|
80
|
+
return value.isoformat()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class SearchQuery(BaseModel):
|
|
84
|
+
"""Represents a semantic search query with parameters."""
|
|
85
|
+
|
|
86
|
+
query: str = Field(..., min_length=1, description="The search query text")
|
|
87
|
+
max_results: int = Field(
|
|
88
|
+
default=10, ge=1, le=100, description="Maximum number of results"
|
|
89
|
+
)
|
|
90
|
+
min_similarity: float = Field(
|
|
91
|
+
default=0.3, ge=0.0, le=1.0, description="Minimum similarity threshold"
|
|
92
|
+
)
|
|
93
|
+
file_types: list[str] = Field(
|
|
94
|
+
default_factory=list, description="Filter by file types"
|
|
95
|
+
)
|
|
96
|
+
include_context: bool = Field(
|
|
97
|
+
default=True, description="Include surrounding context lines"
|
|
98
|
+
)
|
|
99
|
+
context_lines: int = Field(
|
|
100
|
+
default=3, ge=0, le=10, description="Number of context lines"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
model_config = ConfigDict(validate_assignment=True)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class IndexingProgress(BaseModel):
|
|
107
|
+
"""Progress information for indexing operations."""
|
|
108
|
+
|
|
109
|
+
current_file: Path = Field(..., description="Currently processing file")
|
|
110
|
+
files_processed: int = Field(..., ge=0, description="Number of files processed")
|
|
111
|
+
total_files: int = Field(..., ge=0, description="Total files to process")
|
|
112
|
+
chunks_created: int = Field(..., ge=0, description="Number of chunks created")
|
|
113
|
+
elapsed_time: float = Field(..., ge=0.0, description="Elapsed time in seconds")
|
|
114
|
+
estimated_remaining: float | None = Field(
|
|
115
|
+
default=None, description="Estimated remaining time in seconds"
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def progress_percentage(self) -> float:
|
|
120
|
+
"""Calculate progress as a percentage."""
|
|
121
|
+
if self.total_files == 0:
|
|
122
|
+
return 0.0
|
|
123
|
+
return min(100.0, (self.files_processed / self.total_files) * 100.0)
|
|
124
|
+
|
|
125
|
+
@field_serializer("current_file")
|
|
126
|
+
def serialize_path(self, value: Path) -> str:
|
|
127
|
+
"""Serialize Path to string."""
|
|
128
|
+
return str(value)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class SemanticConfig(BaseModel):
|
|
132
|
+
"""Configuration for semantic search functionality."""
|
|
133
|
+
|
|
134
|
+
embedding_model: str = Field(
|
|
135
|
+
default="all-MiniLM-L6-v2", description="Sentence transformer model name"
|
|
136
|
+
)
|
|
137
|
+
chunk_size: int = Field(
|
|
138
|
+
default=500, ge=100, le=2000, description="Maximum characters per chunk"
|
|
139
|
+
)
|
|
140
|
+
chunk_overlap: int = Field(
|
|
141
|
+
default=50, ge=0, le=500, description="Overlap between chunks"
|
|
142
|
+
)
|
|
143
|
+
max_search_results: int = Field(
|
|
144
|
+
default=10, ge=1, le=100, description="Maximum number of search results"
|
|
145
|
+
)
|
|
146
|
+
similarity_threshold: float = Field(
|
|
147
|
+
default=0.7, ge=0.0, le=1.0, description="Minimum similarity threshold"
|
|
148
|
+
)
|
|
149
|
+
embedding_dimension: int = Field(
|
|
150
|
+
default=384, ge=128, le=1024, description="Embedding vector dimension"
|
|
151
|
+
)
|
|
152
|
+
max_file_size_mb: int = Field(
|
|
153
|
+
default=10, ge=1, le=100, description="Maximum file size to process"
|
|
154
|
+
)
|
|
155
|
+
excluded_patterns: list[str] = Field(
|
|
156
|
+
default_factory=lambda: [
|
|
157
|
+
"*.pyc",
|
|
158
|
+
"*.pyo",
|
|
159
|
+
"*.pyd",
|
|
160
|
+
"__pycache__/*",
|
|
161
|
+
".git/*",
|
|
162
|
+
".venv/*",
|
|
163
|
+
"*.log",
|
|
164
|
+
"*.tmp",
|
|
165
|
+
],
|
|
166
|
+
description="File patterns to exclude from indexing",
|
|
167
|
+
)
|
|
168
|
+
included_extensions: list[str] = Field(
|
|
169
|
+
default_factory=lambda: [
|
|
170
|
+
".py",
|
|
171
|
+
".md",
|
|
172
|
+
".txt",
|
|
173
|
+
".yml",
|
|
174
|
+
".yaml",
|
|
175
|
+
".json",
|
|
176
|
+
".toml",
|
|
177
|
+
".ini",
|
|
178
|
+
".cfg",
|
|
179
|
+
".sh",
|
|
180
|
+
".js",
|
|
181
|
+
".ts",
|
|
182
|
+
".html",
|
|
183
|
+
".css",
|
|
184
|
+
".sql",
|
|
185
|
+
],
|
|
186
|
+
description="File extensions to include in indexing",
|
|
187
|
+
)
|
|
188
|
+
cache_embeddings: bool = Field(default=True, description="Cache embeddings to disk")
|
|
189
|
+
cache_ttl_hours: int = Field(
|
|
190
|
+
default=24, ge=1, le=168, description="Cache time-to-live in hours"
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
model_config = ConfigDict(validate_assignment=True)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
class FileChangeEvent(BaseModel):
|
|
197
|
+
"""Represents a file system change event for incremental indexing."""
|
|
198
|
+
|
|
199
|
+
file_path: Path = Field(..., description="Path to the changed file")
|
|
200
|
+
event_type: t.Literal["created", "modified", "deleted"] = Field(
|
|
201
|
+
..., description="Type of change"
|
|
202
|
+
)
|
|
203
|
+
timestamp: datetime = Field(
|
|
204
|
+
default_factory=datetime.now, description="When the change occurred"
|
|
205
|
+
)
|
|
206
|
+
file_hash: str | None = Field(
|
|
207
|
+
default=None, description="New file hash if available"
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
@field_serializer("file_path")
|
|
211
|
+
def serialize_path(self, value: Path) -> str:
|
|
212
|
+
"""Serialize Path to string."""
|
|
213
|
+
return str(value)
|
|
214
|
+
|
|
215
|
+
@field_serializer("timestamp")
|
|
216
|
+
def serialize_datetime(self, value: datetime) -> str:
|
|
217
|
+
"""Serialize datetime to ISO format."""
|
|
218
|
+
return value.isoformat()
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class SemanticContext(BaseModel):
|
|
222
|
+
"""Context information for AI agents using semantic search."""
|
|
223
|
+
|
|
224
|
+
query: str = Field(..., description="The query that generated this context")
|
|
225
|
+
related_files: list[SearchResult] = Field(
|
|
226
|
+
..., description="Semantically related files"
|
|
227
|
+
)
|
|
228
|
+
patterns: list[str] = Field(
|
|
229
|
+
default_factory=list, description="Identified code patterns"
|
|
230
|
+
)
|
|
231
|
+
suggestions: list[str] = Field(
|
|
232
|
+
default_factory=list, description="AI-generated suggestions"
|
|
233
|
+
)
|
|
234
|
+
confidence: float = Field(
|
|
235
|
+
..., ge=0.0, le=1.0, description="Confidence in the context relevance"
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# Type aliases for better code readability
|
|
240
|
+
EmbeddingMatrix = list[list[float]]
|
|
241
|
+
SimilarityMatrix = list[list[float]]
|
|
242
|
+
FilePathSet = set[Path]
|
|
243
|
+
ChunkMapping = dict[str, EmbeddingVector]
|
|
244
|
+
|
|
245
|
+
__all__ = [
|
|
246
|
+
"EmbeddingVector",
|
|
247
|
+
"SearchResult",
|
|
248
|
+
"IndexStats",
|
|
249
|
+
"SearchQuery",
|
|
250
|
+
"IndexingProgress",
|
|
251
|
+
"SemanticConfig",
|
|
252
|
+
"FileChangeEvent",
|
|
253
|
+
"SemanticContext",
|
|
254
|
+
"EmbeddingMatrix",
|
|
255
|
+
"SimilarityMatrix",
|
|
256
|
+
"FilePathSet",
|
|
257
|
+
"ChunkMapping",
|
|
258
|
+
]
|
crackerjack/models/task.py
CHANGED
|
@@ -3,8 +3,9 @@ import typing as t
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from enum import Enum
|
|
5
5
|
|
|
6
|
+
from acb.console import Console
|
|
7
|
+
from acb.depends import Inject, depends
|
|
6
8
|
from pydantic import BaseModel
|
|
7
|
-
from rich.console import Console
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class TaskStatus(Enum):
|
|
@@ -38,11 +39,23 @@ class HookResult:
|
|
|
38
39
|
duration: float
|
|
39
40
|
files_processed: int = 0
|
|
40
41
|
issues_found: list[str] | None = None
|
|
42
|
+
issues_count: int = (
|
|
43
|
+
0 # Total count of issues (may exceed len(issues_found) if truncated)
|
|
44
|
+
)
|
|
41
45
|
stage: str = "pre-commit"
|
|
46
|
+
exit_code: int | None = None # Non-zero exit codes for failed hooks
|
|
47
|
+
error_message: str | None = None # Error details from stderr or exceptions
|
|
48
|
+
is_timeout: bool = False # Whether hook failed due to timeout
|
|
49
|
+
is_config_error: bool = (
|
|
50
|
+
False # Whether failure is due to config/tool error (not code issues)
|
|
51
|
+
)
|
|
42
52
|
|
|
43
53
|
def __post_init__(self) -> None:
|
|
44
54
|
if self.issues_found is None:
|
|
45
55
|
self.issues_found = []
|
|
56
|
+
# If issues_count not explicitly set, default to length of issues_found list
|
|
57
|
+
if self.issues_count == 0 and self.issues_found:
|
|
58
|
+
self.issues_count = len(self.issues_found)
|
|
46
59
|
|
|
47
60
|
|
|
48
61
|
@dataclass
|
|
@@ -68,16 +81,18 @@ class TaskStatusData:
|
|
|
68
81
|
|
|
69
82
|
|
|
70
83
|
class SessionTracker(BaseModel, arbitrary_types_allowed=True):
|
|
71
|
-
console: Console
|
|
72
84
|
session_id: str
|
|
73
85
|
start_time: float
|
|
74
86
|
progress_file: t.Any = None
|
|
75
87
|
tasks: dict[str, TaskStatusData] = {}
|
|
76
88
|
current_task: str | None = None
|
|
77
89
|
metadata: dict[str, t.Any] = {}
|
|
90
|
+
console: t.Any = None # Console instance from DI
|
|
78
91
|
|
|
79
|
-
|
|
92
|
+
@depends.inject # type: ignore[misc]
|
|
93
|
+
def __init__(self, console: Inject[Console], **data: t.Any) -> None:
|
|
80
94
|
super().__init__(**data)
|
|
95
|
+
self.console = console
|
|
81
96
|
if not self.tasks:
|
|
82
97
|
self.tasks = {}
|
|
83
98
|
if not self.metadata:
|
|
@@ -150,6 +165,7 @@ class SessionTracker(BaseModel, arbitrary_types_allowed=True):
|
|
|
150
165
|
"session_id": self.session_id,
|
|
151
166
|
"duration": time.time() - self.start_time,
|
|
152
167
|
"total_tasks": len(self.tasks),
|
|
168
|
+
"tasks_count": len(self.tasks),
|
|
153
169
|
"completed": completed,
|
|
154
170
|
"failed": failed,
|
|
155
171
|
"in_progress": in_progress,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class TestFailure:
|
|
7
|
+
"""Structured representation of a test failure."""
|
|
8
|
+
|
|
9
|
+
test_name: str
|
|
10
|
+
"""Full test node ID (e.g., tests/test_foo.py::TestClass::test_method)"""
|
|
11
|
+
|
|
12
|
+
status: str
|
|
13
|
+
"""Test status: FAILED, ERROR, or XFAIL"""
|
|
14
|
+
|
|
15
|
+
location: str
|
|
16
|
+
"""File path and line number (e.g., tests/test_foo.py:42)"""
|
|
17
|
+
|
|
18
|
+
traceback: list[str] = field(default_factory=list)
|
|
19
|
+
"""Full traceback lines"""
|
|
20
|
+
|
|
21
|
+
assertion: str | None = None
|
|
22
|
+
"""Assertion error message if present"""
|
|
23
|
+
|
|
24
|
+
captured_stdout: str | None = None
|
|
25
|
+
"""Captured stdout during test execution"""
|
|
26
|
+
|
|
27
|
+
captured_stderr: str | None = None
|
|
28
|
+
"""Captured stderr during test execution"""
|
|
29
|
+
|
|
30
|
+
duration: float | None = None
|
|
31
|
+
"""Test execution duration in seconds"""
|
|
32
|
+
|
|
33
|
+
short_summary: str | None = None
|
|
34
|
+
"""One-line failure summary"""
|
|
35
|
+
|
|
36
|
+
locals_context: dict[str, Any] = field(default_factory=dict)
|
|
37
|
+
"""Local variables at failure point (in -vvv mode)"""
|
|
38
|
+
|
|
39
|
+
def get_file_path(self) -> str:
|
|
40
|
+
"""Extract file path from location."""
|
|
41
|
+
if ":" in self.location:
|
|
42
|
+
return self.location.split(":")[0]
|
|
43
|
+
return self.location
|
|
44
|
+
|
|
45
|
+
def get_line_number(self) -> int | None:
|
|
46
|
+
"""Extract line number from location."""
|
|
47
|
+
if ":" in self.location:
|
|
48
|
+
try:
|
|
49
|
+
return int(self.location.split(":")[1])
|
|
50
|
+
except (ValueError, IndexError):
|
|
51
|
+
return None
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
def get_relevant_traceback(self, max_lines: int = 15) -> list[str]:
|
|
55
|
+
"""Get most relevant traceback lines (last N lines)."""
|
|
56
|
+
return (
|
|
57
|
+
self.traceback[-max_lines:]
|
|
58
|
+
if len(self.traceback) > max_lines
|
|
59
|
+
else self.traceback
|
|
60
|
+
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
> Crackerjack Docs: [Main](<../../README.md>) | [Crackerjack Package](<../README.md>) | [Monitoring](<./README.md>)
|
|
2
|
+
|
|
3
|
+
# Monitoring
|
|
4
|
+
|
|
5
|
+
Observability, metrics, and health checks.
|
|
6
|
+
|
|
7
|
+
## Related
|
|
8
|
+
|
|
9
|
+
- [Crackerjack Package](<../README.md>) - Parent package
|
|
10
|
+
- [Events](<../events/README.md>) - Event types and signals
|
|
11
|
+
- [MCP](<../mcp/README.md>) - MCP server monitoring and progress tracking
|
|
@@ -5,7 +5,8 @@ from dataclasses import dataclass, field
|
|
|
5
5
|
from datetime import datetime, timedelta
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
|
-
from
|
|
8
|
+
from acb.console import Console
|
|
9
|
+
from acb.depends import depends
|
|
9
10
|
from rich.live import Live
|
|
10
11
|
from rich.table import Table
|
|
11
12
|
|
|
@@ -21,7 +22,7 @@ class AgentPerformanceMetrics:
|
|
|
21
22
|
failed_fixes: int = 0
|
|
22
23
|
average_confidence: float = 0.0
|
|
23
24
|
average_execution_time: float = 0.0
|
|
24
|
-
issue_types_handled: dict[IssueType, int] = field(default_factory=dict
|
|
25
|
+
issue_types_handled: dict[IssueType, int] = field(default_factory=dict)
|
|
25
26
|
recent_failures: list[str] = field(default_factory=list)
|
|
26
27
|
last_successful_fix: datetime | None = None
|
|
27
28
|
regression_patterns: list[str] = field(default_factory=list)
|
|
@@ -39,7 +40,7 @@ class WatchdogAlert:
|
|
|
39
40
|
|
|
40
41
|
class AIAgentWatchdog:
|
|
41
42
|
def __init__(self, console: Console | None = None):
|
|
42
|
-
self.console = console or Console
|
|
43
|
+
self.console = console or depends.get_sync(Console)
|
|
43
44
|
self.performance_metrics: dict[str, AgentPerformanceMetrics] = {}
|
|
44
45
|
self.alerts: list[WatchdogAlert] = []
|
|
45
46
|
self.known_regressions: set[str] = {
|
|
@@ -358,7 +359,7 @@ class AIAgentWatchdog:
|
|
|
358
359
|
|
|
359
360
|
|
|
360
361
|
async def run_agent_monitoring_demo() -> None:
|
|
361
|
-
console = Console
|
|
362
|
+
console = depends.get_sync(Console)
|
|
362
363
|
watchdog = AIAgentWatchdog(console)
|
|
363
364
|
|
|
364
365
|
from crackerjack.agents.base import AgentContext
|
|
@@ -9,10 +9,11 @@ from collections.abc import Callable
|
|
|
9
9
|
from dataclasses import asdict, dataclass, field
|
|
10
10
|
from datetime import datetime, timedelta
|
|
11
11
|
|
|
12
|
-
from
|
|
12
|
+
from acb.console import Console
|
|
13
|
+
from acb.depends import depends
|
|
13
14
|
|
|
14
15
|
from crackerjack.monitoring.ai_agent_watchdog import AgentPerformanceMetrics
|
|
15
|
-
from crackerjack.services.
|
|
16
|
+
from crackerjack.services.acb_cache_adapter import CrackerjackCache
|
|
16
17
|
|
|
17
18
|
logger = logging.getLogger(__name__)
|
|
18
19
|
|
|
@@ -111,7 +112,7 @@ class MetricsCollector:
|
|
|
111
112
|
"""
|
|
112
113
|
|
|
113
114
|
def __init__(self, cache: CrackerjackCache | None = None):
|
|
114
|
-
self.console = Console
|
|
115
|
+
self.console = depends.get_sync(Console)
|
|
115
116
|
self.cache = cache or CrackerjackCache()
|
|
116
117
|
|
|
117
118
|
self.is_collecting = False
|
|
@@ -6,7 +6,8 @@ from datetime import datetime, timedelta
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
|
-
from
|
|
9
|
+
from acb.console import Console
|
|
10
|
+
from acb.depends import depends
|
|
10
11
|
from rich.panel import Panel
|
|
11
12
|
from rich.table import Table
|
|
12
13
|
|
|
@@ -40,7 +41,7 @@ class RegressionAlert:
|
|
|
40
41
|
|
|
41
42
|
class RegressionPreventionSystem:
|
|
42
43
|
def __init__(self, console: Console | None = None):
|
|
43
|
-
self.console = console or Console
|
|
44
|
+
self.console = console or depends.get_sync(Console)
|
|
44
45
|
self.known_patterns: dict[str, RegressionPattern] = {}
|
|
45
46
|
self.regression_alerts: list[RegressionAlert] = []
|
|
46
47
|
self.prevention_active = True
|
|
@@ -565,7 +566,7 @@ async def monitor_for_regressions(
|
|
|
565
566
|
|
|
566
567
|
|
|
567
568
|
if __name__ == "__main__":
|
|
568
|
-
console = Console
|
|
569
|
+
console = depends.get_sync(Console)
|
|
569
570
|
system = RegressionPreventionSystem(console)
|
|
570
571
|
|
|
571
572
|
console.print(system.create_prevention_dashboard())
|