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,280 @@
|
|
|
1
|
+
"""Performance profiling for tool execution.
|
|
2
|
+
|
|
3
|
+
Phase 10.3.1: Provides baseline metrics and bottleneck identification for optimization.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import time
|
|
7
|
+
from collections.abc import Callable
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from statistics import mean, median, stdev
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
import psutil
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class ProfileResult:
|
|
18
|
+
"""Results from profiling a single tool."""
|
|
19
|
+
|
|
20
|
+
tool_name: str
|
|
21
|
+
runs: int
|
|
22
|
+
execution_times: list[float] = field(default_factory=list)
|
|
23
|
+
memory_usage: list[float] = field(default_factory=list)
|
|
24
|
+
cache_hits: int = 0
|
|
25
|
+
cache_misses: int = 0
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def mean_time(self) -> float:
|
|
29
|
+
"""Average execution time."""
|
|
30
|
+
return mean(self.execution_times) if self.execution_times else 0.0
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def median_time(self) -> float:
|
|
34
|
+
"""Median execution time."""
|
|
35
|
+
return median(self.execution_times) if self.execution_times else 0.0
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def std_dev_time(self) -> float:
|
|
39
|
+
"""Standard deviation of execution times."""
|
|
40
|
+
return stdev(self.execution_times) if len(self.execution_times) > 1 else 0.0
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def mean_memory(self) -> float:
|
|
44
|
+
"""Average memory usage in MB."""
|
|
45
|
+
return mean(self.memory_usage) if self.memory_usage else 0.0
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def cache_hit_rate(self) -> float:
|
|
49
|
+
"""Cache hit rate as percentage."""
|
|
50
|
+
total = self.cache_hits + self.cache_misses
|
|
51
|
+
return (self.cache_hits / total * 100) if total > 0 else 0.0
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@dataclass
|
|
55
|
+
class Bottleneck:
|
|
56
|
+
"""Identified performance bottleneck."""
|
|
57
|
+
|
|
58
|
+
tool_name: str
|
|
59
|
+
metric_type: str # 'time', 'memory', 'cache'
|
|
60
|
+
severity: str # 'high', 'medium', 'low'
|
|
61
|
+
value: float
|
|
62
|
+
threshold: float
|
|
63
|
+
recommendation: str
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclass
|
|
67
|
+
class ComparisonReport:
|
|
68
|
+
"""Comparison between fast and comprehensive hook phases."""
|
|
69
|
+
|
|
70
|
+
fast_phase_time: float
|
|
71
|
+
comprehensive_phase_time: float
|
|
72
|
+
total_time: float
|
|
73
|
+
tools_profiled: int
|
|
74
|
+
bottlenecks: list[Bottleneck] = field(default_factory=list)
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def time_ratio(self) -> float:
|
|
78
|
+
"""Ratio of comprehensive to fast phase time."""
|
|
79
|
+
return (
|
|
80
|
+
self.comprehensive_phase_time / self.fast_phase_time
|
|
81
|
+
if self.fast_phase_time > 0
|
|
82
|
+
else 0.0
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class ToolProfiler:
|
|
87
|
+
"""Profiles tool execution for performance optimization."""
|
|
88
|
+
|
|
89
|
+
def __init__(self, cache_dir: Path | None = None):
|
|
90
|
+
"""Initialize profiler.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
cache_dir: Directory for cache statistics tracking
|
|
94
|
+
"""
|
|
95
|
+
self.cache_dir = cache_dir or Path.cwd() / ".crackerjack" / "cache"
|
|
96
|
+
self.results: dict[str, ProfileResult] = {}
|
|
97
|
+
|
|
98
|
+
def profile_tool(
|
|
99
|
+
self,
|
|
100
|
+
tool_name: str,
|
|
101
|
+
tool_func: Callable[[], Any],
|
|
102
|
+
runs: int = 10,
|
|
103
|
+
) -> ProfileResult:
|
|
104
|
+
"""Profile a tool's execution performance.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
tool_name: Name of the tool being profiled
|
|
108
|
+
tool_func: Function to execute and profile
|
|
109
|
+
runs: Number of profiling runs (default: 10)
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
ProfileResult with timing and memory statistics
|
|
113
|
+
"""
|
|
114
|
+
result = ProfileResult(tool_name=tool_name, runs=runs)
|
|
115
|
+
process = psutil.Process()
|
|
116
|
+
|
|
117
|
+
for _ in range(runs):
|
|
118
|
+
# Memory before execution
|
|
119
|
+
mem_before = process.memory_info().rss / 1024 / 1024 # MB
|
|
120
|
+
|
|
121
|
+
# Time execution
|
|
122
|
+
start_time = time.perf_counter()
|
|
123
|
+
tool_func()
|
|
124
|
+
end_time = time.perf_counter()
|
|
125
|
+
|
|
126
|
+
# Memory after execution
|
|
127
|
+
mem_after = process.memory_info().rss / 1024 / 1024 # MB
|
|
128
|
+
|
|
129
|
+
# Record metrics
|
|
130
|
+
result.execution_times.append(end_time - start_time)
|
|
131
|
+
result.memory_usage.append(mem_after - mem_before)
|
|
132
|
+
|
|
133
|
+
# Store result
|
|
134
|
+
self.results[tool_name] = result
|
|
135
|
+
return result
|
|
136
|
+
|
|
137
|
+
def compare_phases(self) -> ComparisonReport:
|
|
138
|
+
"""Compare fast vs comprehensive hook phase performance.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
ComparisonReport with phase timing comparison
|
|
142
|
+
"""
|
|
143
|
+
fast_tools = ["ruff-format", "ruff-isort"]
|
|
144
|
+
comp_tools = ["zuban", "bandit", "complexipy"]
|
|
145
|
+
|
|
146
|
+
fast_time = sum(
|
|
147
|
+
self.results[t].mean_time for t in fast_tools if t in self.results
|
|
148
|
+
)
|
|
149
|
+
comp_time = sum(
|
|
150
|
+
self.results[t].mean_time for t in comp_tools if t in self.results
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
report = ComparisonReport(
|
|
154
|
+
fast_phase_time=fast_time,
|
|
155
|
+
comprehensive_phase_time=comp_time,
|
|
156
|
+
total_time=fast_time + comp_time,
|
|
157
|
+
tools_profiled=len(self.results),
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Identify bottlenecks
|
|
161
|
+
report.bottlenecks = self.identify_bottlenecks()
|
|
162
|
+
|
|
163
|
+
return report
|
|
164
|
+
|
|
165
|
+
def identify_bottlenecks(self) -> list[Bottleneck]:
|
|
166
|
+
"""Identify performance bottlenecks across all profiled tools.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
List of identified bottlenecks ordered by severity
|
|
170
|
+
"""
|
|
171
|
+
bottlenecks: list[Bottleneck] = []
|
|
172
|
+
|
|
173
|
+
for tool_name, result in self.results.items():
|
|
174
|
+
# Time bottlenecks (>2s mean time)
|
|
175
|
+
if result.mean_time > 2.0:
|
|
176
|
+
severity = "high" if result.mean_time > 5.0 else "medium"
|
|
177
|
+
bottlenecks.append(
|
|
178
|
+
Bottleneck(
|
|
179
|
+
tool_name=tool_name,
|
|
180
|
+
metric_type="time",
|
|
181
|
+
severity=severity,
|
|
182
|
+
value=result.mean_time,
|
|
183
|
+
threshold=2.0,
|
|
184
|
+
recommendation=(
|
|
185
|
+
"Consider incremental execution or caching strategy"
|
|
186
|
+
),
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Memory bottlenecks (>100MB mean usage)
|
|
191
|
+
if result.mean_memory > 100.0:
|
|
192
|
+
severity = "high" if result.mean_memory > 500.0 else "medium"
|
|
193
|
+
bottlenecks.append(
|
|
194
|
+
Bottleneck(
|
|
195
|
+
tool_name=tool_name,
|
|
196
|
+
metric_type="memory",
|
|
197
|
+
severity=severity,
|
|
198
|
+
value=result.mean_memory,
|
|
199
|
+
threshold=100.0,
|
|
200
|
+
recommendation="Optimize memory usage or implement streaming",
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# Cache bottlenecks (<50% hit rate with >10 requests)
|
|
205
|
+
total_requests = result.cache_hits + result.cache_misses
|
|
206
|
+
if total_requests > 10 and result.cache_hit_rate < 50.0:
|
|
207
|
+
bottlenecks.append(
|
|
208
|
+
Bottleneck(
|
|
209
|
+
tool_name=tool_name,
|
|
210
|
+
metric_type="cache",
|
|
211
|
+
severity="medium",
|
|
212
|
+
value=result.cache_hit_rate,
|
|
213
|
+
threshold=50.0,
|
|
214
|
+
recommendation="Improve cache strategy or increase cache TTL",
|
|
215
|
+
)
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# Sort by severity (high -> medium -> low)
|
|
219
|
+
severity_order = {"high": 0, "medium": 1, "low": 2}
|
|
220
|
+
bottlenecks.sort(key=lambda b: severity_order[b.severity])
|
|
221
|
+
|
|
222
|
+
return bottlenecks
|
|
223
|
+
|
|
224
|
+
def generate_report(self) -> str:
|
|
225
|
+
"""Generate formatted performance report.
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
Formatted report string with all profiling results
|
|
229
|
+
"""
|
|
230
|
+
lines = ["# Performance Profile Report", ""]
|
|
231
|
+
|
|
232
|
+
# Summary statistics
|
|
233
|
+
if self.results:
|
|
234
|
+
total_tools = len(self.results)
|
|
235
|
+
total_time = sum(r.mean_time for r in self.results.values())
|
|
236
|
+
total_memory = sum(r.mean_memory for r in self.results.values())
|
|
237
|
+
|
|
238
|
+
lines.extend(
|
|
239
|
+
[
|
|
240
|
+
"## Summary",
|
|
241
|
+
f"- Tools Profiled: {total_tools}",
|
|
242
|
+
f"- Total Mean Time: {total_time:.2f}s",
|
|
243
|
+
f"- Total Mean Memory: {total_memory:.2f}MB",
|
|
244
|
+
"",
|
|
245
|
+
]
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
# Individual tool results
|
|
249
|
+
lines.append("## Tool Performance")
|
|
250
|
+
for tool_name, result in sorted(self.results.items()):
|
|
251
|
+
lines.extend(
|
|
252
|
+
[
|
|
253
|
+
f"### {tool_name}",
|
|
254
|
+
f"- Runs: {result.runs}",
|
|
255
|
+
f"- Mean Time: {result.mean_time:.3f}s",
|
|
256
|
+
f"- Median Time: {result.median_time:.3f}s",
|
|
257
|
+
f"- Std Dev: {result.std_dev_time:.3f}s",
|
|
258
|
+
f"- Mean Memory: {result.mean_memory:.2f}MB",
|
|
259
|
+
f"- Cache Hit Rate: {result.cache_hit_rate:.1f}%",
|
|
260
|
+
"",
|
|
261
|
+
]
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
# Bottlenecks
|
|
265
|
+
bottlenecks = self.identify_bottlenecks()
|
|
266
|
+
if bottlenecks:
|
|
267
|
+
lines.extend(["## Identified Bottlenecks", ""])
|
|
268
|
+
for bottleneck in bottlenecks:
|
|
269
|
+
lines.extend(
|
|
270
|
+
[
|
|
271
|
+
f"### {bottleneck.tool_name} ({bottleneck.severity.upper()})",
|
|
272
|
+
f"- Type: {bottleneck.metric_type}",
|
|
273
|
+
f"- Value: {bottleneck.value:.2f}",
|
|
274
|
+
f"- Threshold: {bottleneck.threshold:.2f}",
|
|
275
|
+
f"- Recommendation: {bottleneck.recommendation}",
|
|
276
|
+
"",
|
|
277
|
+
]
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
return "\n".join(lines)
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
> Crackerjack Docs: [Main](<../../../README.md>) | [CLAUDE.md](../../../docs/guides/CLAUDE.md) | [Services](<../README.md>) | Quality Services
|
|
2
|
+
|
|
3
|
+
# Quality Services
|
|
4
|
+
|
|
5
|
+
Quality baseline management, pattern detection, and anomaly detection services.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The quality services package provides intelligent quality monitoring, baseline tracking, and pattern detection capabilities. These services power crackerjack's coverage ratchet system, detect code quality degradation, and orchestrate quality checks across multiple tools.
|
|
10
|
+
|
|
11
|
+
## Services
|
|
12
|
+
|
|
13
|
+
- **`quality_baseline_enhanced.py`** - Quality baseline tracking and trend analysis
|
|
14
|
+
- **`pattern_detector.py`** - Code and error pattern detection
|
|
15
|
+
- **`pattern_cache.py`** - Pattern caching for improved performance
|
|
16
|
+
- **`anomaly_detector.py`** - Quality anomaly detection and alerting
|
|
17
|
+
- **`qa_orchestrator.py`** - Quality assurance workflow orchestration
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
### Baseline Tracking
|
|
22
|
+
|
|
23
|
+
Monitor quality metrics over time with ratchet enforcement:
|
|
24
|
+
|
|
25
|
+
- **Coverage Tracking** - Track test coverage with never-decrease policy
|
|
26
|
+
- **Metric History** - Historical trend analysis for all quality metrics
|
|
27
|
+
- **Baseline Enforcement** - Prevent quality degradation
|
|
28
|
+
- **Automatic Updates** - Auto-update baselines on improvement
|
|
29
|
+
- **Trend Visualization** - Visual trend reporting
|
|
30
|
+
|
|
31
|
+
### Pattern Recognition
|
|
32
|
+
|
|
33
|
+
Detect code smells and anti-patterns:
|
|
34
|
+
|
|
35
|
+
- **Code Pattern Detection** - Identifies common anti-patterns
|
|
36
|
+
- **Error Pattern Analysis** - Categorizes and learns from errors
|
|
37
|
+
- **Duplicate Detection** - Finds code duplication
|
|
38
|
+
- **Complexity Patterns** - Identifies high-complexity patterns
|
|
39
|
+
- **Security Patterns** - Detects security anti-patterns
|
|
40
|
+
|
|
41
|
+
### Anomaly Detection
|
|
42
|
+
|
|
43
|
+
Identify unusual quality degradation:
|
|
44
|
+
|
|
45
|
+
- **Statistical Analysis** - Detects outliers in quality metrics
|
|
46
|
+
- **Threshold Monitoring** - Alerts on threshold violations
|
|
47
|
+
- **Trend Analysis** - Identifies negative trends early
|
|
48
|
+
- **Alerting** - Configurable alert mechanisms
|
|
49
|
+
- **Root Cause Analysis** - Helps identify degradation causes
|
|
50
|
+
|
|
51
|
+
### Performance Caching
|
|
52
|
+
|
|
53
|
+
Improve performance with intelligent pattern caching:
|
|
54
|
+
|
|
55
|
+
- **Pattern Cache** - Caches detected patterns for reuse
|
|
56
|
+
- **TTL Management** - Time-to-live based cache invalidation
|
|
57
|
+
- **Hit Rate Tracking** - Monitors cache effectiveness
|
|
58
|
+
- **Selective Caching** - Caches only high-value patterns
|
|
59
|
+
- **Memory Efficient** - LRU eviction for large projects
|
|
60
|
+
|
|
61
|
+
### QA Orchestration
|
|
62
|
+
|
|
63
|
+
Coordinate quality checks across tools:
|
|
64
|
+
|
|
65
|
+
- **Multi-Tool Coordination** - Orchestrates Ruff, pytest, mypy, etc.
|
|
66
|
+
- **Parallel Execution** - Runs compatible checks in parallel
|
|
67
|
+
- **Dependency Management** - Respects tool dependencies
|
|
68
|
+
- **Result Aggregation** - Combines results from all tools
|
|
69
|
+
- **Retry Logic** - Smart retry for transient failures
|
|
70
|
+
|
|
71
|
+
## Usage Examples
|
|
72
|
+
|
|
73
|
+
### Quality Baseline Tracking
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from crackerjack.services.quality import QualityBaselineEnhanced
|
|
77
|
+
from acb.depends import depends
|
|
78
|
+
|
|
79
|
+
baseline = depends.get(QualityBaselineEnhanced)
|
|
80
|
+
|
|
81
|
+
# Record current metrics
|
|
82
|
+
await baseline.record_metrics(
|
|
83
|
+
{"coverage": 21.6, "complexity": 8.2, "lint_issues": 0, "security_issues": 0}
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Check if current metrics meet baseline
|
|
87
|
+
results = await baseline.validate_metrics(
|
|
88
|
+
{
|
|
89
|
+
"coverage": 22.1, # Improved!
|
|
90
|
+
"complexity": 8.2,
|
|
91
|
+
"lint_issues": 0,
|
|
92
|
+
"security_issues": 0,
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
if results.all_passed:
|
|
97
|
+
print("✅ All quality metrics improved or maintained")
|
|
98
|
+
# Update baseline with new improved values
|
|
99
|
+
await baseline.update_baseline()
|
|
100
|
+
else:
|
|
101
|
+
print("❌ Quality regression detected:")
|
|
102
|
+
for metric, result in results.items():
|
|
103
|
+
if not result.passed:
|
|
104
|
+
print(f" {metric}: {result.current} < {result.baseline}")
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Pattern Detection
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from crackerjack.services.quality import PatternDetector
|
|
111
|
+
from pathlib import Path
|
|
112
|
+
from acb.depends import depends
|
|
113
|
+
|
|
114
|
+
detector = depends.get(PatternDetector)
|
|
115
|
+
|
|
116
|
+
# Detect patterns in code file
|
|
117
|
+
patterns = await detector.detect_patterns(
|
|
118
|
+
file_path=Path("src/main.py"),
|
|
119
|
+
pattern_types=["complexity", "duplication", "security"],
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
for pattern in patterns:
|
|
123
|
+
print(f"Pattern: {pattern.type}")
|
|
124
|
+
print(f" Location: {pattern.file}:{pattern.line}")
|
|
125
|
+
print(f" Severity: {pattern.severity}")
|
|
126
|
+
print(f" Message: {pattern.message}")
|
|
127
|
+
if pattern.suggestion:
|
|
128
|
+
print(f" Suggestion: {pattern.suggestion}")
|
|
129
|
+
|
|
130
|
+
# Detect error patterns from test output
|
|
131
|
+
error_patterns = await detector.detect_error_patterns(error_output=test_failure_output)
|
|
132
|
+
|
|
133
|
+
for error in error_patterns:
|
|
134
|
+
print(f"Error Category: {error.category}")
|
|
135
|
+
print(f" Pattern: {error.pattern}")
|
|
136
|
+
print(f" Occurrences: {error.count}")
|
|
137
|
+
print(f" Files: {', '.join(error.files)}")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Anomaly Detection
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from crackerjack.services.quality import AnomalyDetector
|
|
144
|
+
from acb.depends import depends
|
|
145
|
+
|
|
146
|
+
detector = depends.get(AnomalyDetector)
|
|
147
|
+
|
|
148
|
+
# Configure thresholds
|
|
149
|
+
detector.configure_thresholds(
|
|
150
|
+
{
|
|
151
|
+
"coverage": {"min": 19.6, "warning": 20.0},
|
|
152
|
+
"complexity": {"max": 15, "warning": 12},
|
|
153
|
+
"test_duration": {"max": 300, "warning": 240},
|
|
154
|
+
}
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# Check for anomalies
|
|
158
|
+
anomalies = await detector.detect_anomalies(
|
|
159
|
+
{
|
|
160
|
+
"coverage": 18.5, # Below minimum!
|
|
161
|
+
"complexity": 14,
|
|
162
|
+
"test_duration": 285,
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
if anomalies:
|
|
167
|
+
print("⚠️ Anomalies detected:")
|
|
168
|
+
for anomaly in anomalies:
|
|
169
|
+
print(f" {anomaly.metric}: {anomaly.value}")
|
|
170
|
+
print(f" Severity: {anomaly.severity}")
|
|
171
|
+
print(f" Threshold: {anomaly.threshold}")
|
|
172
|
+
print(f" Recommendation: {anomaly.recommendation}")
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Pattern Caching
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from crackerjack.services.quality import PatternCache
|
|
179
|
+
from acb.depends import depends
|
|
180
|
+
|
|
181
|
+
cache = depends.get(PatternCache)
|
|
182
|
+
|
|
183
|
+
# Cache detected patterns
|
|
184
|
+
cache_key = "src/main.py:complexity"
|
|
185
|
+
patterns = await detect_complexity_patterns("src/main.py")
|
|
186
|
+
await cache.set(cache_key, patterns, ttl=3600)
|
|
187
|
+
|
|
188
|
+
# Retrieve cached patterns
|
|
189
|
+
cached_patterns = await cache.get(cache_key)
|
|
190
|
+
if cached_patterns:
|
|
191
|
+
print(f"✅ Cache hit! Found {len(cached_patterns)} patterns")
|
|
192
|
+
else:
|
|
193
|
+
print("❌ Cache miss - analyzing file...")
|
|
194
|
+
patterns = await detect_complexity_patterns("src/main.py")
|
|
195
|
+
|
|
196
|
+
# Monitor cache performance
|
|
197
|
+
stats = await cache.get_stats()
|
|
198
|
+
print(f"Cache hit rate: {stats.hit_rate:.1%}")
|
|
199
|
+
print(f"Total hits: {stats.hits}")
|
|
200
|
+
print(f"Total misses: {stats.misses}")
|
|
201
|
+
print(f"Cache size: {stats.size} entries")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### QA Orchestration
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
from crackerjack.services.quality import QAOrchestrator
|
|
208
|
+
from acb.depends import depends
|
|
209
|
+
|
|
210
|
+
orchestrator = depends.get(QAOrchestrator)
|
|
211
|
+
|
|
212
|
+
# Configure quality checks
|
|
213
|
+
orchestrator.configure(
|
|
214
|
+
{
|
|
215
|
+
"tools": ["ruff", "pytest", "mypy", "bandit"],
|
|
216
|
+
"parallel": True,
|
|
217
|
+
"fail_fast": False, # Run all checks even if one fails
|
|
218
|
+
"retry_attempts": 1,
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
# Run orchestrated quality checks
|
|
223
|
+
results = await orchestrator.run_qa_workflow()
|
|
224
|
+
|
|
225
|
+
print(f"Overall Status: {results.status}")
|
|
226
|
+
print(f"Duration: {results.duration:.1f}s")
|
|
227
|
+
print(f"Tools Run: {len(results.tool_results)}")
|
|
228
|
+
|
|
229
|
+
for tool_result in results.tool_results:
|
|
230
|
+
status_icon = "✅" if tool_result.passed else "❌"
|
|
231
|
+
print(f"{status_icon} {tool_result.tool}: {tool_result.message}")
|
|
232
|
+
if not tool_result.passed and tool_result.details:
|
|
233
|
+
print(f" Details: {tool_result.details}")
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Configuration
|
|
237
|
+
|
|
238
|
+
Quality services are configured through ACB Settings:
|
|
239
|
+
|
|
240
|
+
```yaml
|
|
241
|
+
# settings/crackerjack.yaml
|
|
242
|
+
|
|
243
|
+
# Baseline tracking
|
|
244
|
+
quality_baseline_file: ".crackerjack/quality_baseline.json"
|
|
245
|
+
coverage_ratchet_enabled: true
|
|
246
|
+
coverage_baseline: 19.6
|
|
247
|
+
|
|
248
|
+
# Pattern detection
|
|
249
|
+
pattern_detection_enabled: true
|
|
250
|
+
pattern_cache_ttl: 3600
|
|
251
|
+
pattern_types:
|
|
252
|
+
- complexity
|
|
253
|
+
- duplication
|
|
254
|
+
- security
|
|
255
|
+
- performance
|
|
256
|
+
|
|
257
|
+
# Anomaly detection
|
|
258
|
+
anomaly_detection_enabled: true
|
|
259
|
+
anomaly_thresholds:
|
|
260
|
+
coverage_drop_threshold: 0.5 # Alert if coverage drops >0.5%
|
|
261
|
+
complexity_increase_threshold: 2 # Alert if avg complexity increases >2
|
|
262
|
+
test_duration_increase: 1.2 # Alert if tests take 20% longer
|
|
263
|
+
|
|
264
|
+
# QA orchestration
|
|
265
|
+
parallel_qa_checks: true
|
|
266
|
+
max_parallel_tools: 4
|
|
267
|
+
qa_retry_attempts: 1
|
|
268
|
+
qa_timeout_seconds: 600
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Local Configuration Overrides
|
|
272
|
+
|
|
273
|
+
```yaml
|
|
274
|
+
# settings/local.yaml (gitignored)
|
|
275
|
+
quality_baseline_file: ".crackerjack/quality_baseline_dev.json"
|
|
276
|
+
anomaly_detection_enabled: false # Disable for local development
|
|
277
|
+
parallel_qa_checks: true
|
|
278
|
+
max_parallel_tools: 8 # More parallel tools on dev machine
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Integration Examples
|
|
282
|
+
|
|
283
|
+
### Coverage Ratchet Integration
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
from crackerjack.services.quality import QualityBaselineEnhanced
|
|
287
|
+
from crackerjack.services.coverage_ratchet import CoverageRatchet
|
|
288
|
+
from acb.depends import depends
|
|
289
|
+
|
|
290
|
+
baseline = depends.get(QualityBaselineEnhanced)
|
|
291
|
+
ratchet = depends.get(CoverageRatchet)
|
|
292
|
+
|
|
293
|
+
# After test run
|
|
294
|
+
current_coverage = await get_current_coverage()
|
|
295
|
+
baseline_coverage = await baseline.get_baseline("coverage")
|
|
296
|
+
|
|
297
|
+
if ratchet.validate_coverage(current_coverage, baseline_coverage):
|
|
298
|
+
print(f"✅ Coverage {current_coverage:.1%} meets baseline {baseline_coverage:.1%}")
|
|
299
|
+
await baseline.update_baseline({"coverage": current_coverage})
|
|
300
|
+
else:
|
|
301
|
+
print(f"❌ Coverage {current_coverage:.1%} below baseline {baseline_coverage:.1%}")
|
|
302
|
+
raise CoverageRegressionError(
|
|
303
|
+
f"Coverage dropped from {baseline_coverage:.1%} to {current_coverage:.1%}"
|
|
304
|
+
)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### AI Agent Integration
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
from crackerjack.services.quality import PatternDetector
|
|
311
|
+
from crackerjack.intelligence import AgentOrchestrator
|
|
312
|
+
from acb.depends import depends
|
|
313
|
+
|
|
314
|
+
detector = depends.get(PatternDetector)
|
|
315
|
+
orchestrator = depends.get(AgentOrchestrator)
|
|
316
|
+
|
|
317
|
+
# Detect patterns
|
|
318
|
+
patterns = await detector.detect_patterns("src/complex_module.py")
|
|
319
|
+
|
|
320
|
+
# Feed patterns to appropriate agents
|
|
321
|
+
for pattern in patterns:
|
|
322
|
+
if pattern.type == "complexity":
|
|
323
|
+
# Route to RefactoringAgent
|
|
324
|
+
await orchestrator.execute_agent(
|
|
325
|
+
agent_type="refactoring", context={"patterns": [pattern]}
|
|
326
|
+
)
|
|
327
|
+
elif pattern.type == "security":
|
|
328
|
+
# Route to SecurityAgent
|
|
329
|
+
await orchestrator.execute_agent(
|
|
330
|
+
agent_type="security", context={"patterns": [pattern]}
|
|
331
|
+
)
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Workflow Integration
|
|
335
|
+
|
|
336
|
+
```python
|
|
337
|
+
from crackerjack.services.quality import QAOrchestrator
|
|
338
|
+
from crackerjack.workflows import CrackerjackWorkflowEngine
|
|
339
|
+
from acb.depends import depends
|
|
340
|
+
|
|
341
|
+
orchestrator = depends.get(QAOrchestrator)
|
|
342
|
+
engine = depends.get(CrackerjackWorkflowEngine)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
# Register QA orchestrator as workflow action
|
|
346
|
+
@engine.register_action("run_quality_checks")
|
|
347
|
+
async def run_quality_checks(context):
|
|
348
|
+
results = await orchestrator.run_qa_workflow()
|
|
349
|
+
return {"success": results.status == "passed", "results": results.tool_results}
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
# Quality checks now integrated into workflows
|
|
353
|
+
workflow_result = await engine.execute_workflow("STANDARD_WORKFLOW")
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Best Practices
|
|
357
|
+
|
|
358
|
+
1. **Enable Ratcheting** - Always use coverage ratchet to prevent degradation
|
|
359
|
+
1. **Cache Aggressively** - Enable pattern caching for large projects
|
|
360
|
+
1. **Set Appropriate Baselines** - Start with achievable baselines, improve incrementally
|
|
361
|
+
1. **Monitor Trends** - Review quality trends regularly, not just current values
|
|
362
|
+
1. **Configure Thresholds** - Set anomaly thresholds based on project needs
|
|
363
|
+
1. **Use Orchestration** - Leverage QA orchestrator for consistent quality checks
|
|
364
|
+
1. **Parallel When Possible** - Enable parallel execution to speed up checks
|
|
365
|
+
1. **Review Patterns** - Regularly review detected patterns for false positives
|
|
366
|
+
1. **Integrate with CI/CD** - Run quality checks in CI/CD pipeline
|
|
367
|
+
1. **Document Baselines** - Keep quality baseline changes in version control
|
|
368
|
+
|
|
369
|
+
## Performance Considerations
|
|
370
|
+
|
|
371
|
+
### Caching Strategy
|
|
372
|
+
|
|
373
|
+
- **Pattern Cache**: Cache pattern detection results (default TTL: 1 hour)
|
|
374
|
+
- **Baseline Cache**: Cache baseline data in memory (refresh on update)
|
|
375
|
+
- **Result Cache**: Cache tool execution results for unchanged files
|
|
376
|
+
|
|
377
|
+
### Parallel Execution
|
|
378
|
+
|
|
379
|
+
Quality checks run in parallel when possible:
|
|
380
|
+
|
|
381
|
+
```python
|
|
382
|
+
# These can run in parallel (no dependencies)
|
|
383
|
+
parallel_tools = ["ruff", "bandit", "complexity_check"]
|
|
384
|
+
|
|
385
|
+
# These must run sequentially
|
|
386
|
+
sequential_tools = ["tests", "coverage_report"]
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Memory Optimization
|
|
390
|
+
|
|
391
|
+
For large projects:
|
|
392
|
+
|
|
393
|
+
```yaml
|
|
394
|
+
# settings/crackerjack.yaml
|
|
395
|
+
pattern_cache_max_size: 1000 # Limit cache size
|
|
396
|
+
pattern_cache_eviction: "lru" # Use LRU eviction
|
|
397
|
+
quality_history_max_entries: 100 # Limit history size
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## Related
|
|
401
|
+
|
|
402
|
+
- [Services](<../README.md>) - Parent services documentation
|
|
403
|
+
- [AI Services](<../ai/README.md>) - AI-powered quality analysis
|
|
404
|
+
- [Workflows](<../../workflows/README.md>) - Quality workflow integration
|
|
405
|
+
- [COVERAGE_POLICY.md](<../../../docs/reference/COVERAGE_POLICY.md>) - Coverage ratchet policy
|
|
406
|
+
- [CLAUDE.md](../../../docs/guides/CLAUDE.md) - AI agent integration
|
|
407
|
+
|
|
408
|
+
## Future Enhancements
|
|
409
|
+
|
|
410
|
+
- [ ] Machine learning for pattern detection improvement
|
|
411
|
+
- [ ] Predictive quality degradation alerts
|
|
412
|
+
- [ ] Custom pattern definition language
|
|
413
|
+
- [ ] Integration with more static analysis tools
|
|
414
|
+
- [ ] Quality dashboard with real-time metrics
|
|
415
|
+
- [ ] Automated baseline recommendations
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Quality-focused service modules."""
|
|
2
|
+
|
|
3
|
+
from crackerjack.services.config_template import * # noqa: F401,F403
|
|
4
|
+
|
|
5
|
+
from .anomaly_detector import * # noqa: F401,F403
|
|
6
|
+
from .pattern_cache import * # noqa: F401,F403
|
|
7
|
+
from .pattern_detector import * # noqa: F401,F403
|
|
8
|
+
from .qa_orchestrator import * # noqa: F401,F403
|
|
9
|
+
from .quality_baseline import * # noqa: F401,F403
|
|
10
|
+
from .quality_baseline_enhanced import * # noqa: F401,F403
|
|
11
|
+
from .quality_intelligence import * # noqa: F401,F403
|