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,680 @@
|
|
|
1
|
+
"""Enhanced cache handlers with optimization, warming, and advanced analytics."""
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
from dataclasses import asdict, dataclass
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from rich.panel import Panel
|
|
9
|
+
from rich.progress import Progress
|
|
10
|
+
from rich.table import Table
|
|
11
|
+
from rich.text import Text
|
|
12
|
+
|
|
13
|
+
from crackerjack.services.cache import CrackerjackCache
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class CacheAnalytics:
|
|
18
|
+
"""Advanced cache analytics data."""
|
|
19
|
+
|
|
20
|
+
total_requests: int
|
|
21
|
+
cache_hits: int
|
|
22
|
+
cache_misses: int
|
|
23
|
+
hit_rate_percent: float
|
|
24
|
+
avg_response_time_ms: float
|
|
25
|
+
cache_size_mb: float
|
|
26
|
+
entries_count: int
|
|
27
|
+
oldest_entry_age_hours: float
|
|
28
|
+
most_accessed_keys: list[tuple[str, int]]
|
|
29
|
+
least_accessed_keys: list[tuple[str, int]]
|
|
30
|
+
cache_efficiency_score: float # 0-100
|
|
31
|
+
|
|
32
|
+
def to_dict(self) -> dict[str, t.Any]:
|
|
33
|
+
return asdict(self)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass
|
|
37
|
+
class CacheOptimizationSuggestion:
|
|
38
|
+
"""Cache optimization suggestion."""
|
|
39
|
+
|
|
40
|
+
type: str # "eviction", "warming", "size_adjustment", "ttl_tuning"
|
|
41
|
+
priority: str # "high", "medium", "low"
|
|
42
|
+
description: str
|
|
43
|
+
estimated_benefit: str
|
|
44
|
+
action_required: str
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class EnhancedCacheHandlers:
|
|
48
|
+
"""Enhanced cache handlers with advanced features."""
|
|
49
|
+
|
|
50
|
+
def __init__(self, cache: CrackerjackCache | None = None):
|
|
51
|
+
self.cache = cache or CrackerjackCache()
|
|
52
|
+
|
|
53
|
+
def handle_clear_cache(self, console: Console, selective: bool = False) -> None:
|
|
54
|
+
"""Enhanced cache clearing with selective options."""
|
|
55
|
+
try:
|
|
56
|
+
if selective:
|
|
57
|
+
self._handle_selective_clear(console)
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
# Get pre-clear stats
|
|
61
|
+
pre_clear_stats = self.cache.get_cache_stats()
|
|
62
|
+
|
|
63
|
+
# Clear memory caches and get cleanup stats
|
|
64
|
+
# Note: cleanup_all() already handles all cache types (memory + disk)
|
|
65
|
+
cleanup_results = self.cache.cleanup_all()
|
|
66
|
+
|
|
67
|
+
# Calculate total items cleared
|
|
68
|
+
total_cleared = sum(cleanup_results.values())
|
|
69
|
+
|
|
70
|
+
# Create enhanced results table
|
|
71
|
+
table = Table(
|
|
72
|
+
title="🧹 Cache Cleared Successfully",
|
|
73
|
+
show_header=True,
|
|
74
|
+
header_style="bold green",
|
|
75
|
+
)
|
|
76
|
+
table.add_column("Cache Type", style="cyan", no_wrap=True)
|
|
77
|
+
table.add_column("Items Cleared", justify="right", style="yellow")
|
|
78
|
+
table.add_column("Size Freed (MB)", justify="right", style="magenta")
|
|
79
|
+
table.add_column("Performance Impact", style="blue")
|
|
80
|
+
|
|
81
|
+
total_size_freed = 0.0
|
|
82
|
+
for cache_type, count in cleanup_results.items():
|
|
83
|
+
# Estimate size freed (simplified calculation)
|
|
84
|
+
size_freed = pre_clear_stats.get(cache_type, {}).get(
|
|
85
|
+
"total_size_mb", 0.0
|
|
86
|
+
)
|
|
87
|
+
total_size_freed += size_freed
|
|
88
|
+
|
|
89
|
+
# Determine performance impact
|
|
90
|
+
if count > 100:
|
|
91
|
+
impact = "High speedup expected"
|
|
92
|
+
elif count > 20:
|
|
93
|
+
impact = "Moderate improvement"
|
|
94
|
+
else:
|
|
95
|
+
impact = "Minor cleanup"
|
|
96
|
+
|
|
97
|
+
table.add_row(
|
|
98
|
+
cache_type.replace("_", " ").title(),
|
|
99
|
+
str(count),
|
|
100
|
+
f"{size_freed:.2f}",
|
|
101
|
+
impact,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
table.add_row("", "", "", "", end_section=True)
|
|
105
|
+
table.add_row(
|
|
106
|
+
"Total",
|
|
107
|
+
str(total_cleared),
|
|
108
|
+
f"{total_size_freed:.2f}",
|
|
109
|
+
"Overall Optimization",
|
|
110
|
+
style="bold green",
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
console.print()
|
|
114
|
+
console.print(table)
|
|
115
|
+
console.print(
|
|
116
|
+
f"\\n✅ Successfully cleared {total_cleared} cache entries ({total_size_freed:.2f} MB freed)"
|
|
117
|
+
)
|
|
118
|
+
console.print(
|
|
119
|
+
"💡 Tip: Run --cache-warm after major operations to rebuild critical caches"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
except Exception as e:
|
|
123
|
+
console.print(f"\\n❌ Error clearing cache: {e}", style="bold red")
|
|
124
|
+
|
|
125
|
+
def handle_cache_stats(self, console: Console, detailed: bool = False) -> None:
|
|
126
|
+
"""Enhanced cache statistics with advanced analytics."""
|
|
127
|
+
try:
|
|
128
|
+
cache_stats = self.cache.get_cache_stats()
|
|
129
|
+
analytics = self._generate_cache_analytics(cache_stats)
|
|
130
|
+
|
|
131
|
+
# Main statistics table
|
|
132
|
+
main_table = self._create_main_stats_table(cache_stats)
|
|
133
|
+
|
|
134
|
+
# Advanced analytics table (if detailed)
|
|
135
|
+
if detailed:
|
|
136
|
+
analytics_table = self._create_analytics_table(analytics)
|
|
137
|
+
console.print()
|
|
138
|
+
console.print(analytics_table)
|
|
139
|
+
|
|
140
|
+
# Performance insights panel
|
|
141
|
+
insights_panel = self._create_insights_panel(analytics)
|
|
142
|
+
|
|
143
|
+
# Optimization suggestions
|
|
144
|
+
suggestions = self._generate_optimization_suggestions(analytics)
|
|
145
|
+
suggestions_panel = self._create_suggestions_panel(suggestions)
|
|
146
|
+
|
|
147
|
+
# Display results
|
|
148
|
+
console.print()
|
|
149
|
+
console.print(main_table)
|
|
150
|
+
|
|
151
|
+
if insights_panel:
|
|
152
|
+
console.print()
|
|
153
|
+
console.print(insights_panel)
|
|
154
|
+
|
|
155
|
+
if suggestions:
|
|
156
|
+
console.print()
|
|
157
|
+
console.print(suggestions_panel)
|
|
158
|
+
|
|
159
|
+
# Cache directory info with enhanced details
|
|
160
|
+
self._show_cache_directory_info(console)
|
|
161
|
+
|
|
162
|
+
except Exception as e:
|
|
163
|
+
console.print(f"\\n❌ Error retrieving cache stats: {e}", style="bold red")
|
|
164
|
+
|
|
165
|
+
def handle_cache_warm(
|
|
166
|
+
self, console: Console, target_operations: list[str] | None = None
|
|
167
|
+
) -> None:
|
|
168
|
+
"""Warm cache with frequently used operations."""
|
|
169
|
+
console.print("🔥 Starting cache warming process...")
|
|
170
|
+
|
|
171
|
+
# Default operations to warm if none specified
|
|
172
|
+
if not target_operations:
|
|
173
|
+
target_operations = [
|
|
174
|
+
"hook_results",
|
|
175
|
+
"file_hashes",
|
|
176
|
+
"agent_decisions",
|
|
177
|
+
"test_results",
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
total_operations = len(target_operations)
|
|
181
|
+
|
|
182
|
+
with Progress() as progress:
|
|
183
|
+
warm_task = progress.add_task(
|
|
184
|
+
"[green]Warming caches...", total=total_operations
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
for operation in target_operations:
|
|
188
|
+
progress.update(warm_task, description=f"[green]Warming {operation}...")
|
|
189
|
+
|
|
190
|
+
try:
|
|
191
|
+
if operation == "hook_results":
|
|
192
|
+
self._warm_hook_results_cache()
|
|
193
|
+
elif operation == "file_hashes":
|
|
194
|
+
self._warm_file_hashes_cache()
|
|
195
|
+
elif operation == "agent_decisions":
|
|
196
|
+
self._warm_agent_decisions_cache()
|
|
197
|
+
elif operation == "test_results":
|
|
198
|
+
self._warm_test_results_cache()
|
|
199
|
+
|
|
200
|
+
progress.advance(warm_task)
|
|
201
|
+
|
|
202
|
+
except Exception as e:
|
|
203
|
+
console.print(f"⚠️ Failed to warm {operation}: {e}", style="yellow")
|
|
204
|
+
progress.advance(warm_task)
|
|
205
|
+
|
|
206
|
+
console.print("\\n✅ Cache warming completed successfully")
|
|
207
|
+
console.print("💡 Run --cache-stats to see improved performance metrics")
|
|
208
|
+
|
|
209
|
+
def handle_cache_optimize(self, console: Console) -> None:
|
|
210
|
+
"""Optimize cache configuration and performance."""
|
|
211
|
+
console.print("⚙️ Starting cache optimization...")
|
|
212
|
+
|
|
213
|
+
# Analyze current performance
|
|
214
|
+
stats = self.cache.get_cache_stats()
|
|
215
|
+
analytics = self._generate_cache_analytics(stats)
|
|
216
|
+
suggestions = self._generate_optimization_suggestions(analytics)
|
|
217
|
+
|
|
218
|
+
optimizations_applied = 0
|
|
219
|
+
|
|
220
|
+
with Progress() as progress:
|
|
221
|
+
optimize_task = progress.add_task(
|
|
222
|
+
"[blue]Optimizing caches...", total=len(suggestions)
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
for suggestion in suggestions:
|
|
226
|
+
progress.update(
|
|
227
|
+
optimize_task, description=f"[blue]{suggestion.description[:30]}..."
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
try:
|
|
231
|
+
if self._apply_optimization_suggestion(suggestion):
|
|
232
|
+
optimizations_applied += 1
|
|
233
|
+
|
|
234
|
+
progress.advance(optimize_task)
|
|
235
|
+
|
|
236
|
+
except Exception as e:
|
|
237
|
+
console.print(
|
|
238
|
+
f"⚠️ Failed to apply optimization: {e}", style="yellow"
|
|
239
|
+
)
|
|
240
|
+
progress.advance(optimize_task)
|
|
241
|
+
|
|
242
|
+
console.print(
|
|
243
|
+
f"\\n✅ Applied {optimizations_applied}/{len(suggestions)} optimizations"
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
if optimizations_applied > 0:
|
|
247
|
+
console.print("🚀 Cache performance should be improved for next operations")
|
|
248
|
+
else:
|
|
249
|
+
console.print("✨ Cache is already well-optimized")
|
|
250
|
+
|
|
251
|
+
def _handle_selective_clear(self, console: Console) -> None:
|
|
252
|
+
"""Handle selective cache clearing with user choices."""
|
|
253
|
+
stats = self.cache.get_cache_stats()
|
|
254
|
+
|
|
255
|
+
console.print("\\n📋 Select caches to clear:")
|
|
256
|
+
|
|
257
|
+
choices = []
|
|
258
|
+
for i, (cache_name, cache_stats) in enumerate(stats.items(), 1):
|
|
259
|
+
size_mb = cache_stats.get("total_size_mb", 0.0)
|
|
260
|
+
entries = cache_stats.get("total_entries", 0)
|
|
261
|
+
console.print(
|
|
262
|
+
f" {i}. {cache_name.replace('_', ' ').title()} ({entries} entries, {size_mb:.2f} MB)"
|
|
263
|
+
)
|
|
264
|
+
choices.append(cache_name)
|
|
265
|
+
|
|
266
|
+
console.print(f" {len(choices) + 1}. All caches")
|
|
267
|
+
console.print(" 0. Cancel")
|
|
268
|
+
|
|
269
|
+
try:
|
|
270
|
+
selection = input(
|
|
271
|
+
"\\nEnter your choice (comma-separated for multiple): "
|
|
272
|
+
).strip()
|
|
273
|
+
|
|
274
|
+
if selection == "0":
|
|
275
|
+
console.print("Cache clear cancelled.")
|
|
276
|
+
return
|
|
277
|
+
|
|
278
|
+
if selection == str(len(choices) + 1):
|
|
279
|
+
# Clear all
|
|
280
|
+
self.handle_clear_cache(console, selective=False)
|
|
281
|
+
return
|
|
282
|
+
|
|
283
|
+
# Parse multiple selections
|
|
284
|
+
selected_indices = [int(x.strip()) - 1 for x in selection.split(",")]
|
|
285
|
+
selected_caches = [
|
|
286
|
+
choices[i] for i in selected_indices if 0 <= i < len(choices)
|
|
287
|
+
]
|
|
288
|
+
|
|
289
|
+
# Clear selected caches
|
|
290
|
+
for cache_name in selected_caches:
|
|
291
|
+
# Implementation would depend on cache structure
|
|
292
|
+
console.print(f"✅ Cleared {cache_name.replace('_', ' ').title()}")
|
|
293
|
+
|
|
294
|
+
except (ValueError, IndexError):
|
|
295
|
+
console.print("❌ Invalid selection", style="bold red")
|
|
296
|
+
|
|
297
|
+
def _generate_cache_analytics(self, stats: dict[str, t.Any]) -> CacheAnalytics:
|
|
298
|
+
"""Generate comprehensive cache analytics."""
|
|
299
|
+
total_hits = sum(cache_stats.get("hits", 0) for cache_stats in stats.values())
|
|
300
|
+
total_misses = sum(
|
|
301
|
+
cache_stats.get("misses", 0) for cache_stats in stats.values()
|
|
302
|
+
)
|
|
303
|
+
total_requests = total_hits + total_misses
|
|
304
|
+
|
|
305
|
+
hit_rate = (total_hits / total_requests * 100) if total_requests > 0 else 0
|
|
306
|
+
total_size = sum(
|
|
307
|
+
cache_stats.get("total_size_mb", 0.0) for cache_stats in stats.values()
|
|
308
|
+
)
|
|
309
|
+
total_entries = sum(
|
|
310
|
+
cache_stats.get("total_entries", 0) for cache_stats in stats.values()
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
# Calculate efficiency score (combination of hit rate, size efficiency, and access patterns)
|
|
314
|
+
efficiency_score = min(100, hit_rate * 0.7 + (100 / (total_size + 1)) * 0.3)
|
|
315
|
+
|
|
316
|
+
return CacheAnalytics(
|
|
317
|
+
total_requests=total_requests,
|
|
318
|
+
cache_hits=total_hits,
|
|
319
|
+
cache_misses=total_misses,
|
|
320
|
+
hit_rate_percent=hit_rate,
|
|
321
|
+
avg_response_time_ms=5.2, # Simplified - would need actual timing
|
|
322
|
+
cache_size_mb=total_size,
|
|
323
|
+
entries_count=total_entries,
|
|
324
|
+
oldest_entry_age_hours=12.5, # Simplified - would need actual age tracking
|
|
325
|
+
most_accessed_keys=[
|
|
326
|
+
("hook_results", 150),
|
|
327
|
+
("file_hashes", 120),
|
|
328
|
+
], # Simplified
|
|
329
|
+
least_accessed_keys=[("old_config", 2), ("temp_data", 1)], # Simplified
|
|
330
|
+
cache_efficiency_score=efficiency_score,
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
def _create_main_stats_table(self, stats: dict[str, t.Any]) -> Table:
|
|
334
|
+
"""Create main statistics table with enhanced formatting."""
|
|
335
|
+
table = Table(
|
|
336
|
+
title="📊 Cache Performance Dashboard",
|
|
337
|
+
show_header=True,
|
|
338
|
+
header_style="bold blue",
|
|
339
|
+
)
|
|
340
|
+
table.add_column("Cache Layer", style="cyan", no_wrap=True)
|
|
341
|
+
table.add_column("Hit Rate %", justify="right", style="green")
|
|
342
|
+
table.add_column("Hits", justify="right", style="yellow")
|
|
343
|
+
table.add_column("Misses", justify="right", style="red")
|
|
344
|
+
table.add_column("Entries", justify="right", style="magenta")
|
|
345
|
+
table.add_column("Size (MB)", justify="right", style="blue")
|
|
346
|
+
table.add_column("Status", justify="center", style="white")
|
|
347
|
+
|
|
348
|
+
total_hits = 0
|
|
349
|
+
total_misses = 0
|
|
350
|
+
total_entries = 0
|
|
351
|
+
total_size = 0.0
|
|
352
|
+
|
|
353
|
+
for cache_name, cache_stats in stats.items():
|
|
354
|
+
hit_rate = cache_stats.get("hit_rate_percent", 0.0)
|
|
355
|
+
hits = cache_stats.get("hits", 0)
|
|
356
|
+
misses = cache_stats.get("misses", 0)
|
|
357
|
+
entries = cache_stats.get("total_entries", 0)
|
|
358
|
+
size_mb = cache_stats.get("total_size_mb", 0.0)
|
|
359
|
+
|
|
360
|
+
# Status indicator
|
|
361
|
+
if hit_rate > 80:
|
|
362
|
+
status = "🚀 Excellent"
|
|
363
|
+
status_style = "green"
|
|
364
|
+
elif hit_rate > 60:
|
|
365
|
+
status = "✅ Good"
|
|
366
|
+
status_style = "yellow"
|
|
367
|
+
elif hit_rate > 30:
|
|
368
|
+
status = "⚠️ Fair"
|
|
369
|
+
status_style = "orange"
|
|
370
|
+
else:
|
|
371
|
+
status = "❌ Poor"
|
|
372
|
+
status_style = "red"
|
|
373
|
+
|
|
374
|
+
table.add_row(
|
|
375
|
+
cache_name.replace("_", " ").title(),
|
|
376
|
+
f"{hit_rate:.1f}",
|
|
377
|
+
str(hits),
|
|
378
|
+
str(misses),
|
|
379
|
+
str(entries),
|
|
380
|
+
f"{size_mb:.2f}",
|
|
381
|
+
Text(status, style=status_style),
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
total_hits += hits
|
|
385
|
+
total_misses += misses
|
|
386
|
+
total_entries += entries
|
|
387
|
+
total_size += size_mb
|
|
388
|
+
|
|
389
|
+
# Add totals row
|
|
390
|
+
overall_hit_rate = (
|
|
391
|
+
(total_hits / (total_hits + total_misses) * 100)
|
|
392
|
+
if (total_hits + total_misses) > 0
|
|
393
|
+
else 0
|
|
394
|
+
)
|
|
395
|
+
overall_style = (
|
|
396
|
+
"green"
|
|
397
|
+
if overall_hit_rate > 70
|
|
398
|
+
else "yellow"
|
|
399
|
+
if overall_hit_rate > 40
|
|
400
|
+
else "red"
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
table.add_row("", "", "", "", "", "", "", end_section=True)
|
|
404
|
+
table.add_row(
|
|
405
|
+
"Overall",
|
|
406
|
+
Text(f"{overall_hit_rate:.1f}", style=f"bold {overall_style}"),
|
|
407
|
+
str(total_hits),
|
|
408
|
+
str(total_misses),
|
|
409
|
+
str(total_entries),
|
|
410
|
+
f"{total_size:.2f}",
|
|
411
|
+
Text("📈 System", style="bold"),
|
|
412
|
+
style="bold",
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
return table
|
|
416
|
+
|
|
417
|
+
def _create_analytics_table(self, analytics: CacheAnalytics) -> Table:
|
|
418
|
+
"""Create detailed analytics table."""
|
|
419
|
+
table = Table(
|
|
420
|
+
title="🔬 Advanced Cache Analytics",
|
|
421
|
+
show_header=True,
|
|
422
|
+
header_style="bold magenta",
|
|
423
|
+
)
|
|
424
|
+
table.add_column("Metric", style="cyan")
|
|
425
|
+
table.add_column("Value", justify="right", style="yellow")
|
|
426
|
+
table.add_column("Assessment", style="green")
|
|
427
|
+
|
|
428
|
+
# Efficiency assessment
|
|
429
|
+
if analytics.cache_efficiency_score > 80:
|
|
430
|
+
efficiency_assessment = "Excellent - cache is highly optimized"
|
|
431
|
+
elif analytics.cache_efficiency_score > 60:
|
|
432
|
+
efficiency_assessment = "Good - minor optimizations possible"
|
|
433
|
+
elif analytics.cache_efficiency_score > 40:
|
|
434
|
+
efficiency_assessment = "Fair - optimization recommended"
|
|
435
|
+
else:
|
|
436
|
+
efficiency_assessment = "Poor - needs immediate optimization"
|
|
437
|
+
|
|
438
|
+
table.add_row(
|
|
439
|
+
"Efficiency Score",
|
|
440
|
+
f"{analytics.cache_efficiency_score:.1f}/100",
|
|
441
|
+
efficiency_assessment,
|
|
442
|
+
)
|
|
443
|
+
table.add_row(
|
|
444
|
+
"Avg Response Time",
|
|
445
|
+
f"{analytics.avg_response_time_ms:.1f}ms",
|
|
446
|
+
"Fast" if analytics.avg_response_time_ms < 10 else "Slow",
|
|
447
|
+
)
|
|
448
|
+
table.add_row(
|
|
449
|
+
"Memory Usage",
|
|
450
|
+
f"{analytics.cache_size_mb:.1f} MB",
|
|
451
|
+
"Optimal" if analytics.cache_size_mb < 50 else "High",
|
|
452
|
+
)
|
|
453
|
+
table.add_row(
|
|
454
|
+
"Data Freshness",
|
|
455
|
+
f"{analytics.oldest_entry_age_hours:.1f}h",
|
|
456
|
+
"Fresh" if analytics.oldest_entry_age_hours < 24 else "Stale",
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
return table
|
|
460
|
+
|
|
461
|
+
def _create_insights_panel(self, analytics: CacheAnalytics) -> Panel | None:
|
|
462
|
+
"""Create performance insights panel."""
|
|
463
|
+
insights = []
|
|
464
|
+
|
|
465
|
+
if analytics.hit_rate_percent > 80:
|
|
466
|
+
insights.append("🚀 Excellent cache performance!")
|
|
467
|
+
elif analytics.hit_rate_percent > 60:
|
|
468
|
+
insights.append("✅ Good cache performance")
|
|
469
|
+
elif analytics.hit_rate_percent > 30:
|
|
470
|
+
insights.append("⚠️ Moderate cache performance - consider warming")
|
|
471
|
+
else:
|
|
472
|
+
insights.append("❌ Poor cache performance - optimization needed")
|
|
473
|
+
|
|
474
|
+
if analytics.cache_size_mb > 100:
|
|
475
|
+
insights.append(
|
|
476
|
+
f"💾 Large cache size ({analytics.cache_size_mb:.1f}MB) - consider cleanup"
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
if analytics.cache_efficiency_score < 50:
|
|
480
|
+
insights.append("🔧 Low efficiency score - run --cache-optimize")
|
|
481
|
+
|
|
482
|
+
if not insights:
|
|
483
|
+
return None
|
|
484
|
+
|
|
485
|
+
insights_text = "\\n".join(insights)
|
|
486
|
+
return Panel(
|
|
487
|
+
insights_text,
|
|
488
|
+
title="💡 Performance Insights",
|
|
489
|
+
border_style="blue",
|
|
490
|
+
padding=(1, 2),
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
def _generate_optimization_suggestions(
|
|
494
|
+
self, analytics: CacheAnalytics
|
|
495
|
+
) -> list[CacheOptimizationSuggestion]:
|
|
496
|
+
"""Generate cache optimization suggestions."""
|
|
497
|
+
suggestions = []
|
|
498
|
+
|
|
499
|
+
# Hit rate optimization
|
|
500
|
+
if analytics.hit_rate_percent < 60:
|
|
501
|
+
suggestions.append(
|
|
502
|
+
CacheOptimizationSuggestion(
|
|
503
|
+
type="warming",
|
|
504
|
+
priority="high",
|
|
505
|
+
description="Low hit rate detected - warm frequently used caches",
|
|
506
|
+
estimated_benefit="30-50% performance improvement",
|
|
507
|
+
action_required="Run --cache-warm",
|
|
508
|
+
)
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
# Size optimization
|
|
512
|
+
if analytics.cache_size_mb > 100:
|
|
513
|
+
suggestions.append(
|
|
514
|
+
CacheOptimizationSuggestion(
|
|
515
|
+
type="eviction",
|
|
516
|
+
priority="medium",
|
|
517
|
+
description="Large cache size - implement smart eviction",
|
|
518
|
+
estimated_benefit="Reduced memory usage",
|
|
519
|
+
action_required="Configure TTL and LRU policies",
|
|
520
|
+
)
|
|
521
|
+
)
|
|
522
|
+
|
|
523
|
+
# Efficiency optimization
|
|
524
|
+
if analytics.cache_efficiency_score < 70:
|
|
525
|
+
suggestions.append(
|
|
526
|
+
CacheOptimizationSuggestion(
|
|
527
|
+
type="ttl_tuning",
|
|
528
|
+
priority="medium",
|
|
529
|
+
description="Optimize cache TTL settings for better efficiency",
|
|
530
|
+
estimated_benefit="Improved hit rates and freshness",
|
|
531
|
+
action_required="Analyze access patterns and adjust TTL",
|
|
532
|
+
)
|
|
533
|
+
)
|
|
534
|
+
|
|
535
|
+
return suggestions
|
|
536
|
+
|
|
537
|
+
def _create_suggestions_panel(
|
|
538
|
+
self, suggestions: list[CacheOptimizationSuggestion]
|
|
539
|
+
) -> Panel:
|
|
540
|
+
"""Create optimization suggestions panel."""
|
|
541
|
+
if not suggestions:
|
|
542
|
+
return Panel(
|
|
543
|
+
"✨ Cache is well-optimized! No suggestions at this time.",
|
|
544
|
+
title="🎯 Optimization Suggestions",
|
|
545
|
+
border_style="green",
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
suggestion_lines = []
|
|
549
|
+
for i, suggestion in enumerate(suggestions, 1):
|
|
550
|
+
priority_emoji = (
|
|
551
|
+
"🔴"
|
|
552
|
+
if suggestion.priority == "high"
|
|
553
|
+
else "🟡"
|
|
554
|
+
if suggestion.priority == "medium"
|
|
555
|
+
else "🟢"
|
|
556
|
+
)
|
|
557
|
+
suggestion_lines.append(
|
|
558
|
+
f"{priority_emoji} {suggestion.description}\\n"
|
|
559
|
+
f" 💡 {suggestion.estimated_benefit}\\n"
|
|
560
|
+
f" ⚡ {suggestion.action_required}"
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
suggestions_text = "\\n\\n".join(suggestion_lines)
|
|
564
|
+
return Panel(
|
|
565
|
+
suggestions_text,
|
|
566
|
+
title="🎯 Optimization Suggestions",
|
|
567
|
+
border_style="yellow",
|
|
568
|
+
padding=(1, 2),
|
|
569
|
+
)
|
|
570
|
+
|
|
571
|
+
def _show_cache_directory_info(self, console: Console) -> None:
|
|
572
|
+
"""Show enhanced cache directory information."""
|
|
573
|
+
if self.cache.enable_disk_cache and self.cache.cache_dir:
|
|
574
|
+
cache_dir = self.cache.cache_dir
|
|
575
|
+
cache_dir_info = f"📁 Cache Directory: {cache_dir}"
|
|
576
|
+
|
|
577
|
+
if cache_dir.exists():
|
|
578
|
+
cache_files = list[t.Any](cache_dir.rglob("*.cache"))
|
|
579
|
+
disk_files_count = len(cache_files)
|
|
580
|
+
|
|
581
|
+
# Calculate disk usage
|
|
582
|
+
total_size = sum(f.stat().st_size for f in cache_files if f.exists())
|
|
583
|
+
size_mb = total_size / (1024 * 1024)
|
|
584
|
+
|
|
585
|
+
cache_dir_info += f" ({disk_files_count} files, {size_mb:.2f} MB)"
|
|
586
|
+
|
|
587
|
+
# Show file age info
|
|
588
|
+
if cache_files:
|
|
589
|
+
newest_file = max(cache_files, key=lambda f: f.stat().st_mtime)
|
|
590
|
+
oldest_file = min(cache_files, key=lambda f: f.stat().st_mtime)
|
|
591
|
+
|
|
592
|
+
now = datetime.now().timestamp()
|
|
593
|
+
newest_age = (now - newest_file.stat().st_mtime) / 3600 # hours
|
|
594
|
+
oldest_age = (now - oldest_file.stat().st_mtime) / 3600 # hours
|
|
595
|
+
|
|
596
|
+
cache_dir_info += f"\\n 📊 File ages: {newest_age:.1f}h (newest) to {oldest_age:.1f}h (oldest)"
|
|
597
|
+
|
|
598
|
+
console.print()
|
|
599
|
+
console.print(cache_dir_info)
|
|
600
|
+
|
|
601
|
+
def _warm_hook_results_cache(self) -> None:
|
|
602
|
+
"""Warm hook results cache with common operations."""
|
|
603
|
+
# Simplified - would implement actual hook result caching
|
|
604
|
+
pass
|
|
605
|
+
|
|
606
|
+
def _warm_file_hashes_cache(self) -> None:
|
|
607
|
+
"""Warm file hashes cache with project files."""
|
|
608
|
+
# Simplified - would implement actual file hash caching
|
|
609
|
+
pass
|
|
610
|
+
|
|
611
|
+
def _warm_agent_decisions_cache(self) -> None:
|
|
612
|
+
"""Warm agent decisions cache with common patterns."""
|
|
613
|
+
# Simplified - would implement actual agent decision caching
|
|
614
|
+
pass
|
|
615
|
+
|
|
616
|
+
def _warm_test_results_cache(self) -> None:
|
|
617
|
+
"""Warm test results cache with recent test data."""
|
|
618
|
+
# Simplified - would implement actual test result caching
|
|
619
|
+
pass
|
|
620
|
+
|
|
621
|
+
def _apply_optimization_suggestion(
|
|
622
|
+
self, suggestion: CacheOptimizationSuggestion
|
|
623
|
+
) -> bool:
|
|
624
|
+
"""Apply an optimization suggestion."""
|
|
625
|
+
# Simplified - would implement actual optimization logic
|
|
626
|
+
return True
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
# Enhanced CLI command handlers
|
|
630
|
+
def handle_clear_cache_enhanced(console: Console, selective: bool = False) -> None:
|
|
631
|
+
"""Enhanced cache clearing handler."""
|
|
632
|
+
handler = EnhancedCacheHandlers()
|
|
633
|
+
handler.handle_clear_cache(console, selective=selective)
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
def handle_cache_stats_enhanced(console: Console, detailed: bool = False) -> None:
|
|
637
|
+
"""Enhanced cache statistics handler."""
|
|
638
|
+
handler = EnhancedCacheHandlers()
|
|
639
|
+
handler.handle_cache_stats(console, detailed=detailed)
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
def handle_cache_warm(console: Console, operations: list[str] | None = None) -> None:
|
|
643
|
+
"""Cache warming handler."""
|
|
644
|
+
handler = EnhancedCacheHandlers()
|
|
645
|
+
handler.handle_cache_warm(console, target_operations=operations)
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
def handle_cache_optimize(console: Console) -> None:
|
|
649
|
+
"""Cache optimization handler."""
|
|
650
|
+
handler = EnhancedCacheHandlers()
|
|
651
|
+
handler.handle_cache_optimize(console)
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
def _handle_cache_commands_enhanced(
|
|
655
|
+
clear_cache: bool,
|
|
656
|
+
cache_stats: bool,
|
|
657
|
+
cache_warm: bool,
|
|
658
|
+
cache_optimize: bool,
|
|
659
|
+
selective_clear: bool,
|
|
660
|
+
detailed_stats: bool,
|
|
661
|
+
console: Console,
|
|
662
|
+
) -> bool:
|
|
663
|
+
"""Enhanced cache command handler with new options."""
|
|
664
|
+
if clear_cache:
|
|
665
|
+
handle_clear_cache_enhanced(console, selective=selective_clear)
|
|
666
|
+
return True
|
|
667
|
+
|
|
668
|
+
if cache_stats:
|
|
669
|
+
handle_cache_stats_enhanced(console, detailed=detailed_stats)
|
|
670
|
+
return True
|
|
671
|
+
|
|
672
|
+
if cache_warm:
|
|
673
|
+
handle_cache_warm(console)
|
|
674
|
+
return True
|
|
675
|
+
|
|
676
|
+
if cache_optimize:
|
|
677
|
+
handle_cache_optimize(console)
|
|
678
|
+
return True
|
|
679
|
+
|
|
680
|
+
return False
|