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,199 @@
|
|
|
1
|
+
"""REST API endpoints for quality intelligence features.
|
|
2
|
+
|
|
3
|
+
This module provides HTTP endpoints for anomaly detection, predictions,
|
|
4
|
+
insights, and pattern analysis.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import typing as t
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
|
|
10
|
+
from fastapi import FastAPI, HTTPException
|
|
11
|
+
from fastapi.responses import JSONResponse
|
|
12
|
+
|
|
13
|
+
from crackerjack.services.quality.quality_intelligence import (
|
|
14
|
+
QualityIntelligenceService,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def register_intelligence_api_endpoints(
|
|
19
|
+
app: FastAPI, intelligence_service: QualityIntelligenceService
|
|
20
|
+
) -> None:
|
|
21
|
+
"""Register intelligence-related REST API endpoints."""
|
|
22
|
+
|
|
23
|
+
@app.get("/api/intelligence/anomalies")
|
|
24
|
+
async def get_anomalies(days: int = 7, metrics: str = None) -> None:
|
|
25
|
+
"""Get anomaly detection results."""
|
|
26
|
+
return await _handle_anomalies_request(intelligence_service, days, metrics)
|
|
27
|
+
|
|
28
|
+
@app.get("/api/intelligence/predictions/{metric}")
|
|
29
|
+
async def get_metric_prediction(metric: str, horizon_days: int = 7) -> None:
|
|
30
|
+
"""Get prediction for a specific metric."""
|
|
31
|
+
return await _handle_metric_prediction_request(
|
|
32
|
+
intelligence_service, metric, horizon_days
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
@app.get("/api/intelligence/insights")
|
|
36
|
+
async def get_quality_insights(days: int = 30) -> None:
|
|
37
|
+
"""Get comprehensive quality insights."""
|
|
38
|
+
return await _handle_quality_insights_request(intelligence_service, days)
|
|
39
|
+
|
|
40
|
+
@app.get("/api/intelligence/patterns")
|
|
41
|
+
async def get_pattern_analysis(days: int = 30) -> None:
|
|
42
|
+
"""Get pattern recognition analysis."""
|
|
43
|
+
return await _handle_pattern_analysis_request(intelligence_service, days)
|
|
44
|
+
|
|
45
|
+
@app.post("/api/intelligence/analyze")
|
|
46
|
+
async def run_comprehensive_analysis(request: dict) -> None:
|
|
47
|
+
"""Run comprehensive intelligence analysis."""
|
|
48
|
+
return await _handle_comprehensive_analysis_request(
|
|
49
|
+
intelligence_service, request
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
async def _handle_anomalies_request(
|
|
54
|
+
intelligence_service: QualityIntelligenceService, days: int, metrics: str | None
|
|
55
|
+
) -> JSONResponse:
|
|
56
|
+
"""Handle anomalies API request."""
|
|
57
|
+
try:
|
|
58
|
+
if days > 365:
|
|
59
|
+
raise HTTPException(status_code=400, detail="Days parameter too large")
|
|
60
|
+
|
|
61
|
+
metrics_list = metrics.split(",") if metrics else None
|
|
62
|
+
anomalies = intelligence_service.detect_anomalies(
|
|
63
|
+
days=days, metrics=metrics_list
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
return JSONResponse(
|
|
67
|
+
{
|
|
68
|
+
"status": "success",
|
|
69
|
+
"data": [anomaly.to_dict() for anomaly in anomalies],
|
|
70
|
+
"timestamp": datetime.now().isoformat(),
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
except Exception as e:
|
|
74
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async def _handle_metric_prediction_request(
|
|
78
|
+
intelligence_service: QualityIntelligenceService, metric: str, horizon_days: int
|
|
79
|
+
) -> JSONResponse:
|
|
80
|
+
"""Handle metric prediction API request."""
|
|
81
|
+
try:
|
|
82
|
+
if horizon_days > 30:
|
|
83
|
+
raise HTTPException(status_code=400, detail="Horizon too far in the future")
|
|
84
|
+
|
|
85
|
+
all_predictions = intelligence_service.generate_advanced_predictions(
|
|
86
|
+
horizon_days
|
|
87
|
+
)
|
|
88
|
+
prediction = next((p for p in all_predictions if p.metric_name == metric), None)
|
|
89
|
+
if not prediction:
|
|
90
|
+
raise HTTPException(status_code=404, detail="Prediction not available")
|
|
91
|
+
|
|
92
|
+
return JSONResponse(
|
|
93
|
+
{
|
|
94
|
+
"status": "success",
|
|
95
|
+
"data": prediction.to_dict(),
|
|
96
|
+
"timestamp": datetime.now().isoformat(),
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
except Exception as e:
|
|
100
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
async def _handle_quality_insights_request(
|
|
104
|
+
intelligence_service: QualityIntelligenceService, days: int
|
|
105
|
+
) -> JSONResponse:
|
|
106
|
+
"""Handle quality insights API request."""
|
|
107
|
+
try:
|
|
108
|
+
if days > 365:
|
|
109
|
+
raise HTTPException(status_code=400, detail="Days parameter too large")
|
|
110
|
+
|
|
111
|
+
insights = intelligence_service.generate_comprehensive_insights(days=days)
|
|
112
|
+
|
|
113
|
+
return JSONResponse(
|
|
114
|
+
{
|
|
115
|
+
"status": "success",
|
|
116
|
+
"data": insights.to_dict(),
|
|
117
|
+
"timestamp": datetime.now().isoformat(),
|
|
118
|
+
}
|
|
119
|
+
)
|
|
120
|
+
except Exception as e:
|
|
121
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
async def _handle_pattern_analysis_request(
|
|
125
|
+
intelligence_service: QualityIntelligenceService, days: int
|
|
126
|
+
) -> JSONResponse:
|
|
127
|
+
"""Handle pattern analysis API request."""
|
|
128
|
+
try:
|
|
129
|
+
if days > 365:
|
|
130
|
+
raise HTTPException(status_code=400, detail="Days parameter too large")
|
|
131
|
+
|
|
132
|
+
patterns = intelligence_service.identify_patterns(days=days)
|
|
133
|
+
|
|
134
|
+
return JSONResponse(
|
|
135
|
+
{
|
|
136
|
+
"status": "success",
|
|
137
|
+
"data": patterns,
|
|
138
|
+
"timestamp": datetime.now().isoformat(),
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
except Exception as e:
|
|
142
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
async def _handle_comprehensive_analysis_request(
|
|
146
|
+
intelligence_service: QualityIntelligenceService, request: dict
|
|
147
|
+
) -> JSONResponse:
|
|
148
|
+
"""Handle comprehensive analysis API request."""
|
|
149
|
+
try:
|
|
150
|
+
days = request.get("days", 30)
|
|
151
|
+
|
|
152
|
+
if days > 365:
|
|
153
|
+
raise HTTPException(status_code=400, detail="Days parameter too large")
|
|
154
|
+
|
|
155
|
+
results = await _build_comprehensive_analysis_results(
|
|
156
|
+
intelligence_service, request, days
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
return JSONResponse(
|
|
160
|
+
{
|
|
161
|
+
"status": "success",
|
|
162
|
+
"data": results,
|
|
163
|
+
"timestamp": datetime.now().isoformat(),
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
except Exception as e:
|
|
167
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
async def _build_comprehensive_analysis_results(
|
|
171
|
+
intelligence_service: QualityIntelligenceService, request: dict, days: int
|
|
172
|
+
) -> dict[str, t.Any]:
|
|
173
|
+
"""Build comprehensive analysis results based on request parameters."""
|
|
174
|
+
results = {}
|
|
175
|
+
|
|
176
|
+
if request.get("include_anomalies", True):
|
|
177
|
+
results["anomalies"] = [
|
|
178
|
+
anomaly.to_dict()
|
|
179
|
+
for anomaly in intelligence_service.detect_anomalies(days=days)
|
|
180
|
+
]
|
|
181
|
+
|
|
182
|
+
if request.get("include_predictions", True):
|
|
183
|
+
insights = intelligence_service.generate_comprehensive_insights(days=days)
|
|
184
|
+
results["insights"] = insights.to_dict()
|
|
185
|
+
|
|
186
|
+
# Generate specific predictions
|
|
187
|
+
predictions = {}
|
|
188
|
+
for metric in ("quality_score", "test_coverage", "hook_duration"):
|
|
189
|
+
pred = intelligence_service.generate_advanced_predictions(
|
|
190
|
+
metric, horizon_days=7
|
|
191
|
+
)
|
|
192
|
+
if pred:
|
|
193
|
+
predictions[metric] = pred.to_dict()
|
|
194
|
+
results["predictions"] = predictions
|
|
195
|
+
|
|
196
|
+
if request.get("include_patterns", True):
|
|
197
|
+
results["patterns"] = intelligence_service.identify_patterns(days=days)
|
|
198
|
+
|
|
199
|
+
return results
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"""REST API endpoints for metrics and quality analysis.
|
|
2
|
+
|
|
3
|
+
This module provides HTTP endpoints for metrics summaries, quality trends,
|
|
4
|
+
alert configuration, and data export.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import csv
|
|
9
|
+
import typing as t
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
from io import StringIO
|
|
12
|
+
|
|
13
|
+
from fastapi import FastAPI, HTTPException
|
|
14
|
+
from fastapi.responses import JSONResponse, Response
|
|
15
|
+
|
|
16
|
+
from crackerjack.services.quality.quality_baseline_enhanced import (
|
|
17
|
+
EnhancedQualityBaselineService,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
from ..metrics import get_monitoring_current_metrics
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def register_metrics_api_endpoints(
|
|
24
|
+
app: FastAPI, job_manager: t.Any, quality_service: EnhancedQualityBaselineService
|
|
25
|
+
) -> None:
|
|
26
|
+
"""Register metrics-related REST API endpoints."""
|
|
27
|
+
|
|
28
|
+
@app.get("/api/metrics/summary")
|
|
29
|
+
async def get_metrics_summary() -> None:
|
|
30
|
+
"""Get current system summary."""
|
|
31
|
+
try:
|
|
32
|
+
current_metrics = await get_monitoring_current_metrics(
|
|
33
|
+
quality_service, job_manager
|
|
34
|
+
)
|
|
35
|
+
return JSONResponse(
|
|
36
|
+
{
|
|
37
|
+
"status": "success",
|
|
38
|
+
"data": current_metrics.to_dict(),
|
|
39
|
+
"timestamp": datetime.now().isoformat(),
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
except Exception as e:
|
|
43
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
44
|
+
|
|
45
|
+
@app.get("/api/trends/quality")
|
|
46
|
+
async def get_quality_trends(days: int = 30) -> None:
|
|
47
|
+
"""Get quality trend analysis."""
|
|
48
|
+
return await _handle_quality_trends_request(quality_service, days)
|
|
49
|
+
|
|
50
|
+
@app.get("/api/alerts/configure")
|
|
51
|
+
async def get_alert_configuration() -> None:
|
|
52
|
+
"""Get current alert configuration."""
|
|
53
|
+
return await _handle_get_alert_configuration(quality_service)
|
|
54
|
+
|
|
55
|
+
@app.post("/api/alerts/configure")
|
|
56
|
+
async def update_alert_configuration(config: dict) -> None:
|
|
57
|
+
"""Update alert configuration."""
|
|
58
|
+
return await _handle_update_alert_configuration(quality_service, config)
|
|
59
|
+
|
|
60
|
+
@app.get("/api/export/data")
|
|
61
|
+
async def export_data(days: int = 30, format: str = "json") -> None:
|
|
62
|
+
"""Export historical data for external analysis."""
|
|
63
|
+
return await _handle_export_data_request(quality_service, days, format)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
async def _handle_quality_trends_request(
|
|
67
|
+
quality_service: EnhancedQualityBaselineService, days: int
|
|
68
|
+
) -> JSONResponse:
|
|
69
|
+
"""Handle quality trends API request."""
|
|
70
|
+
try:
|
|
71
|
+
if days > 365:
|
|
72
|
+
raise HTTPException(status_code=400, detail="Days parameter too large")
|
|
73
|
+
|
|
74
|
+
trends = await asyncio.to_thread(
|
|
75
|
+
quality_service.analyze_quality_trend,
|
|
76
|
+
days,
|
|
77
|
+
)
|
|
78
|
+
return JSONResponse(
|
|
79
|
+
{
|
|
80
|
+
"status": "success",
|
|
81
|
+
"data": trends.to_dict(),
|
|
82
|
+
"timestamp": datetime.now().isoformat(),
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
except Exception as e:
|
|
86
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
async def _handle_get_alert_configuration(
|
|
90
|
+
quality_service: EnhancedQualityBaselineService,
|
|
91
|
+
) -> JSONResponse:
|
|
92
|
+
"""Handle get alert configuration API request."""
|
|
93
|
+
try:
|
|
94
|
+
config = quality_service.get_alert_thresholds()
|
|
95
|
+
return JSONResponse(
|
|
96
|
+
{
|
|
97
|
+
"status": "success",
|
|
98
|
+
"data": config,
|
|
99
|
+
"timestamp": datetime.now().isoformat(),
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
except Exception as e:
|
|
103
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
async def _handle_update_alert_configuration(
|
|
107
|
+
quality_service: EnhancedQualityBaselineService, config: dict
|
|
108
|
+
) -> JSONResponse:
|
|
109
|
+
"""Handle update alert configuration API request."""
|
|
110
|
+
try:
|
|
111
|
+
# Update individual thresholds
|
|
112
|
+
for metric, threshold in config.items():
|
|
113
|
+
quality_service.set_alert_threshold(metric, threshold)
|
|
114
|
+
return JSONResponse(
|
|
115
|
+
{
|
|
116
|
+
"status": "success",
|
|
117
|
+
"message": "Alert configuration updated",
|
|
118
|
+
"timestamp": datetime.now().isoformat(),
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
except Exception as e:
|
|
122
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
async def _handle_export_data_request(
|
|
126
|
+
quality_service: EnhancedQualityBaselineService, days: int, format_type: str
|
|
127
|
+
) -> JSONResponse | t.Any:
|
|
128
|
+
"""Handle export data API request."""
|
|
129
|
+
try:
|
|
130
|
+
if days > 365:
|
|
131
|
+
raise HTTPException(status_code=400, detail="Days parameter too large")
|
|
132
|
+
|
|
133
|
+
if format_type not in ("json", "csv"):
|
|
134
|
+
raise HTTPException(
|
|
135
|
+
status_code=400, detail="Format must be 'json' or 'csv'"
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
historical_baselines = await quality_service.aget_recent_baselines(limit=days)
|
|
139
|
+
|
|
140
|
+
if format_type == "csv":
|
|
141
|
+
return _export_csv_data(historical_baselines, days)
|
|
142
|
+
else:
|
|
143
|
+
data = [baseline.to_dict() for baseline in historical_baselines]
|
|
144
|
+
return JSONResponse(
|
|
145
|
+
{
|
|
146
|
+
"status": "success",
|
|
147
|
+
"data": data,
|
|
148
|
+
"timestamp": datetime.now().isoformat(),
|
|
149
|
+
}
|
|
150
|
+
)
|
|
151
|
+
except Exception as e:
|
|
152
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _export_csv_data(historical_baselines: list[t.Any], days: int) -> t.Any:
|
|
156
|
+
"""Export data in CSV format."""
|
|
157
|
+
output = StringIO()
|
|
158
|
+
writer = csv.writer(output)
|
|
159
|
+
|
|
160
|
+
# Write header
|
|
161
|
+
writer.writerow(
|
|
162
|
+
[
|
|
163
|
+
"timestamp",
|
|
164
|
+
"git_hash",
|
|
165
|
+
"quality_score",
|
|
166
|
+
"coverage_percent",
|
|
167
|
+
"test_count",
|
|
168
|
+
"test_pass_rate",
|
|
169
|
+
"hook_failures",
|
|
170
|
+
"complexity_violations",
|
|
171
|
+
"security_issues",
|
|
172
|
+
"type_errors",
|
|
173
|
+
"linting_issues",
|
|
174
|
+
]
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
# Write data
|
|
178
|
+
for baseline in historical_baselines:
|
|
179
|
+
writer.writerow(
|
|
180
|
+
[
|
|
181
|
+
baseline.timestamp.isoformat(),
|
|
182
|
+
baseline.git_hash,
|
|
183
|
+
baseline.quality_score,
|
|
184
|
+
baseline.coverage_percent,
|
|
185
|
+
baseline.test_count,
|
|
186
|
+
baseline.test_pass_rate,
|
|
187
|
+
baseline.hook_failures,
|
|
188
|
+
baseline.complexity_violations,
|
|
189
|
+
baseline.security_issues,
|
|
190
|
+
baseline.type_errors,
|
|
191
|
+
baseline.linting_issues,
|
|
192
|
+
]
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
return Response(
|
|
196
|
+
content=output.getvalue(),
|
|
197
|
+
media_type="text/csv",
|
|
198
|
+
headers={
|
|
199
|
+
"Content-Disposition": (
|
|
200
|
+
f"attachment; filename=crackerjack_metrics_{days}d.csv"
|
|
201
|
+
)
|
|
202
|
+
},
|
|
203
|
+
)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""REST API endpoints for telemetry and health monitoring.
|
|
2
|
+
|
|
3
|
+
This module provides HTTP endpoints for workflow event telemetry
|
|
4
|
+
and system health metrics.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import typing as t
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
|
|
10
|
+
from fastapi import FastAPI
|
|
11
|
+
|
|
12
|
+
from crackerjack.events import WorkflowEventTelemetry
|
|
13
|
+
from crackerjack.services.quality.quality_baseline_enhanced import (
|
|
14
|
+
EnhancedQualityBaselineService,
|
|
15
|
+
UnifiedMetrics,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from ..metrics import get_monitoring_current_metrics
|
|
19
|
+
from ..models import (
|
|
20
|
+
HealthResponseModel,
|
|
21
|
+
TelemetryEventModel,
|
|
22
|
+
TelemetryResponseModel,
|
|
23
|
+
TelemetrySnapshotModel,
|
|
24
|
+
UnifiedMetricsModel,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def register_telemetry_api_endpoints(
|
|
29
|
+
app: FastAPI,
|
|
30
|
+
job_manager: t.Any,
|
|
31
|
+
telemetry: WorkflowEventTelemetry,
|
|
32
|
+
quality_service: EnhancedQualityBaselineService,
|
|
33
|
+
) -> None:
|
|
34
|
+
"""Register telemetry and dashboard REST endpoints."""
|
|
35
|
+
|
|
36
|
+
@app.get(
|
|
37
|
+
"/monitoring/events",
|
|
38
|
+
response_model=TelemetryResponseModel,
|
|
39
|
+
summary="Get workflow telemetry snapshot",
|
|
40
|
+
)
|
|
41
|
+
async def get_monitoring_events() -> TelemetryResponseModel:
|
|
42
|
+
snapshot = await telemetry.snapshot()
|
|
43
|
+
data = TelemetrySnapshotModel(
|
|
44
|
+
counts=snapshot.get("counts", {}),
|
|
45
|
+
recent_events=[
|
|
46
|
+
TelemetryEventModel.model_validate(event)
|
|
47
|
+
for event in snapshot.get("recent_events", [])
|
|
48
|
+
],
|
|
49
|
+
last_error=None, # Adjust based on how last_error is stored in snapshot
|
|
50
|
+
)
|
|
51
|
+
return TelemetryResponseModel(
|
|
52
|
+
status="success",
|
|
53
|
+
data=data,
|
|
54
|
+
timestamp=datetime.now(),
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
@app.post(
|
|
58
|
+
"/monitoring/events/reset",
|
|
59
|
+
response_model=TelemetryResponseModel,
|
|
60
|
+
summary="Reset workflow telemetry history",
|
|
61
|
+
)
|
|
62
|
+
async def reset_monitoring_events() -> TelemetryResponseModel:
|
|
63
|
+
await telemetry.reset()
|
|
64
|
+
snapshot = await telemetry.snapshot()
|
|
65
|
+
data = TelemetrySnapshotModel(
|
|
66
|
+
counts=snapshot.get("counts", {}),
|
|
67
|
+
recent_events=[
|
|
68
|
+
TelemetryEventModel.model_validate(event)
|
|
69
|
+
for event in snapshot.get("recent_events", [])
|
|
70
|
+
],
|
|
71
|
+
last_error=None, # Adjust based on how last_error is stored in snapshot
|
|
72
|
+
)
|
|
73
|
+
return TelemetryResponseModel(
|
|
74
|
+
status="success",
|
|
75
|
+
data=data,
|
|
76
|
+
timestamp=datetime.now(),
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
@app.get(
|
|
80
|
+
"/monitoring/health",
|
|
81
|
+
response_model=HealthResponseModel,
|
|
82
|
+
summary="Retrieve aggregated monitoring health metrics",
|
|
83
|
+
)
|
|
84
|
+
async def get_monitoring_health() -> HealthResponseModel:
|
|
85
|
+
unified_metrics = await get_monitoring_current_metrics(
|
|
86
|
+
quality_service, job_manager
|
|
87
|
+
) # Use the function parameters
|
|
88
|
+
return HealthResponseModel(
|
|
89
|
+
status=_derive_health_status(unified_metrics),
|
|
90
|
+
data=UnifiedMetricsModel.from_domain(unified_metrics),
|
|
91
|
+
timestamp=datetime.now(),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _derive_health_status(metrics: UnifiedMetrics) -> str:
|
|
96
|
+
"""Derive a coarse health status string from unified metrics."""
|
|
97
|
+
if metrics.error_count > 5 or metrics.quality_score < 40:
|
|
98
|
+
return "critical"
|
|
99
|
+
if metrics.error_count > 0 or metrics.quality_score < 60:
|
|
100
|
+
return "warning"
|
|
101
|
+
return "healthy"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Dashboard HTML rendering for monitoring endpoints.
|
|
2
|
+
|
|
3
|
+
This module provides the HTML dashboard endpoint for the monitoring system.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from fastapi.responses import HTMLResponse
|
|
7
|
+
|
|
8
|
+
from crackerjack.ui.dashboard_renderer import render_monitoring_dashboard
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
async def get_dashboard_html() -> HTMLResponse:
|
|
12
|
+
"""Serve the monitoring dashboard HTML."""
|
|
13
|
+
return HTMLResponse(_get_dashboard_html())
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _get_dashboard_html() -> str:
|
|
17
|
+
"""Generate the monitoring dashboard HTML."""
|
|
18
|
+
return render_monitoring_dashboard()
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Factory module for monitoring endpoint registration.
|
|
2
|
+
|
|
3
|
+
This module orchestrates the initialization of all monitoring services
|
|
4
|
+
and registration of WebSocket and REST API endpoints.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import typing as t
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from acb.depends import depends
|
|
11
|
+
from fastapi import FastAPI
|
|
12
|
+
|
|
13
|
+
from crackerjack.events import WorkflowEventTelemetry
|
|
14
|
+
from crackerjack.services.cache import CrackerjackCache
|
|
15
|
+
from crackerjack.services.dependency_analyzer import DependencyAnalyzer
|
|
16
|
+
from crackerjack.services.monitoring.error_pattern_analyzer import (
|
|
17
|
+
ErrorPatternAnalyzer,
|
|
18
|
+
)
|
|
19
|
+
from crackerjack.services.quality.quality_baseline_enhanced import (
|
|
20
|
+
EnhancedQualityBaselineService,
|
|
21
|
+
)
|
|
22
|
+
from crackerjack.services.quality.quality_intelligence import (
|
|
23
|
+
QualityIntelligenceService,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
from .api.dependencies import register_dependency_api_endpoints
|
|
27
|
+
from .api.heatmap import register_heatmap_api_endpoints
|
|
28
|
+
from .api.intelligence import register_intelligence_api_endpoints
|
|
29
|
+
from .api.metrics import register_metrics_api_endpoints
|
|
30
|
+
from .api.telemetry import register_telemetry_api_endpoints
|
|
31
|
+
from .dashboard import get_dashboard_html
|
|
32
|
+
from .websocket_manager import MonitoringWebSocketManager
|
|
33
|
+
from .websockets.dependencies import register_dependency_websockets
|
|
34
|
+
from .websockets.heatmap import register_heatmap_websockets
|
|
35
|
+
from .websockets.intelligence import register_intelligence_websockets
|
|
36
|
+
from .websockets.metrics import register_metrics_websockets
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def create_monitoring_endpoints(
|
|
40
|
+
app: FastAPI,
|
|
41
|
+
job_manager: t.Any,
|
|
42
|
+
progress_dir: Path,
|
|
43
|
+
ws_manager: MonitoringWebSocketManager,
|
|
44
|
+
) -> None:
|
|
45
|
+
"""Add monitoring endpoints to the FastAPI app."""
|
|
46
|
+
services = _initialize_monitoring_services(progress_dir)
|
|
47
|
+
|
|
48
|
+
_register_websocket_endpoints(app, job_manager, ws_manager, services)
|
|
49
|
+
_register_rest_api_endpoints(app, job_manager, services)
|
|
50
|
+
_register_dashboard_endpoint(app)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _initialize_monitoring_services(progress_dir: Path) -> dict[str, t.Any]:
|
|
54
|
+
"""Initialize all monitoring services."""
|
|
55
|
+
cache = CrackerjackCache()
|
|
56
|
+
quality_service = EnhancedQualityBaselineService(cache=cache)
|
|
57
|
+
intelligence_service = QualityIntelligenceService(quality_service)
|
|
58
|
+
dependency_analyzer = DependencyAnalyzer(progress_dir.parent)
|
|
59
|
+
error_analyzer = ErrorPatternAnalyzer(progress_dir.parent)
|
|
60
|
+
try:
|
|
61
|
+
telemetry = depends.get_sync(WorkflowEventTelemetry)
|
|
62
|
+
except Exception:
|
|
63
|
+
telemetry = WorkflowEventTelemetry()
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
"cache": cache,
|
|
67
|
+
"quality_service": quality_service,
|
|
68
|
+
"intelligence_service": intelligence_service,
|
|
69
|
+
"dependency_analyzer": dependency_analyzer,
|
|
70
|
+
"error_analyzer": error_analyzer,
|
|
71
|
+
"telemetry": telemetry,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _register_websocket_endpoints(
|
|
76
|
+
app: FastAPI,
|
|
77
|
+
job_manager: t.Any,
|
|
78
|
+
ws_manager: MonitoringWebSocketManager,
|
|
79
|
+
services: dict[str, t.Any],
|
|
80
|
+
) -> None:
|
|
81
|
+
"""Register all WebSocket endpoints."""
|
|
82
|
+
register_metrics_websockets(
|
|
83
|
+
app, job_manager, ws_manager, services["quality_service"]
|
|
84
|
+
)
|
|
85
|
+
register_intelligence_websockets(app, ws_manager, services["intelligence_service"])
|
|
86
|
+
register_dependency_websockets(app, ws_manager, services["dependency_analyzer"])
|
|
87
|
+
register_heatmap_websockets(app, services["error_analyzer"])
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _register_rest_api_endpoints(
|
|
91
|
+
app: FastAPI, job_manager: t.Any, services: dict[str, t.Any]
|
|
92
|
+
) -> None:
|
|
93
|
+
"""Register all REST API endpoints."""
|
|
94
|
+
register_telemetry_api_endpoints(
|
|
95
|
+
app, job_manager, services["telemetry"], services["quality_service"]
|
|
96
|
+
)
|
|
97
|
+
register_metrics_api_endpoints(app, job_manager, services["quality_service"])
|
|
98
|
+
register_intelligence_api_endpoints(app, services["intelligence_service"])
|
|
99
|
+
register_dependency_api_endpoints(app, services["dependency_analyzer"])
|
|
100
|
+
register_heatmap_api_endpoints(app, services["error_analyzer"], services["cache"])
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _register_dashboard_endpoint(app: FastAPI) -> None:
|
|
104
|
+
"""Register the dashboard HTML endpoint."""
|
|
105
|
+
|
|
106
|
+
@app.get("/dashboard")
|
|
107
|
+
async def dashboard_endpoint() -> None:
|
|
108
|
+
"""Serve the monitoring dashboard HTML."""
|
|
109
|
+
return await get_dashboard_html()
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Filter utilities for monitoring system.
|
|
2
|
+
|
|
3
|
+
This module contains functions for applying various filters to monitoring data.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _apply_graph_filters(graph, filters):
|
|
8
|
+
"""Apply graph filters for monitoring purposes."""
|
|
9
|
+
# Implementation of graph filter functionality
|
|
10
|
+
return graph
|