crackerjack 0.18.2__py3-none-any.whl → 0.45.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- crackerjack/README.md +19 -0
- crackerjack/__init__.py +96 -2
- crackerjack/__main__.py +637 -138
- crackerjack/adapters/README.md +18 -0
- crackerjack/adapters/__init__.py +39 -0
- crackerjack/adapters/_output_paths.py +167 -0
- crackerjack/adapters/_qa_adapter_base.py +309 -0
- crackerjack/adapters/_tool_adapter_base.py +706 -0
- crackerjack/adapters/ai/README.md +65 -0
- crackerjack/adapters/ai/__init__.py +5 -0
- crackerjack/adapters/ai/claude.py +853 -0
- crackerjack/adapters/complexity/README.md +53 -0
- crackerjack/adapters/complexity/__init__.py +10 -0
- crackerjack/adapters/complexity/complexipy.py +641 -0
- crackerjack/adapters/dependency/__init__.py +22 -0
- crackerjack/adapters/dependency/pip_audit.py +418 -0
- crackerjack/adapters/format/README.md +72 -0
- crackerjack/adapters/format/__init__.py +11 -0
- crackerjack/adapters/format/mdformat.py +313 -0
- crackerjack/adapters/format/ruff.py +516 -0
- crackerjack/adapters/lint/README.md +47 -0
- crackerjack/adapters/lint/__init__.py +11 -0
- crackerjack/adapters/lint/codespell.py +273 -0
- crackerjack/adapters/lsp/README.md +49 -0
- crackerjack/adapters/lsp/__init__.py +27 -0
- crackerjack/adapters/lsp/_base.py +194 -0
- crackerjack/adapters/lsp/_client.py +358 -0
- crackerjack/adapters/lsp/_manager.py +193 -0
- crackerjack/adapters/lsp/skylos.py +283 -0
- crackerjack/adapters/lsp/zuban.py +557 -0
- crackerjack/adapters/refactor/README.md +59 -0
- crackerjack/adapters/refactor/__init__.py +12 -0
- crackerjack/adapters/refactor/creosote.py +318 -0
- crackerjack/adapters/refactor/refurb.py +406 -0
- crackerjack/adapters/refactor/skylos.py +494 -0
- crackerjack/adapters/sast/README.md +132 -0
- crackerjack/adapters/sast/__init__.py +32 -0
- crackerjack/adapters/sast/_base.py +201 -0
- crackerjack/adapters/sast/bandit.py +423 -0
- crackerjack/adapters/sast/pyscn.py +405 -0
- crackerjack/adapters/sast/semgrep.py +241 -0
- crackerjack/adapters/security/README.md +111 -0
- crackerjack/adapters/security/__init__.py +17 -0
- crackerjack/adapters/security/gitleaks.py +339 -0
- crackerjack/adapters/type/README.md +52 -0
- crackerjack/adapters/type/__init__.py +12 -0
- crackerjack/adapters/type/pyrefly.py +402 -0
- crackerjack/adapters/type/ty.py +402 -0
- crackerjack/adapters/type/zuban.py +522 -0
- crackerjack/adapters/utility/README.md +51 -0
- crackerjack/adapters/utility/__init__.py +10 -0
- crackerjack/adapters/utility/checks.py +884 -0
- crackerjack/agents/README.md +264 -0
- crackerjack/agents/__init__.py +66 -0
- crackerjack/agents/architect_agent.py +238 -0
- crackerjack/agents/base.py +167 -0
- crackerjack/agents/claude_code_bridge.py +641 -0
- crackerjack/agents/coordinator.py +600 -0
- crackerjack/agents/documentation_agent.py +520 -0
- crackerjack/agents/dry_agent.py +585 -0
- crackerjack/agents/enhanced_coordinator.py +279 -0
- crackerjack/agents/enhanced_proactive_agent.py +185 -0
- crackerjack/agents/error_middleware.py +53 -0
- crackerjack/agents/formatting_agent.py +230 -0
- crackerjack/agents/helpers/__init__.py +9 -0
- crackerjack/agents/helpers/performance/__init__.py +22 -0
- crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
- crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
- crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
- crackerjack/agents/helpers/refactoring/__init__.py +22 -0
- crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
- crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
- crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
- crackerjack/agents/helpers/test_creation/__init__.py +19 -0
- crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
- crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
- crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
- crackerjack/agents/import_optimization_agent.py +1181 -0
- crackerjack/agents/performance_agent.py +325 -0
- crackerjack/agents/performance_helpers.py +205 -0
- crackerjack/agents/proactive_agent.py +55 -0
- crackerjack/agents/refactoring_agent.py +511 -0
- crackerjack/agents/refactoring_helpers.py +247 -0
- crackerjack/agents/security_agent.py +793 -0
- crackerjack/agents/semantic_agent.py +479 -0
- crackerjack/agents/semantic_helpers.py +356 -0
- crackerjack/agents/test_creation_agent.py +570 -0
- crackerjack/agents/test_specialist_agent.py +526 -0
- crackerjack/agents/tracker.py +110 -0
- crackerjack/api.py +647 -0
- crackerjack/cli/README.md +394 -0
- crackerjack/cli/__init__.py +24 -0
- crackerjack/cli/cache_handlers.py +209 -0
- crackerjack/cli/cache_handlers_enhanced.py +680 -0
- crackerjack/cli/facade.py +162 -0
- crackerjack/cli/formatting.py +13 -0
- crackerjack/cli/handlers/__init__.py +85 -0
- crackerjack/cli/handlers/advanced.py +103 -0
- crackerjack/cli/handlers/ai_features.py +62 -0
- crackerjack/cli/handlers/analytics.py +479 -0
- crackerjack/cli/handlers/changelog.py +271 -0
- crackerjack/cli/handlers/config_handlers.py +16 -0
- crackerjack/cli/handlers/coverage.py +84 -0
- crackerjack/cli/handlers/documentation.py +280 -0
- crackerjack/cli/handlers/main_handlers.py +497 -0
- crackerjack/cli/handlers/monitoring.py +371 -0
- crackerjack/cli/handlers.py +700 -0
- crackerjack/cli/interactive.py +488 -0
- crackerjack/cli/options.py +1216 -0
- crackerjack/cli/semantic_handlers.py +292 -0
- crackerjack/cli/utils.py +19 -0
- crackerjack/cli/version.py +19 -0
- crackerjack/code_cleaner.py +1307 -0
- crackerjack/config/README.md +472 -0
- crackerjack/config/__init__.py +275 -0
- crackerjack/config/global_lock_config.py +207 -0
- crackerjack/config/hooks.py +390 -0
- crackerjack/config/loader.py +239 -0
- crackerjack/config/settings.py +141 -0
- crackerjack/config/tool_commands.py +331 -0
- crackerjack/core/README.md +393 -0
- crackerjack/core/__init__.py +0 -0
- crackerjack/core/async_workflow_orchestrator.py +738 -0
- crackerjack/core/autofix_coordinator.py +282 -0
- crackerjack/core/container.py +105 -0
- crackerjack/core/enhanced_container.py +583 -0
- crackerjack/core/file_lifecycle.py +472 -0
- crackerjack/core/performance.py +244 -0
- crackerjack/core/performance_monitor.py +357 -0
- crackerjack/core/phase_coordinator.py +1227 -0
- crackerjack/core/proactive_workflow.py +267 -0
- crackerjack/core/resource_manager.py +425 -0
- crackerjack/core/retry.py +275 -0
- crackerjack/core/service_watchdog.py +601 -0
- crackerjack/core/session_coordinator.py +239 -0
- crackerjack/core/timeout_manager.py +563 -0
- crackerjack/core/websocket_lifecycle.py +410 -0
- crackerjack/core/workflow/__init__.py +21 -0
- crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
- crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
- crackerjack/core/workflow/workflow_issue_parser.py +714 -0
- crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
- crackerjack/core/workflow/workflow_security_gates.py +400 -0
- crackerjack/core/workflow_orchestrator.py +2243 -0
- crackerjack/data/README.md +11 -0
- crackerjack/data/__init__.py +8 -0
- crackerjack/data/models.py +79 -0
- crackerjack/data/repository.py +210 -0
- crackerjack/decorators/README.md +180 -0
- crackerjack/decorators/__init__.py +35 -0
- crackerjack/decorators/error_handling.py +649 -0
- crackerjack/decorators/error_handling_decorators.py +334 -0
- crackerjack/decorators/helpers.py +58 -0
- crackerjack/decorators/patterns.py +281 -0
- crackerjack/decorators/utils.py +58 -0
- crackerjack/docs/INDEX.md +11 -0
- crackerjack/docs/README.md +11 -0
- crackerjack/docs/generated/api/API_REFERENCE.md +10895 -0
- crackerjack/docs/generated/api/CLI_REFERENCE.md +109 -0
- crackerjack/docs/generated/api/CROSS_REFERENCES.md +1755 -0
- crackerjack/docs/generated/api/PROTOCOLS.md +3 -0
- crackerjack/docs/generated/api/SERVICES.md +1252 -0
- crackerjack/documentation/README.md +11 -0
- crackerjack/documentation/__init__.py +31 -0
- crackerjack/documentation/ai_templates.py +756 -0
- crackerjack/documentation/dual_output_generator.py +767 -0
- crackerjack/documentation/mkdocs_integration.py +518 -0
- crackerjack/documentation/reference_generator.py +1065 -0
- crackerjack/dynamic_config.py +678 -0
- crackerjack/errors.py +378 -0
- crackerjack/events/README.md +11 -0
- crackerjack/events/__init__.py +16 -0
- crackerjack/events/telemetry.py +175 -0
- crackerjack/events/workflow_bus.py +346 -0
- crackerjack/exceptions/README.md +301 -0
- crackerjack/exceptions/__init__.py +5 -0
- crackerjack/exceptions/config.py +4 -0
- crackerjack/exceptions/tool_execution_error.py +245 -0
- crackerjack/executors/README.md +591 -0
- crackerjack/executors/__init__.py +13 -0
- crackerjack/executors/async_hook_executor.py +938 -0
- crackerjack/executors/cached_hook_executor.py +316 -0
- crackerjack/executors/hook_executor.py +1295 -0
- crackerjack/executors/hook_lock_manager.py +708 -0
- crackerjack/executors/individual_hook_executor.py +739 -0
- crackerjack/executors/lsp_aware_hook_executor.py +349 -0
- crackerjack/executors/progress_hook_executor.py +282 -0
- crackerjack/executors/tool_proxy.py +433 -0
- crackerjack/hooks/README.md +485 -0
- crackerjack/hooks/lsp_hook.py +93 -0
- crackerjack/intelligence/README.md +557 -0
- crackerjack/intelligence/__init__.py +37 -0
- crackerjack/intelligence/adaptive_learning.py +693 -0
- crackerjack/intelligence/agent_orchestrator.py +485 -0
- crackerjack/intelligence/agent_registry.py +377 -0
- crackerjack/intelligence/agent_selector.py +439 -0
- crackerjack/intelligence/integration.py +250 -0
- crackerjack/interactive.py +719 -0
- crackerjack/managers/README.md +369 -0
- crackerjack/managers/__init__.py +11 -0
- crackerjack/managers/async_hook_manager.py +135 -0
- crackerjack/managers/hook_manager.py +585 -0
- crackerjack/managers/publish_manager.py +631 -0
- crackerjack/managers/test_command_builder.py +391 -0
- crackerjack/managers/test_executor.py +474 -0
- crackerjack/managers/test_manager.py +1357 -0
- crackerjack/managers/test_progress.py +187 -0
- crackerjack/mcp/README.md +374 -0
- crackerjack/mcp/__init__.py +0 -0
- crackerjack/mcp/cache.py +352 -0
- crackerjack/mcp/client_runner.py +121 -0
- crackerjack/mcp/context.py +802 -0
- crackerjack/mcp/dashboard.py +657 -0
- crackerjack/mcp/enhanced_progress_monitor.py +493 -0
- crackerjack/mcp/file_monitor.py +394 -0
- crackerjack/mcp/progress_components.py +607 -0
- crackerjack/mcp/progress_monitor.py +1016 -0
- crackerjack/mcp/rate_limiter.py +336 -0
- crackerjack/mcp/server.py +24 -0
- crackerjack/mcp/server_core.py +526 -0
- crackerjack/mcp/service_watchdog.py +505 -0
- crackerjack/mcp/state.py +407 -0
- crackerjack/mcp/task_manager.py +259 -0
- crackerjack/mcp/tools/README.md +27 -0
- crackerjack/mcp/tools/__init__.py +19 -0
- crackerjack/mcp/tools/core_tools.py +469 -0
- crackerjack/mcp/tools/error_analyzer.py +283 -0
- crackerjack/mcp/tools/execution_tools.py +384 -0
- crackerjack/mcp/tools/intelligence_tool_registry.py +46 -0
- crackerjack/mcp/tools/intelligence_tools.py +264 -0
- crackerjack/mcp/tools/monitoring_tools.py +628 -0
- crackerjack/mcp/tools/proactive_tools.py +367 -0
- crackerjack/mcp/tools/progress_tools.py +222 -0
- crackerjack/mcp/tools/semantic_tools.py +584 -0
- crackerjack/mcp/tools/utility_tools.py +358 -0
- crackerjack/mcp/tools/workflow_executor.py +699 -0
- crackerjack/mcp/websocket/README.md +31 -0
- crackerjack/mcp/websocket/__init__.py +14 -0
- crackerjack/mcp/websocket/app.py +54 -0
- crackerjack/mcp/websocket/endpoints.py +492 -0
- crackerjack/mcp/websocket/event_bridge.py +188 -0
- crackerjack/mcp/websocket/jobs.py +406 -0
- crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
- crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
- crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
- crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
- crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
- crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
- crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
- crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
- crackerjack/mcp/websocket/monitoring/factory.py +109 -0
- crackerjack/mcp/websocket/monitoring/filters.py +10 -0
- crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
- crackerjack/mcp/websocket/monitoring/models.py +90 -0
- crackerjack/mcp/websocket/monitoring/utils.py +171 -0
- crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
- crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
- crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
- crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
- crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
- crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
- crackerjack/mcp/websocket/monitoring_endpoints.py +21 -0
- crackerjack/mcp/websocket/server.py +174 -0
- crackerjack/mcp/websocket/websocket_handler.py +276 -0
- crackerjack/mcp/websocket_server.py +10 -0
- crackerjack/models/README.md +308 -0
- crackerjack/models/__init__.py +40 -0
- crackerjack/models/config.py +730 -0
- crackerjack/models/config_adapter.py +265 -0
- crackerjack/models/protocols.py +1535 -0
- crackerjack/models/pydantic_models.py +320 -0
- crackerjack/models/qa_config.py +145 -0
- crackerjack/models/qa_results.py +134 -0
- crackerjack/models/resource_protocols.py +299 -0
- crackerjack/models/results.py +35 -0
- crackerjack/models/semantic_models.py +258 -0
- crackerjack/models/task.py +173 -0
- crackerjack/models/test_models.py +60 -0
- crackerjack/monitoring/README.md +11 -0
- crackerjack/monitoring/__init__.py +0 -0
- crackerjack/monitoring/ai_agent_watchdog.py +405 -0
- crackerjack/monitoring/metrics_collector.py +427 -0
- crackerjack/monitoring/regression_prevention.py +580 -0
- crackerjack/monitoring/websocket_server.py +406 -0
- crackerjack/orchestration/README.md +340 -0
- crackerjack/orchestration/__init__.py +43 -0
- crackerjack/orchestration/advanced_orchestrator.py +894 -0
- crackerjack/orchestration/cache/README.md +312 -0
- crackerjack/orchestration/cache/__init__.py +37 -0
- crackerjack/orchestration/cache/memory_cache.py +338 -0
- crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
- crackerjack/orchestration/config.py +297 -0
- crackerjack/orchestration/coverage_improvement.py +180 -0
- crackerjack/orchestration/execution_strategies.py +361 -0
- crackerjack/orchestration/hook_orchestrator.py +1398 -0
- crackerjack/orchestration/strategies/README.md +401 -0
- crackerjack/orchestration/strategies/__init__.py +39 -0
- crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
- crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
- crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
- crackerjack/orchestration/test_progress_streamer.py +647 -0
- crackerjack/plugins/README.md +11 -0
- crackerjack/plugins/__init__.py +15 -0
- crackerjack/plugins/base.py +200 -0
- crackerjack/plugins/hooks.py +254 -0
- crackerjack/plugins/loader.py +335 -0
- crackerjack/plugins/managers.py +264 -0
- crackerjack/py313.py +191 -0
- crackerjack/security/README.md +11 -0
- crackerjack/security/__init__.py +0 -0
- crackerjack/security/audit.py +197 -0
- crackerjack/services/README.md +374 -0
- crackerjack/services/__init__.py +9 -0
- crackerjack/services/ai/README.md +295 -0
- crackerjack/services/ai/__init__.py +7 -0
- crackerjack/services/ai/advanced_optimizer.py +878 -0
- crackerjack/services/ai/contextual_ai_assistant.py +542 -0
- crackerjack/services/ai/embeddings.py +444 -0
- crackerjack/services/ai/intelligent_commit.py +328 -0
- crackerjack/services/ai/predictive_analytics.py +510 -0
- crackerjack/services/anomaly_detector.py +392 -0
- crackerjack/services/api_extractor.py +617 -0
- crackerjack/services/backup_service.py +467 -0
- crackerjack/services/bounded_status_operations.py +530 -0
- crackerjack/services/cache.py +369 -0
- crackerjack/services/changelog_automation.py +399 -0
- crackerjack/services/command_execution_service.py +305 -0
- crackerjack/services/config_integrity.py +132 -0
- crackerjack/services/config_merge.py +546 -0
- crackerjack/services/config_service.py +198 -0
- crackerjack/services/config_template.py +493 -0
- crackerjack/services/coverage_badge_service.py +173 -0
- crackerjack/services/coverage_ratchet.py +381 -0
- crackerjack/services/debug.py +733 -0
- crackerjack/services/dependency_analyzer.py +460 -0
- crackerjack/services/dependency_monitor.py +622 -0
- crackerjack/services/documentation_generator.py +493 -0
- crackerjack/services/documentation_service.py +704 -0
- crackerjack/services/enhanced_filesystem.py +497 -0
- crackerjack/services/enterprise_optimizer.py +865 -0
- crackerjack/services/error_pattern_analyzer.py +676 -0
- crackerjack/services/file_filter.py +221 -0
- crackerjack/services/file_hasher.py +149 -0
- crackerjack/services/file_io_service.py +361 -0
- crackerjack/services/file_modifier.py +615 -0
- crackerjack/services/filesystem.py +381 -0
- crackerjack/services/git.py +422 -0
- crackerjack/services/health_metrics.py +615 -0
- crackerjack/services/heatmap_generator.py +744 -0
- crackerjack/services/incremental_executor.py +380 -0
- crackerjack/services/initialization.py +823 -0
- crackerjack/services/input_validator.py +668 -0
- crackerjack/services/intelligent_commit.py +327 -0
- crackerjack/services/log_manager.py +289 -0
- crackerjack/services/logging.py +228 -0
- crackerjack/services/lsp_client.py +628 -0
- crackerjack/services/memory_optimizer.py +414 -0
- crackerjack/services/metrics.py +587 -0
- crackerjack/services/monitoring/README.md +30 -0
- crackerjack/services/monitoring/__init__.py +9 -0
- crackerjack/services/monitoring/dependency_monitor.py +678 -0
- crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
- crackerjack/services/monitoring/health_metrics.py +716 -0
- crackerjack/services/monitoring/metrics.py +587 -0
- crackerjack/services/monitoring/performance_benchmarks.py +410 -0
- crackerjack/services/monitoring/performance_cache.py +388 -0
- crackerjack/services/monitoring/performance_monitor.py +569 -0
- crackerjack/services/parallel_executor.py +527 -0
- crackerjack/services/pattern_cache.py +333 -0
- crackerjack/services/pattern_detector.py +478 -0
- crackerjack/services/patterns/__init__.py +142 -0
- crackerjack/services/patterns/agents.py +107 -0
- crackerjack/services/patterns/code/__init__.py +15 -0
- crackerjack/services/patterns/code/detection.py +118 -0
- crackerjack/services/patterns/code/imports.py +107 -0
- crackerjack/services/patterns/code/paths.py +159 -0
- crackerjack/services/patterns/code/performance.py +119 -0
- crackerjack/services/patterns/code/replacement.py +36 -0
- crackerjack/services/patterns/core.py +212 -0
- crackerjack/services/patterns/documentation/__init__.py +14 -0
- crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
- crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
- crackerjack/services/patterns/documentation/docstrings.py +89 -0
- crackerjack/services/patterns/formatting.py +226 -0
- crackerjack/services/patterns/operations.py +339 -0
- crackerjack/services/patterns/security/__init__.py +23 -0
- crackerjack/services/patterns/security/code_injection.py +122 -0
- crackerjack/services/patterns/security/credentials.py +190 -0
- crackerjack/services/patterns/security/path_traversal.py +221 -0
- crackerjack/services/patterns/security/unsafe_operations.py +216 -0
- crackerjack/services/patterns/templates.py +62 -0
- crackerjack/services/patterns/testing/__init__.py +18 -0
- crackerjack/services/patterns/testing/error_patterns.py +107 -0
- crackerjack/services/patterns/testing/pytest_output.py +126 -0
- crackerjack/services/patterns/tool_output/__init__.py +16 -0
- crackerjack/services/patterns/tool_output/bandit.py +72 -0
- crackerjack/services/patterns/tool_output/other.py +97 -0
- crackerjack/services/patterns/tool_output/pyright.py +67 -0
- crackerjack/services/patterns/tool_output/ruff.py +44 -0
- crackerjack/services/patterns/url_sanitization.py +114 -0
- crackerjack/services/patterns/utilities.py +42 -0
- crackerjack/services/patterns/utils.py +339 -0
- crackerjack/services/patterns/validation.py +46 -0
- crackerjack/services/patterns/versioning.py +62 -0
- crackerjack/services/predictive_analytics.py +523 -0
- crackerjack/services/profiler.py +280 -0
- crackerjack/services/quality/README.md +415 -0
- crackerjack/services/quality/__init__.py +11 -0
- crackerjack/services/quality/anomaly_detector.py +392 -0
- crackerjack/services/quality/pattern_cache.py +333 -0
- crackerjack/services/quality/pattern_detector.py +479 -0
- crackerjack/services/quality/qa_orchestrator.py +491 -0
- crackerjack/services/quality/quality_baseline.py +395 -0
- crackerjack/services/quality/quality_baseline_enhanced.py +649 -0
- crackerjack/services/quality/quality_intelligence.py +949 -0
- crackerjack/services/regex_patterns.py +58 -0
- crackerjack/services/regex_utils.py +483 -0
- crackerjack/services/secure_path_utils.py +524 -0
- crackerjack/services/secure_status_formatter.py +450 -0
- crackerjack/services/secure_subprocess.py +635 -0
- crackerjack/services/security.py +239 -0
- crackerjack/services/security_logger.py +495 -0
- crackerjack/services/server_manager.py +411 -0
- crackerjack/services/smart_scheduling.py +167 -0
- crackerjack/services/status_authentication.py +460 -0
- crackerjack/services/status_security_manager.py +315 -0
- crackerjack/services/terminal_utils.py +0 -0
- crackerjack/services/thread_safe_status_collector.py +441 -0
- crackerjack/services/tool_filter.py +368 -0
- crackerjack/services/tool_version_service.py +43 -0
- crackerjack/services/unified_config.py +115 -0
- crackerjack/services/validation_rate_limiter.py +220 -0
- crackerjack/services/vector_store.py +689 -0
- crackerjack/services/version_analyzer.py +461 -0
- crackerjack/services/version_checker.py +223 -0
- crackerjack/services/websocket_resource_limiter.py +438 -0
- crackerjack/services/zuban_lsp_service.py +391 -0
- crackerjack/slash_commands/README.md +11 -0
- crackerjack/slash_commands/__init__.py +59 -0
- crackerjack/slash_commands/init.md +112 -0
- crackerjack/slash_commands/run.md +197 -0
- crackerjack/slash_commands/status.md +127 -0
- crackerjack/tools/README.md +11 -0
- crackerjack/tools/__init__.py +30 -0
- crackerjack/tools/_git_utils.py +105 -0
- crackerjack/tools/check_added_large_files.py +139 -0
- crackerjack/tools/check_ast.py +105 -0
- crackerjack/tools/check_json.py +103 -0
- crackerjack/tools/check_jsonschema.py +297 -0
- crackerjack/tools/check_toml.py +103 -0
- crackerjack/tools/check_yaml.py +110 -0
- crackerjack/tools/codespell_wrapper.py +72 -0
- crackerjack/tools/end_of_file_fixer.py +202 -0
- crackerjack/tools/format_json.py +128 -0
- crackerjack/tools/mdformat_wrapper.py +114 -0
- crackerjack/tools/trailing_whitespace.py +198 -0
- crackerjack/tools/validate_input_validator_patterns.py +236 -0
- crackerjack/tools/validate_regex_patterns.py +188 -0
- crackerjack/ui/README.md +11 -0
- crackerjack/ui/__init__.py +1 -0
- crackerjack/ui/dashboard_renderer.py +28 -0
- crackerjack/ui/templates/README.md +11 -0
- crackerjack/utils/console_utils.py +13 -0
- crackerjack/utils/dependency_guard.py +230 -0
- crackerjack/utils/retry_utils.py +275 -0
- crackerjack/workflows/README.md +590 -0
- crackerjack/workflows/__init__.py +46 -0
- crackerjack/workflows/actions.py +811 -0
- crackerjack/workflows/auto_fix.py +444 -0
- crackerjack/workflows/container_builder.py +499 -0
- crackerjack/workflows/definitions.py +443 -0
- crackerjack/workflows/engine.py +177 -0
- crackerjack/workflows/event_bridge.py +242 -0
- crackerjack-0.45.2.dist-info/METADATA +1678 -0
- crackerjack-0.45.2.dist-info/RECORD +478 -0
- {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
- crackerjack-0.45.2.dist-info/entry_points.txt +2 -0
- crackerjack/.gitignore +0 -14
- crackerjack/.libcst.codemod.yaml +0 -18
- crackerjack/.pdm.toml +0 -1
- crackerjack/.pre-commit-config.yaml +0 -91
- crackerjack/.pytest_cache/.gitignore +0 -2
- crackerjack/.pytest_cache/CACHEDIR.TAG +0 -4
- crackerjack/.pytest_cache/README.md +0 -8
- crackerjack/.pytest_cache/v/cache/nodeids +0 -1
- crackerjack/.pytest_cache/v/cache/stepwise +0 -1
- crackerjack/.ruff_cache/.gitignore +0 -1
- crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
- crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
- crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
- crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
- crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
- crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
- crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
- crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
- crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
- crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
- crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
- crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
- crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
- crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
- crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
- crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
- crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
- crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
- crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
- crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
- crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
- crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
- crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
- crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
- crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
- crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
- crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
- crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
- crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
- crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
- crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
- crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
- crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
- crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
- crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
- crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
- crackerjack/.ruff_cache/CACHEDIR.TAG +0 -1
- crackerjack/crackerjack.py +0 -855
- crackerjack/pyproject.toml +0 -214
- crackerjack-0.18.2.dist-info/METADATA +0 -420
- crackerjack-0.18.2.dist-info/RECORD +0 -59
- crackerjack-0.18.2.dist-info/entry_points.txt +0 -4
- {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,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
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Metrics utilities for the monitoring system.
|
|
2
|
+
|
|
3
|
+
This module contains functions for collecting, processing, and returning
|
|
4
|
+
current system metrics used by the monitoring endpoints.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from crackerjack.services.quality.quality_baseline_enhanced import (
|
|
11
|
+
EnhancedQualityBaselineService,
|
|
12
|
+
UnifiedMetrics,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async def get_monitoring_current_metrics(
|
|
17
|
+
quality_service: EnhancedQualityBaselineService, job_manager: Any
|
|
18
|
+
) -> UnifiedMetrics:
|
|
19
|
+
"""Get current system metrics for monitoring API endpoints.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
quality_service: EnhancedQualityBaselineService with the quality data
|
|
23
|
+
job_manager: Job manager instance to access current job states
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
UnifiedMetrics containing current system metrics
|
|
27
|
+
"""
|
|
28
|
+
# Get current quality metrics from the service
|
|
29
|
+
current_baseline = await quality_service.aget_current_baseline()
|
|
30
|
+
|
|
31
|
+
# Calculate additional metrics
|
|
32
|
+
active_jobs = 0
|
|
33
|
+
error_count = 0
|
|
34
|
+
|
|
35
|
+
# Access job manager to get current status if possible
|
|
36
|
+
try:
|
|
37
|
+
if hasattr(job_manager, "get_active_jobs"):
|
|
38
|
+
active_jobs = len(job_manager.get_active_jobs() or [])
|
|
39
|
+
elif hasattr(job_manager, "active_jobs"):
|
|
40
|
+
active_jobs = len(job_manager.active_jobs or [])
|
|
41
|
+
|
|
42
|
+
if hasattr(job_manager, "get_error_count"):
|
|
43
|
+
error_count = job_manager.get_error_count()
|
|
44
|
+
elif hasattr(job_manager, "error_count"):
|
|
45
|
+
error_count = getattr(job_manager, "error_count", 0)
|
|
46
|
+
except Exception:
|
|
47
|
+
# If we can't access job info, use defaults
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
# Create UnifiedMetrics instance with current data
|
|
51
|
+
metrics = UnifiedMetrics(
|
|
52
|
+
timestamp=datetime.now(),
|
|
53
|
+
quality_score=current_baseline.quality_score if current_baseline else 100,
|
|
54
|
+
test_coverage=current_baseline.coverage_percent if current_baseline else 0.0,
|
|
55
|
+
hook_duration=current_baseline.hook_duration if current_baseline else 0.0,
|
|
56
|
+
active_jobs=active_jobs,
|
|
57
|
+
error_count=error_count,
|
|
58
|
+
trend_direction=current_baseline.trend_direction
|
|
59
|
+
if current_baseline
|
|
60
|
+
else "stable",
|
|
61
|
+
predictions=current_baseline.predictions if current_baseline else {},
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
return metrics
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Pydantic models for monitoring endpoints.
|
|
2
|
+
|
|
3
|
+
This module contains all data models used for request/response validation
|
|
4
|
+
and serialization in the monitoring system.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import typing as t
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
|
|
10
|
+
from pydantic import BaseModel
|
|
11
|
+
|
|
12
|
+
from crackerjack.services.quality.quality_baseline_enhanced import (
|
|
13
|
+
TrendDirection,
|
|
14
|
+
UnifiedMetrics,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TelemetryEventModel(BaseModel):
|
|
19
|
+
event_type: str
|
|
20
|
+
timestamp: datetime
|
|
21
|
+
source: str | None = None
|
|
22
|
+
payload: t.Any = None
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def from_dict(cls, data: dict[str, t.Any]) -> "TelemetryEventModel":
|
|
26
|
+
return cls(
|
|
27
|
+
event_type=data.get("event_type", ""),
|
|
28
|
+
timestamp=datetime.fromisoformat(data.get("timestamp")),
|
|
29
|
+
source=data.get("source"),
|
|
30
|
+
payload=data.get("payload"),
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TelemetrySnapshotModel(BaseModel):
|
|
35
|
+
counts: dict[str, int]
|
|
36
|
+
recent_events: list[TelemetryEventModel]
|
|
37
|
+
last_error: TelemetryEventModel | None = None
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def from_snapshot(cls, snapshot: dict[str, t.Any]) -> "TelemetrySnapshotModel":
|
|
41
|
+
events = [
|
|
42
|
+
TelemetryEventModel.from_dict(event)
|
|
43
|
+
for event in snapshot.get("recent_events", [])
|
|
44
|
+
]
|
|
45
|
+
last_error = snapshot.get("last_error")
|
|
46
|
+
return cls(
|
|
47
|
+
counts=snapshot.get("counts", {}),
|
|
48
|
+
recent_events=events,
|
|
49
|
+
last_error=(
|
|
50
|
+
TelemetryEventModel.from_dict(last_error)
|
|
51
|
+
if last_error is not None
|
|
52
|
+
else None
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class TelemetryResponseModel(BaseModel):
|
|
58
|
+
status: str
|
|
59
|
+
data: TelemetrySnapshotModel
|
|
60
|
+
timestamp: datetime
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class UnifiedMetricsModel(BaseModel):
|
|
64
|
+
timestamp: datetime
|
|
65
|
+
quality_score: int
|
|
66
|
+
test_coverage: float
|
|
67
|
+
hook_duration: float
|
|
68
|
+
active_jobs: int
|
|
69
|
+
error_count: int
|
|
70
|
+
trend_direction: TrendDirection
|
|
71
|
+
predictions: dict[str, t.Any] = {}
|
|
72
|
+
|
|
73
|
+
@classmethod
|
|
74
|
+
def from_domain(cls, metrics: UnifiedMetrics) -> "UnifiedMetricsModel":
|
|
75
|
+
return cls(
|
|
76
|
+
timestamp=metrics.timestamp,
|
|
77
|
+
quality_score=metrics.quality_score,
|
|
78
|
+
test_coverage=metrics.test_coverage,
|
|
79
|
+
hook_duration=metrics.hook_duration,
|
|
80
|
+
active_jobs=metrics.active_jobs,
|
|
81
|
+
error_count=metrics.error_count,
|
|
82
|
+
trend_direction=metrics.trend_direction,
|
|
83
|
+
predictions=metrics.predictions,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class HealthResponseModel(BaseModel):
|
|
88
|
+
status: str
|
|
89
|
+
data: UnifiedMetricsModel
|
|
90
|
+
timestamp: datetime
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""Utility functions for monitoring endpoints.
|
|
2
|
+
|
|
3
|
+
This module contains helper functions for metrics aggregation, health checks,
|
|
4
|
+
and data filtering.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import typing as t
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
|
|
11
|
+
from crackerjack.services.dependency_analyzer import DependencyGraph
|
|
12
|
+
from crackerjack.services.quality.quality_baseline_enhanced import (
|
|
13
|
+
EnhancedQualityBaselineService,
|
|
14
|
+
SystemHealthStatus,
|
|
15
|
+
TrendDirection,
|
|
16
|
+
UnifiedMetrics,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
async def get_current_metrics(
|
|
21
|
+
quality_service: EnhancedQualityBaselineService, job_manager: t.Any
|
|
22
|
+
) -> UnifiedMetrics:
|
|
23
|
+
"""Get current unified metrics."""
|
|
24
|
+
try:
|
|
25
|
+
# Get baseline from quality service
|
|
26
|
+
baseline = await quality_service.aget_baseline()
|
|
27
|
+
if not baseline:
|
|
28
|
+
# Return default metrics if no baseline exists
|
|
29
|
+
return UnifiedMetrics(
|
|
30
|
+
timestamp=datetime.now(),
|
|
31
|
+
quality_score=0,
|
|
32
|
+
test_coverage=0.0,
|
|
33
|
+
hook_duration=0.0,
|
|
34
|
+
active_jobs=len(job_manager.active_connections),
|
|
35
|
+
error_count=0,
|
|
36
|
+
trend_direction=TrendDirection.STABLE,
|
|
37
|
+
predictions={},
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Create metrics dict from baseline
|
|
41
|
+
current_metrics = {
|
|
42
|
+
"coverage_percent": baseline.coverage_percent,
|
|
43
|
+
"test_count": baseline.test_count,
|
|
44
|
+
"test_pass_rate": baseline.test_pass_rate,
|
|
45
|
+
"hook_failures": baseline.hook_failures,
|
|
46
|
+
"complexity_violations": baseline.complexity_violations,
|
|
47
|
+
"security_issues": baseline.security_issues,
|
|
48
|
+
"type_errors": baseline.type_errors,
|
|
49
|
+
"linting_issues": baseline.linting_issues,
|
|
50
|
+
"hook_duration": 0.0, # Would need to be tracked separately
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
unified = await asyncio.to_thread(
|
|
54
|
+
quality_service.create_unified_metrics,
|
|
55
|
+
current_metrics,
|
|
56
|
+
len(job_manager.active_connections)
|
|
57
|
+
if hasattr(job_manager, "active_connections")
|
|
58
|
+
else 0,
|
|
59
|
+
)
|
|
60
|
+
return unified
|
|
61
|
+
except Exception:
|
|
62
|
+
# Fallback to basic metrics if service fails
|
|
63
|
+
return UnifiedMetrics(
|
|
64
|
+
timestamp=datetime.now(),
|
|
65
|
+
quality_score=0,
|
|
66
|
+
test_coverage=0.0,
|
|
67
|
+
hook_duration=0.0,
|
|
68
|
+
active_jobs=len(job_manager.active_connections)
|
|
69
|
+
if hasattr(job_manager, "active_connections")
|
|
70
|
+
else 0,
|
|
71
|
+
error_count=0,
|
|
72
|
+
trend_direction=TrendDirection.STABLE,
|
|
73
|
+
predictions={},
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async def get_system_health_status(
|
|
78
|
+
quality_service: EnhancedQualityBaselineService,
|
|
79
|
+
) -> SystemHealthStatus:
|
|
80
|
+
"""Get system health status."""
|
|
81
|
+
return await asyncio.to_thread(quality_service.get_system_health)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _filter_nodes_by_criteria(
|
|
85
|
+
nodes: list[t.Any], filter_type: str | None, include_external: bool
|
|
86
|
+
) -> list[t.Any]:
|
|
87
|
+
"""Filter nodes by type and external criteria."""
|
|
88
|
+
filtered = nodes
|
|
89
|
+
|
|
90
|
+
# Filter by type if specified
|
|
91
|
+
if filter_type:
|
|
92
|
+
filtered = [node for node in filtered if node.type == filter_type]
|
|
93
|
+
|
|
94
|
+
# Filter external dependencies if not included
|
|
95
|
+
if not include_external:
|
|
96
|
+
filtered = [
|
|
97
|
+
node
|
|
98
|
+
for node in filtered
|
|
99
|
+
if not node.file_path or "site-packages" not in node.file_path
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
return filtered
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _prioritize_and_limit_nodes(
|
|
106
|
+
nodes: list[t.Any], graph: DependencyGraph, max_nodes: int
|
|
107
|
+
) -> list[t.Any]:
|
|
108
|
+
"""Prioritize nodes and limit to max count."""
|
|
109
|
+
if len(nodes) <= max_nodes:
|
|
110
|
+
return nodes
|
|
111
|
+
|
|
112
|
+
def node_priority(node: t.Any) -> int:
|
|
113
|
+
edge_count = sum(
|
|
114
|
+
1 for edge in graph.edges if node.id in (edge.source, edge.target)
|
|
115
|
+
)
|
|
116
|
+
return int(node.complexity * edge_count)
|
|
117
|
+
|
|
118
|
+
nodes.sort(key=node_priority, reverse=True)
|
|
119
|
+
return nodes[:max_nodes]
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _build_filtered_clusters(
|
|
123
|
+
graph: DependencyGraph, node_ids: set[str]
|
|
124
|
+
) -> dict[str, list[str]]:
|
|
125
|
+
"""Build filtered clusters containing only included nodes."""
|
|
126
|
+
filtered_clusters = {}
|
|
127
|
+
for cluster_name, cluster_nodes in graph.clusters.items():
|
|
128
|
+
filtered_cluster_nodes = [
|
|
129
|
+
node_id for node_id in cluster_nodes if node_id in node_ids
|
|
130
|
+
]
|
|
131
|
+
if filtered_cluster_nodes:
|
|
132
|
+
filtered_clusters[cluster_name] = filtered_cluster_nodes
|
|
133
|
+
return filtered_clusters
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
async def _apply_graph_filters(
|
|
137
|
+
graph: DependencyGraph, filters: dict[str, t.Any]
|
|
138
|
+
) -> DependencyGraph:
|
|
139
|
+
"""Apply filters to dependency graph."""
|
|
140
|
+
filtered_graph = DependencyGraph(
|
|
141
|
+
generated_at=graph.generated_at,
|
|
142
|
+
metrics=graph.metrics.copy(),
|
|
143
|
+
clusters=graph.clusters.copy(),
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# Extract filter parameters
|
|
147
|
+
filter_type = filters.get("type")
|
|
148
|
+
max_nodes = filters.get("max_nodes", 1000)
|
|
149
|
+
include_external = filters.get("include_external", False)
|
|
150
|
+
|
|
151
|
+
# Apply filters to nodes
|
|
152
|
+
candidate_nodes = list(graph.nodes.values())
|
|
153
|
+
candidate_nodes = _filter_nodes_by_criteria(
|
|
154
|
+
candidate_nodes, filter_type, include_external
|
|
155
|
+
)
|
|
156
|
+
candidate_nodes = _prioritize_and_limit_nodes(candidate_nodes, graph, max_nodes)
|
|
157
|
+
|
|
158
|
+
# Build filtered graph
|
|
159
|
+
node_ids = {node.id for node in candidate_nodes}
|
|
160
|
+
for node in candidate_nodes:
|
|
161
|
+
filtered_graph.nodes[node.id] = node
|
|
162
|
+
|
|
163
|
+
# Add edges between filtered nodes
|
|
164
|
+
for edge in graph.edges:
|
|
165
|
+
if edge.source in node_ids and edge.target in node_ids:
|
|
166
|
+
filtered_graph.edges.append(edge)
|
|
167
|
+
|
|
168
|
+
# Update clusters
|
|
169
|
+
filtered_graph.clusters = _build_filtered_clusters(graph, node_ids)
|
|
170
|
+
|
|
171
|
+
return filtered_graph
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""WebSocket connection manager for real-time monitoring.
|
|
2
|
+
|
|
3
|
+
This module manages WebSocket connections for metrics streaming and alert notifications.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
|
|
9
|
+
from fastapi import WebSocket
|
|
10
|
+
|
|
11
|
+
from crackerjack.services.quality.quality_baseline_enhanced import (
|
|
12
|
+
QualityAlert,
|
|
13
|
+
UnifiedMetrics,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MonitoringWebSocketManager:
|
|
18
|
+
"""Manages WebSocket connections for real-time monitoring."""
|
|
19
|
+
|
|
20
|
+
def __init__(self) -> None:
|
|
21
|
+
self.active_connections: dict[str, WebSocket] = {}
|
|
22
|
+
self.metrics_subscribers: set[WebSocket] = set()
|
|
23
|
+
self.alerts_subscribers: set[WebSocket] = set()
|
|
24
|
+
|
|
25
|
+
async def connect_metrics(self, websocket: WebSocket, client_id: str) -> None:
|
|
26
|
+
"""Connect a client for metrics streaming."""
|
|
27
|
+
await websocket.accept()
|
|
28
|
+
self.active_connections[client_id] = websocket
|
|
29
|
+
self.metrics_subscribers.add(websocket)
|
|
30
|
+
|
|
31
|
+
async def connect_alerts(self, websocket: WebSocket, client_id: str) -> None:
|
|
32
|
+
"""Connect a client for alert notifications."""
|
|
33
|
+
await websocket.accept()
|
|
34
|
+
self.active_connections[client_id] = websocket
|
|
35
|
+
self.alerts_subscribers.add(websocket)
|
|
36
|
+
|
|
37
|
+
def disconnect(self, websocket: WebSocket, client_id: str) -> None:
|
|
38
|
+
"""Disconnect a client."""
|
|
39
|
+
if client_id in self.active_connections:
|
|
40
|
+
del self.active_connections[client_id]
|
|
41
|
+
self.metrics_subscribers.discard(websocket)
|
|
42
|
+
self.alerts_subscribers.discard(websocket)
|
|
43
|
+
|
|
44
|
+
async def broadcast_metrics(self, metrics: UnifiedMetrics) -> None:
|
|
45
|
+
"""Broadcast metrics to all connected metrics subscribers."""
|
|
46
|
+
message = {
|
|
47
|
+
"type": "metrics_update",
|
|
48
|
+
"data": metrics.to_dict(),
|
|
49
|
+
"timestamp": datetime.now().isoformat(),
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
disconnected = []
|
|
53
|
+
for websocket in self.metrics_subscribers:
|
|
54
|
+
try:
|
|
55
|
+
await websocket.send_text(json.dumps(message))
|
|
56
|
+
except Exception:
|
|
57
|
+
disconnected.append(websocket)
|
|
58
|
+
|
|
59
|
+
# Clean up disconnected clients
|
|
60
|
+
self.metrics_subscribers.difference_update(disconnected)
|
|
61
|
+
|
|
62
|
+
async def broadcast_alert(self, alert: QualityAlert) -> None:
|
|
63
|
+
"""Broadcast alert to all connected alert subscribers."""
|
|
64
|
+
message = {
|
|
65
|
+
"type": "alert",
|
|
66
|
+
"data": alert.to_dict(),
|
|
67
|
+
"timestamp": datetime.now().isoformat(),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
disconnected = []
|
|
71
|
+
for websocket in self.alerts_subscribers:
|
|
72
|
+
try:
|
|
73
|
+
await websocket.send_text(json.dumps(message))
|
|
74
|
+
except Exception:
|
|
75
|
+
disconnected.append(websocket)
|
|
76
|
+
|
|
77
|
+
# Clean up disconnected clients
|
|
78
|
+
self.alerts_subscribers.difference_update(disconnected)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""WebSocket endpoint registration.
|
|
2
|
+
|
|
3
|
+
This module provides registration functions for all WebSocket endpoints
|
|
4
|
+
including metrics, intelligence, dependencies, and heatmap streaming.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .dependencies import register_dependency_websockets
|
|
8
|
+
from .heatmap import register_heatmap_websockets
|
|
9
|
+
from .intelligence import register_intelligence_websockets
|
|
10
|
+
from .metrics import register_metrics_websockets
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"register_metrics_websockets",
|
|
14
|
+
"register_intelligence_websockets",
|
|
15
|
+
"register_dependency_websockets",
|
|
16
|
+
"register_heatmap_websockets",
|
|
17
|
+
]
|