crackerjack 0.37.9__py3-none-any.whl → 0.45.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- crackerjack/README.md +19 -0
- crackerjack/__init__.py +30 -1
- crackerjack/__main__.py +342 -1263
- crackerjack/adapters/README.md +18 -0
- crackerjack/adapters/__init__.py +27 -5
- crackerjack/adapters/_output_paths.py +167 -0
- crackerjack/adapters/_qa_adapter_base.py +309 -0
- crackerjack/adapters/_tool_adapter_base.py +706 -0
- crackerjack/adapters/ai/README.md +65 -0
- crackerjack/adapters/ai/__init__.py +5 -0
- crackerjack/adapters/ai/claude.py +853 -0
- crackerjack/adapters/complexity/README.md +53 -0
- crackerjack/adapters/complexity/__init__.py +10 -0
- crackerjack/adapters/complexity/complexipy.py +641 -0
- crackerjack/adapters/dependency/__init__.py +22 -0
- crackerjack/adapters/dependency/pip_audit.py +418 -0
- crackerjack/adapters/format/README.md +72 -0
- crackerjack/adapters/format/__init__.py +11 -0
- crackerjack/adapters/format/mdformat.py +313 -0
- crackerjack/adapters/format/ruff.py +516 -0
- crackerjack/adapters/lint/README.md +47 -0
- crackerjack/adapters/lint/__init__.py +11 -0
- crackerjack/adapters/lint/codespell.py +273 -0
- crackerjack/adapters/lsp/README.md +49 -0
- crackerjack/adapters/lsp/__init__.py +27 -0
- crackerjack/adapters/{rust_tool_manager.py → lsp/_manager.py} +3 -3
- crackerjack/adapters/{skylos_adapter.py → lsp/skylos.py} +59 -7
- crackerjack/adapters/{zuban_adapter.py → lsp/zuban.py} +3 -6
- crackerjack/adapters/refactor/README.md +59 -0
- crackerjack/adapters/refactor/__init__.py +12 -0
- crackerjack/adapters/refactor/creosote.py +318 -0
- crackerjack/adapters/refactor/refurb.py +406 -0
- crackerjack/adapters/refactor/skylos.py +494 -0
- crackerjack/adapters/sast/README.md +132 -0
- crackerjack/adapters/sast/__init__.py +32 -0
- crackerjack/adapters/sast/_base.py +201 -0
- crackerjack/adapters/sast/bandit.py +423 -0
- crackerjack/adapters/sast/pyscn.py +405 -0
- crackerjack/adapters/sast/semgrep.py +241 -0
- crackerjack/adapters/security/README.md +111 -0
- crackerjack/adapters/security/__init__.py +17 -0
- crackerjack/adapters/security/gitleaks.py +339 -0
- crackerjack/adapters/type/README.md +52 -0
- crackerjack/adapters/type/__init__.py +12 -0
- crackerjack/adapters/type/pyrefly.py +402 -0
- crackerjack/adapters/type/ty.py +402 -0
- crackerjack/adapters/type/zuban.py +522 -0
- crackerjack/adapters/utility/README.md +51 -0
- crackerjack/adapters/utility/__init__.py +10 -0
- crackerjack/adapters/utility/checks.py +884 -0
- crackerjack/agents/README.md +264 -0
- crackerjack/agents/__init__.py +40 -12
- crackerjack/agents/base.py +1 -0
- crackerjack/agents/claude_code_bridge.py +641 -0
- crackerjack/agents/coordinator.py +49 -53
- crackerjack/agents/dry_agent.py +187 -3
- crackerjack/agents/enhanced_coordinator.py +279 -0
- crackerjack/agents/enhanced_proactive_agent.py +185 -0
- crackerjack/agents/error_middleware.py +53 -0
- crackerjack/agents/formatting_agent.py +6 -8
- crackerjack/agents/helpers/__init__.py +9 -0
- crackerjack/agents/helpers/performance/__init__.py +22 -0
- crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
- crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
- crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
- crackerjack/agents/helpers/refactoring/__init__.py +22 -0
- crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
- crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
- crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
- crackerjack/agents/helpers/test_creation/__init__.py +19 -0
- crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
- crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
- crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
- crackerjack/agents/performance_agent.py +121 -1152
- crackerjack/agents/refactoring_agent.py +156 -655
- crackerjack/agents/semantic_agent.py +479 -0
- crackerjack/agents/semantic_helpers.py +356 -0
- crackerjack/agents/test_creation_agent.py +19 -1605
- crackerjack/api.py +5 -7
- crackerjack/cli/README.md +394 -0
- crackerjack/cli/__init__.py +1 -1
- crackerjack/cli/cache_handlers.py +23 -18
- crackerjack/cli/cache_handlers_enhanced.py +1 -4
- crackerjack/cli/facade.py +70 -8
- crackerjack/cli/formatting.py +13 -0
- crackerjack/cli/handlers/__init__.py +85 -0
- crackerjack/cli/handlers/advanced.py +103 -0
- crackerjack/cli/handlers/ai_features.py +62 -0
- crackerjack/cli/handlers/analytics.py +479 -0
- crackerjack/cli/handlers/changelog.py +271 -0
- crackerjack/cli/handlers/config_handlers.py +16 -0
- crackerjack/cli/handlers/coverage.py +84 -0
- crackerjack/cli/handlers/documentation.py +280 -0
- crackerjack/cli/handlers/main_handlers.py +497 -0
- crackerjack/cli/handlers/monitoring.py +371 -0
- crackerjack/cli/handlers.py +249 -49
- crackerjack/cli/interactive.py +8 -5
- crackerjack/cli/options.py +203 -110
- crackerjack/cli/semantic_handlers.py +292 -0
- crackerjack/cli/version.py +19 -0
- crackerjack/code_cleaner.py +60 -24
- crackerjack/config/README.md +472 -0
- crackerjack/config/__init__.py +256 -0
- crackerjack/config/global_lock_config.py +191 -54
- crackerjack/config/hooks.py +188 -16
- crackerjack/config/loader.py +239 -0
- crackerjack/config/settings.py +141 -0
- crackerjack/config/tool_commands.py +331 -0
- crackerjack/core/README.md +393 -0
- crackerjack/core/async_workflow_orchestrator.py +79 -53
- crackerjack/core/autofix_coordinator.py +22 -9
- crackerjack/core/container.py +10 -9
- crackerjack/core/enhanced_container.py +9 -9
- crackerjack/core/performance.py +1 -1
- crackerjack/core/performance_monitor.py +5 -3
- crackerjack/core/phase_coordinator.py +1018 -634
- crackerjack/core/proactive_workflow.py +3 -3
- crackerjack/core/retry.py +275 -0
- crackerjack/core/service_watchdog.py +167 -23
- crackerjack/core/session_coordinator.py +187 -382
- crackerjack/core/timeout_manager.py +161 -44
- crackerjack/core/workflow/__init__.py +21 -0
- crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
- crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
- crackerjack/core/workflow/workflow_issue_parser.py +714 -0
- crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
- crackerjack/core/workflow/workflow_security_gates.py +400 -0
- crackerjack/core/workflow_orchestrator.py +1247 -953
- crackerjack/data/README.md +11 -0
- crackerjack/data/__init__.py +8 -0
- crackerjack/data/models.py +79 -0
- crackerjack/data/repository.py +210 -0
- crackerjack/decorators/README.md +180 -0
- crackerjack/decorators/__init__.py +35 -0
- crackerjack/decorators/error_handling.py +649 -0
- crackerjack/decorators/error_handling_decorators.py +334 -0
- crackerjack/decorators/helpers.py +58 -0
- crackerjack/decorators/patterns.py +281 -0
- crackerjack/decorators/utils.py +58 -0
- crackerjack/docs/README.md +11 -0
- crackerjack/docs/generated/api/CLI_REFERENCE.md +1 -1
- crackerjack/documentation/README.md +11 -0
- crackerjack/documentation/ai_templates.py +1 -1
- crackerjack/documentation/dual_output_generator.py +11 -9
- crackerjack/documentation/reference_generator.py +104 -59
- crackerjack/dynamic_config.py +52 -61
- crackerjack/errors.py +1 -1
- crackerjack/events/README.md +11 -0
- crackerjack/events/__init__.py +16 -0
- crackerjack/events/telemetry.py +175 -0
- crackerjack/events/workflow_bus.py +346 -0
- crackerjack/exceptions/README.md +301 -0
- crackerjack/exceptions/__init__.py +5 -0
- crackerjack/exceptions/config.py +4 -0
- crackerjack/exceptions/tool_execution_error.py +245 -0
- crackerjack/executors/README.md +591 -0
- crackerjack/executors/__init__.py +2 -0
- crackerjack/executors/async_hook_executor.py +539 -77
- crackerjack/executors/cached_hook_executor.py +3 -3
- crackerjack/executors/hook_executor.py +967 -102
- crackerjack/executors/hook_lock_manager.py +31 -22
- crackerjack/executors/individual_hook_executor.py +66 -32
- crackerjack/executors/lsp_aware_hook_executor.py +136 -57
- crackerjack/executors/progress_hook_executor.py +282 -0
- crackerjack/executors/tool_proxy.py +23 -7
- crackerjack/hooks/README.md +485 -0
- crackerjack/hooks/lsp_hook.py +8 -9
- crackerjack/intelligence/README.md +557 -0
- crackerjack/interactive.py +37 -10
- crackerjack/managers/README.md +369 -0
- crackerjack/managers/async_hook_manager.py +41 -57
- crackerjack/managers/hook_manager.py +449 -79
- crackerjack/managers/publish_manager.py +81 -36
- crackerjack/managers/test_command_builder.py +290 -12
- crackerjack/managers/test_executor.py +93 -8
- crackerjack/managers/test_manager.py +1082 -75
- crackerjack/managers/test_progress.py +118 -26
- crackerjack/mcp/README.md +374 -0
- crackerjack/mcp/cache.py +25 -2
- crackerjack/mcp/client_runner.py +35 -18
- crackerjack/mcp/context.py +9 -9
- crackerjack/mcp/dashboard.py +24 -8
- crackerjack/mcp/enhanced_progress_monitor.py +34 -23
- crackerjack/mcp/file_monitor.py +27 -6
- crackerjack/mcp/progress_components.py +45 -34
- crackerjack/mcp/progress_monitor.py +6 -9
- crackerjack/mcp/rate_limiter.py +11 -7
- crackerjack/mcp/server.py +2 -0
- crackerjack/mcp/server_core.py +187 -55
- crackerjack/mcp/service_watchdog.py +12 -9
- crackerjack/mcp/task_manager.py +2 -2
- crackerjack/mcp/tools/README.md +27 -0
- crackerjack/mcp/tools/__init__.py +2 -0
- crackerjack/mcp/tools/core_tools.py +75 -52
- crackerjack/mcp/tools/execution_tools.py +87 -31
- crackerjack/mcp/tools/intelligence_tools.py +2 -2
- crackerjack/mcp/tools/proactive_tools.py +1 -1
- crackerjack/mcp/tools/semantic_tools.py +584 -0
- crackerjack/mcp/tools/utility_tools.py +180 -132
- crackerjack/mcp/tools/workflow_executor.py +87 -46
- crackerjack/mcp/websocket/README.md +31 -0
- crackerjack/mcp/websocket/app.py +11 -1
- crackerjack/mcp/websocket/event_bridge.py +188 -0
- crackerjack/mcp/websocket/jobs.py +27 -4
- crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
- crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
- crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
- crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
- crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
- crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
- crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
- crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
- crackerjack/mcp/websocket/monitoring/factory.py +109 -0
- crackerjack/mcp/websocket/monitoring/filters.py +10 -0
- crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
- crackerjack/mcp/websocket/monitoring/models.py +90 -0
- crackerjack/mcp/websocket/monitoring/utils.py +171 -0
- crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
- crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
- crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
- crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
- crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
- crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
- crackerjack/mcp/websocket/monitoring_endpoints.py +16 -2930
- crackerjack/mcp/websocket/server.py +1 -3
- crackerjack/mcp/websocket/websocket_handler.py +107 -6
- crackerjack/models/README.md +308 -0
- crackerjack/models/__init__.py +10 -1
- crackerjack/models/config.py +639 -22
- crackerjack/models/config_adapter.py +6 -6
- crackerjack/models/protocols.py +1167 -23
- crackerjack/models/pydantic_models.py +320 -0
- crackerjack/models/qa_config.py +145 -0
- crackerjack/models/qa_results.py +134 -0
- crackerjack/models/results.py +35 -0
- crackerjack/models/semantic_models.py +258 -0
- crackerjack/models/task.py +19 -3
- crackerjack/models/test_models.py +60 -0
- crackerjack/monitoring/README.md +11 -0
- crackerjack/monitoring/ai_agent_watchdog.py +5 -4
- crackerjack/monitoring/metrics_collector.py +4 -3
- crackerjack/monitoring/regression_prevention.py +4 -3
- crackerjack/monitoring/websocket_server.py +4 -241
- crackerjack/orchestration/README.md +340 -0
- crackerjack/orchestration/__init__.py +43 -0
- crackerjack/orchestration/advanced_orchestrator.py +20 -67
- crackerjack/orchestration/cache/README.md +312 -0
- crackerjack/orchestration/cache/__init__.py +37 -0
- crackerjack/orchestration/cache/memory_cache.py +338 -0
- crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
- crackerjack/orchestration/config.py +297 -0
- crackerjack/orchestration/coverage_improvement.py +13 -6
- crackerjack/orchestration/execution_strategies.py +6 -6
- crackerjack/orchestration/hook_orchestrator.py +1398 -0
- crackerjack/orchestration/strategies/README.md +401 -0
- crackerjack/orchestration/strategies/__init__.py +39 -0
- crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
- crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
- crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
- crackerjack/orchestration/test_progress_streamer.py +1 -1
- crackerjack/plugins/README.md +11 -0
- crackerjack/plugins/hooks.py +3 -2
- crackerjack/plugins/loader.py +3 -3
- crackerjack/plugins/managers.py +1 -1
- crackerjack/py313.py +191 -0
- crackerjack/security/README.md +11 -0
- crackerjack/services/README.md +374 -0
- crackerjack/services/__init__.py +8 -21
- crackerjack/services/ai/README.md +295 -0
- crackerjack/services/ai/__init__.py +7 -0
- crackerjack/services/ai/advanced_optimizer.py +878 -0
- crackerjack/services/{contextual_ai_assistant.py → ai/contextual_ai_assistant.py} +5 -3
- crackerjack/services/ai/embeddings.py +444 -0
- crackerjack/services/ai/intelligent_commit.py +328 -0
- crackerjack/services/ai/predictive_analytics.py +510 -0
- crackerjack/services/api_extractor.py +5 -3
- crackerjack/services/bounded_status_operations.py +45 -5
- crackerjack/services/cache.py +249 -318
- crackerjack/services/changelog_automation.py +7 -3
- crackerjack/services/command_execution_service.py +305 -0
- crackerjack/services/config_integrity.py +83 -39
- crackerjack/services/config_merge.py +9 -6
- crackerjack/services/config_service.py +198 -0
- crackerjack/services/config_template.py +13 -26
- crackerjack/services/coverage_badge_service.py +6 -4
- crackerjack/services/coverage_ratchet.py +53 -27
- crackerjack/services/debug.py +18 -7
- crackerjack/services/dependency_analyzer.py +4 -4
- crackerjack/services/dependency_monitor.py +13 -13
- crackerjack/services/documentation_generator.py +4 -2
- crackerjack/services/documentation_service.py +62 -33
- crackerjack/services/enhanced_filesystem.py +81 -27
- crackerjack/services/enterprise_optimizer.py +1 -1
- crackerjack/services/error_pattern_analyzer.py +10 -10
- crackerjack/services/file_filter.py +221 -0
- crackerjack/services/file_hasher.py +5 -7
- crackerjack/services/file_io_service.py +361 -0
- crackerjack/services/file_modifier.py +615 -0
- crackerjack/services/filesystem.py +80 -109
- crackerjack/services/git.py +99 -5
- crackerjack/services/health_metrics.py +4 -6
- crackerjack/services/heatmap_generator.py +12 -3
- crackerjack/services/incremental_executor.py +380 -0
- crackerjack/services/initialization.py +101 -49
- crackerjack/services/log_manager.py +2 -2
- crackerjack/services/logging.py +120 -68
- crackerjack/services/lsp_client.py +12 -12
- crackerjack/services/memory_optimizer.py +27 -22
- crackerjack/services/monitoring/README.md +30 -0
- crackerjack/services/monitoring/__init__.py +9 -0
- crackerjack/services/monitoring/dependency_monitor.py +678 -0
- crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
- crackerjack/services/monitoring/health_metrics.py +716 -0
- crackerjack/services/monitoring/metrics.py +587 -0
- crackerjack/services/{performance_benchmarks.py → monitoring/performance_benchmarks.py} +100 -14
- crackerjack/services/{performance_cache.py → monitoring/performance_cache.py} +21 -15
- crackerjack/services/{performance_monitor.py → monitoring/performance_monitor.py} +10 -6
- crackerjack/services/parallel_executor.py +166 -55
- crackerjack/services/patterns/__init__.py +142 -0
- crackerjack/services/patterns/agents.py +107 -0
- crackerjack/services/patterns/code/__init__.py +15 -0
- crackerjack/services/patterns/code/detection.py +118 -0
- crackerjack/services/patterns/code/imports.py +107 -0
- crackerjack/services/patterns/code/paths.py +159 -0
- crackerjack/services/patterns/code/performance.py +119 -0
- crackerjack/services/patterns/code/replacement.py +36 -0
- crackerjack/services/patterns/core.py +212 -0
- crackerjack/services/patterns/documentation/__init__.py +14 -0
- crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
- crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
- crackerjack/services/patterns/documentation/docstrings.py +89 -0
- crackerjack/services/patterns/formatting.py +226 -0
- crackerjack/services/patterns/operations.py +339 -0
- crackerjack/services/patterns/security/__init__.py +23 -0
- crackerjack/services/patterns/security/code_injection.py +122 -0
- crackerjack/services/patterns/security/credentials.py +190 -0
- crackerjack/services/patterns/security/path_traversal.py +221 -0
- crackerjack/services/patterns/security/unsafe_operations.py +216 -0
- crackerjack/services/patterns/templates.py +62 -0
- crackerjack/services/patterns/testing/__init__.py +18 -0
- crackerjack/services/patterns/testing/error_patterns.py +107 -0
- crackerjack/services/patterns/testing/pytest_output.py +126 -0
- crackerjack/services/patterns/tool_output/__init__.py +16 -0
- crackerjack/services/patterns/tool_output/bandit.py +72 -0
- crackerjack/services/patterns/tool_output/other.py +97 -0
- crackerjack/services/patterns/tool_output/pyright.py +67 -0
- crackerjack/services/patterns/tool_output/ruff.py +44 -0
- crackerjack/services/patterns/url_sanitization.py +114 -0
- crackerjack/services/patterns/utilities.py +42 -0
- crackerjack/services/patterns/utils.py +339 -0
- crackerjack/services/patterns/validation.py +46 -0
- crackerjack/services/patterns/versioning.py +62 -0
- crackerjack/services/predictive_analytics.py +21 -8
- crackerjack/services/profiler.py +280 -0
- crackerjack/services/quality/README.md +415 -0
- crackerjack/services/quality/__init__.py +11 -0
- crackerjack/services/quality/anomaly_detector.py +392 -0
- crackerjack/services/quality/pattern_cache.py +333 -0
- crackerjack/services/quality/pattern_detector.py +479 -0
- crackerjack/services/quality/qa_orchestrator.py +491 -0
- crackerjack/services/{quality_baseline.py → quality/quality_baseline.py} +163 -2
- crackerjack/services/{quality_baseline_enhanced.py → quality/quality_baseline_enhanced.py} +4 -1
- crackerjack/services/{quality_intelligence.py → quality/quality_intelligence.py} +180 -16
- crackerjack/services/regex_patterns.py +58 -2987
- crackerjack/services/regex_utils.py +55 -29
- crackerjack/services/secure_status_formatter.py +42 -15
- crackerjack/services/secure_subprocess.py +35 -2
- crackerjack/services/security.py +16 -8
- crackerjack/services/server_manager.py +40 -51
- crackerjack/services/smart_scheduling.py +46 -6
- crackerjack/services/status_authentication.py +3 -3
- crackerjack/services/thread_safe_status_collector.py +1 -0
- crackerjack/services/tool_filter.py +368 -0
- crackerjack/services/tool_version_service.py +9 -5
- crackerjack/services/unified_config.py +43 -351
- crackerjack/services/vector_store.py +689 -0
- crackerjack/services/version_analyzer.py +6 -4
- crackerjack/services/version_checker.py +14 -8
- crackerjack/services/zuban_lsp_service.py +5 -4
- crackerjack/slash_commands/README.md +11 -0
- crackerjack/slash_commands/init.md +2 -12
- crackerjack/slash_commands/run.md +84 -50
- crackerjack/tools/README.md +11 -0
- crackerjack/tools/__init__.py +30 -0
- crackerjack/tools/_git_utils.py +105 -0
- crackerjack/tools/check_added_large_files.py +139 -0
- crackerjack/tools/check_ast.py +105 -0
- crackerjack/tools/check_json.py +103 -0
- crackerjack/tools/check_jsonschema.py +297 -0
- crackerjack/tools/check_toml.py +103 -0
- crackerjack/tools/check_yaml.py +110 -0
- crackerjack/tools/codespell_wrapper.py +72 -0
- crackerjack/tools/end_of_file_fixer.py +202 -0
- crackerjack/tools/format_json.py +128 -0
- crackerjack/tools/mdformat_wrapper.py +114 -0
- crackerjack/tools/trailing_whitespace.py +198 -0
- crackerjack/tools/validate_regex_patterns.py +7 -3
- crackerjack/ui/README.md +11 -0
- crackerjack/ui/dashboard_renderer.py +28 -0
- crackerjack/ui/templates/README.md +11 -0
- crackerjack/utils/console_utils.py +13 -0
- crackerjack/utils/dependency_guard.py +230 -0
- crackerjack/utils/retry_utils.py +275 -0
- crackerjack/workflows/README.md +590 -0
- crackerjack/workflows/__init__.py +46 -0
- crackerjack/workflows/actions.py +811 -0
- crackerjack/workflows/auto_fix.py +444 -0
- crackerjack/workflows/container_builder.py +499 -0
- crackerjack/workflows/definitions.py +443 -0
- crackerjack/workflows/engine.py +177 -0
- crackerjack/workflows/event_bridge.py +242 -0
- {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/METADATA +678 -98
- crackerjack-0.45.2.dist-info/RECORD +478 -0
- {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
- crackerjack/managers/test_manager_backup.py +0 -1075
- crackerjack/mcp/tools/execution_tools_backup.py +0 -1011
- crackerjack/mixins/__init__.py +0 -3
- crackerjack/mixins/error_handling.py +0 -145
- crackerjack/services/config.py +0 -358
- crackerjack/ui/server_panels.py +0 -125
- crackerjack-0.37.9.dist-info/RECORD +0 -231
- /crackerjack/adapters/{rust_tool_adapter.py → lsp/_base.py} +0 -0
- /crackerjack/adapters/{lsp_client.py → lsp/_client.py} +0 -0
- {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/entry_points.txt +0 -0
- {crackerjack-0.37.9.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
"""Tool filtering for targeted execution.
|
|
2
|
+
|
|
3
|
+
Phase 10.3.3: Implements --tool and --changed-only filtering to run only
|
|
4
|
+
specific tools or limit execution to changed files.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import fnmatch
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from crackerjack.services.incremental_executor import IncrementalExecutor
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class FilterConfig:
|
|
16
|
+
"""Configuration for tool filtering."""
|
|
17
|
+
|
|
18
|
+
tool_name: str | None = None # Specific tool to run (--tool flag)
|
|
19
|
+
changed_only: bool = False # Run only on changed files (--changed-only flag)
|
|
20
|
+
file_patterns: list[str] = field(default_factory=list) # File glob patterns
|
|
21
|
+
exclude_patterns: list[str] = field(default_factory=list) # Exclusion patterns
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class FilterResult:
|
|
26
|
+
"""Result of applying filters."""
|
|
27
|
+
|
|
28
|
+
total_tools: int
|
|
29
|
+
filtered_tools: list[str]
|
|
30
|
+
skipped_tools: list[str]
|
|
31
|
+
total_files: int
|
|
32
|
+
filtered_files: list[Path]
|
|
33
|
+
skipped_files: list[Path]
|
|
34
|
+
filter_effectiveness: float # Percentage of items filtered out
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def tools_filtered_out(self) -> int:
|
|
38
|
+
"""Number of tools filtered out."""
|
|
39
|
+
return len(self.skipped_tools)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def files_filtered_out(self) -> int:
|
|
43
|
+
"""Number of files filtered out."""
|
|
44
|
+
return len(self.skipped_files)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ToolFilter:
|
|
48
|
+
"""Filters tool execution based on configuration."""
|
|
49
|
+
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
config: FilterConfig,
|
|
53
|
+
executor: IncrementalExecutor | None = None,
|
|
54
|
+
):
|
|
55
|
+
"""Initialize tool filter.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
config: Filter configuration
|
|
59
|
+
executor: Optional incremental executor for changed file detection
|
|
60
|
+
"""
|
|
61
|
+
self.config = config
|
|
62
|
+
self.executor = executor
|
|
63
|
+
|
|
64
|
+
def filter_tools(
|
|
65
|
+
self,
|
|
66
|
+
available_tools: list[str],
|
|
67
|
+
) -> FilterResult:
|
|
68
|
+
"""Filter list of tools based on configuration.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
available_tools: All available tools
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
FilterResult with filtered and skipped tools
|
|
75
|
+
"""
|
|
76
|
+
if self.config.tool_name:
|
|
77
|
+
# Filter to specific tool
|
|
78
|
+
if self.config.tool_name in available_tools:
|
|
79
|
+
filtered = [self.config.tool_name]
|
|
80
|
+
skipped = [t for t in available_tools if t != self.config.tool_name]
|
|
81
|
+
else:
|
|
82
|
+
# Tool not found - run nothing
|
|
83
|
+
filtered = []
|
|
84
|
+
skipped = available_tools.copy()
|
|
85
|
+
else:
|
|
86
|
+
# No tool filter - run all
|
|
87
|
+
filtered = available_tools.copy()
|
|
88
|
+
skipped = []
|
|
89
|
+
|
|
90
|
+
total_tools = len(available_tools)
|
|
91
|
+
effectiveness = (len(skipped) / total_tools * 100) if total_tools > 0 else 0.0
|
|
92
|
+
|
|
93
|
+
return FilterResult(
|
|
94
|
+
total_tools=total_tools,
|
|
95
|
+
filtered_tools=filtered,
|
|
96
|
+
skipped_tools=skipped,
|
|
97
|
+
total_files=0, # Updated by filter_files
|
|
98
|
+
filtered_files=[],
|
|
99
|
+
skipped_files=[],
|
|
100
|
+
filter_effectiveness=effectiveness,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def filter_files(
|
|
104
|
+
self,
|
|
105
|
+
tool_name: str,
|
|
106
|
+
all_files: list[Path],
|
|
107
|
+
) -> FilterResult:
|
|
108
|
+
"""Filter list of files based on configuration.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
tool_name: Name of the tool being run
|
|
112
|
+
all_files: All available files
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
FilterResult with filtered and skipped files
|
|
116
|
+
"""
|
|
117
|
+
filtered_files = all_files.copy()
|
|
118
|
+
skipped_files: list[Path] = []
|
|
119
|
+
|
|
120
|
+
# Apply changed-only filter
|
|
121
|
+
if self.config.changed_only and self.executor:
|
|
122
|
+
changed_files = self.executor.get_changed_files(tool_name, all_files)
|
|
123
|
+
skipped_files = [f for f in all_files if f not in changed_files]
|
|
124
|
+
filtered_files = changed_files
|
|
125
|
+
|
|
126
|
+
# Apply file pattern filters
|
|
127
|
+
if self.config.file_patterns:
|
|
128
|
+
pattern_filtered = self._apply_patterns(
|
|
129
|
+
filtered_files,
|
|
130
|
+
self.config.file_patterns,
|
|
131
|
+
include=True,
|
|
132
|
+
)
|
|
133
|
+
new_skipped = [f for f in filtered_files if f not in pattern_filtered]
|
|
134
|
+
skipped_files.extend(new_skipped)
|
|
135
|
+
filtered_files = pattern_filtered
|
|
136
|
+
|
|
137
|
+
# Apply exclude patterns
|
|
138
|
+
if self.config.exclude_patterns:
|
|
139
|
+
exclude_filtered = self._apply_patterns(
|
|
140
|
+
filtered_files,
|
|
141
|
+
self.config.exclude_patterns,
|
|
142
|
+
include=False,
|
|
143
|
+
)
|
|
144
|
+
new_skipped = [f for f in filtered_files if f not in exclude_filtered]
|
|
145
|
+
skipped_files.extend(new_skipped)
|
|
146
|
+
filtered_files = exclude_filtered
|
|
147
|
+
|
|
148
|
+
total_files = len(all_files)
|
|
149
|
+
effectiveness = (
|
|
150
|
+
(len(skipped_files) / total_files * 100) if total_files > 0 else 0.0
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
return FilterResult(
|
|
154
|
+
total_tools=1, # Single tool context
|
|
155
|
+
filtered_tools=[tool_name],
|
|
156
|
+
skipped_tools=[],
|
|
157
|
+
total_files=total_files,
|
|
158
|
+
filtered_files=filtered_files,
|
|
159
|
+
skipped_files=skipped_files,
|
|
160
|
+
filter_effectiveness=effectiveness,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
def _apply_patterns(
|
|
164
|
+
self,
|
|
165
|
+
files: list[Path],
|
|
166
|
+
patterns: list[str],
|
|
167
|
+
include: bool,
|
|
168
|
+
) -> list[Path]:
|
|
169
|
+
"""Apply glob patterns to filter files.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
files: Files to filter
|
|
173
|
+
patterns: Glob patterns to apply
|
|
174
|
+
include: If True, include matching files; if False, exclude them
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
Filtered file list
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
matching_files: set[Path] = set()
|
|
181
|
+
|
|
182
|
+
for pattern in patterns:
|
|
183
|
+
for file in files:
|
|
184
|
+
# Match against file name and full path
|
|
185
|
+
if fnmatch.fnmatch(file.name, pattern) or fnmatch.fnmatch(
|
|
186
|
+
str(file), pattern
|
|
187
|
+
):
|
|
188
|
+
matching_files.add(file)
|
|
189
|
+
|
|
190
|
+
if include:
|
|
191
|
+
# Include only matching files
|
|
192
|
+
return [f for f in files if f in matching_files]
|
|
193
|
+
|
|
194
|
+
# Exclude matching files
|
|
195
|
+
return [f for f in files if f not in matching_files]
|
|
196
|
+
|
|
197
|
+
def should_run_tool(self, tool_name: str) -> bool:
|
|
198
|
+
"""Check if a specific tool should run.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
tool_name: Name of the tool
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
True if tool should run
|
|
205
|
+
"""
|
|
206
|
+
if self.config.tool_name is None:
|
|
207
|
+
# No filter - run all tools
|
|
208
|
+
return True
|
|
209
|
+
|
|
210
|
+
# Check if this is the selected tool
|
|
211
|
+
return tool_name == self.config.tool_name
|
|
212
|
+
|
|
213
|
+
def get_filtered_files(
|
|
214
|
+
self,
|
|
215
|
+
tool_name: str,
|
|
216
|
+
all_files: list[Path],
|
|
217
|
+
) -> list[Path]:
|
|
218
|
+
"""Get filtered file list for a tool.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
tool_name: Name of the tool
|
|
222
|
+
all_files: All available files
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
Filtered file list
|
|
226
|
+
"""
|
|
227
|
+
result = self.filter_files(tool_name, all_files)
|
|
228
|
+
return result.filtered_files
|
|
229
|
+
|
|
230
|
+
def estimate_time_savings(
|
|
231
|
+
self,
|
|
232
|
+
tool_execution_times: dict[str, float],
|
|
233
|
+
file_execution_time_per_file: float = 0.1,
|
|
234
|
+
) -> dict[str, float]:
|
|
235
|
+
"""Estimate time savings from filtering.
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
tool_execution_times: Dict mapping tool names to execution times
|
|
239
|
+
file_execution_time_per_file: Average time per file (seconds)
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Dictionary with time savings statistics
|
|
243
|
+
"""
|
|
244
|
+
if not self.config.tool_name and not self.config.changed_only:
|
|
245
|
+
# No filtering - no savings
|
|
246
|
+
return {
|
|
247
|
+
"total_time_baseline": sum(tool_execution_times.values()),
|
|
248
|
+
"total_time_filtered": sum(tool_execution_times.values()),
|
|
249
|
+
"time_saved": 0.0,
|
|
250
|
+
"percent_saved": 0.0,
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# Calculate baseline time (all tools)
|
|
254
|
+
baseline_time = sum(tool_execution_times.values())
|
|
255
|
+
|
|
256
|
+
# Calculate filtered time
|
|
257
|
+
if self.config.tool_name:
|
|
258
|
+
# Only one tool runs
|
|
259
|
+
filtered_time = tool_execution_times.get(self.config.tool_name, 0.0)
|
|
260
|
+
else:
|
|
261
|
+
# All tools run (but maybe on fewer files)
|
|
262
|
+
filtered_time = baseline_time
|
|
263
|
+
|
|
264
|
+
time_saved = baseline_time - filtered_time
|
|
265
|
+
percent_saved = (time_saved / baseline_time * 100) if baseline_time > 0 else 0.0
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
"total_time_baseline": baseline_time,
|
|
269
|
+
"total_time_filtered": filtered_time,
|
|
270
|
+
"time_saved": time_saved,
|
|
271
|
+
"percent_saved": percent_saved,
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
def generate_filter_summary(
|
|
275
|
+
self,
|
|
276
|
+
tool_result: FilterResult | None = None,
|
|
277
|
+
file_result: FilterResult | None = None,
|
|
278
|
+
) -> str:
|
|
279
|
+
"""Generate human-readable filter summary.
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
tool_result: Optional tool filtering result
|
|
283
|
+
file_result: Optional file filtering result
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
Formatted summary string
|
|
287
|
+
"""
|
|
288
|
+
lines = ["# Filter Summary", ""]
|
|
289
|
+
|
|
290
|
+
if tool_result:
|
|
291
|
+
lines.extend(
|
|
292
|
+
[
|
|
293
|
+
"## Tool Filtering",
|
|
294
|
+
f"- Total Tools: {tool_result.total_tools}",
|
|
295
|
+
f"- Tools to Run: {len(tool_result.filtered_tools)}",
|
|
296
|
+
f"- Tools Skipped: {len(tool_result.skipped_tools)}",
|
|
297
|
+
f"- Effectiveness: {tool_result.filter_effectiveness:.1f}%",
|
|
298
|
+
"",
|
|
299
|
+
]
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
if tool_result.filtered_tools:
|
|
303
|
+
lines.append("**Running:**")
|
|
304
|
+
for tool in tool_result.filtered_tools:
|
|
305
|
+
lines.append(f" - {tool}")
|
|
306
|
+
lines.append("")
|
|
307
|
+
|
|
308
|
+
if file_result:
|
|
309
|
+
lines.extend(
|
|
310
|
+
[
|
|
311
|
+
"## File Filtering",
|
|
312
|
+
f"- Total Files: {file_result.total_files}",
|
|
313
|
+
f"- Files to Process: {len(file_result.filtered_files)}",
|
|
314
|
+
f"- Files Skipped: {len(file_result.skipped_files)}",
|
|
315
|
+
f"- Effectiveness: {file_result.filter_effectiveness:.1f}%",
|
|
316
|
+
"",
|
|
317
|
+
]
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
return "\n".join(lines)
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
# Convenience functions for common filtering scenarios
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def create_tool_only_filter(tool_name: str) -> ToolFilter:
|
|
327
|
+
"""Create filter for running a single tool.
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
tool_name: Name of the tool to run
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
Configured ToolFilter
|
|
334
|
+
"""
|
|
335
|
+
config = FilterConfig(tool_name=tool_name)
|
|
336
|
+
return ToolFilter(config=config)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def create_changed_files_filter(
|
|
340
|
+
executor: IncrementalExecutor,
|
|
341
|
+
) -> ToolFilter:
|
|
342
|
+
"""Create filter for running only on changed files.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
executor: IncrementalExecutor for change detection
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
Configured ToolFilter
|
|
349
|
+
"""
|
|
350
|
+
config = FilterConfig(changed_only=True)
|
|
351
|
+
return ToolFilter(config=config, executor=executor)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def create_combined_filter(
|
|
355
|
+
tool_name: str,
|
|
356
|
+
executor: IncrementalExecutor,
|
|
357
|
+
) -> ToolFilter:
|
|
358
|
+
"""Create filter for specific tool on changed files only.
|
|
359
|
+
|
|
360
|
+
Args:
|
|
361
|
+
tool_name: Name of the tool to run
|
|
362
|
+
executor: IncrementalExecutor for change detection
|
|
363
|
+
|
|
364
|
+
Returns:
|
|
365
|
+
Configured ToolFilter
|
|
366
|
+
"""
|
|
367
|
+
config = FilterConfig(tool_name=tool_name, changed_only=True)
|
|
368
|
+
return ToolFilter(config=config, executor=executor)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from acb.console import Console
|
|
4
|
+
from acb.depends import Inject, depends
|
|
4
5
|
|
|
5
6
|
from .config_integrity import ConfigIntegrityService
|
|
6
7
|
from .smart_scheduling import SmartSchedulingService
|
|
@@ -15,13 +16,16 @@ __all__ = [
|
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class ToolVersionService:
|
|
18
|
-
|
|
19
|
+
@depends.inject
|
|
20
|
+
def __init__(
|
|
21
|
+
self, console: Inject[Console], project_path: Path | None = None
|
|
22
|
+
) -> None:
|
|
19
23
|
self.console = console
|
|
20
24
|
self.project_path = project_path or Path.cwd()
|
|
21
25
|
|
|
22
|
-
self._version_checker = VersionChecker(
|
|
23
|
-
self._config_integrity = ConfigIntegrityService(
|
|
24
|
-
self._scheduling = SmartSchedulingService(
|
|
26
|
+
self._version_checker = VersionChecker()
|
|
27
|
+
self._config_integrity = ConfigIntegrityService(self.project_path)
|
|
28
|
+
self._scheduling = SmartSchedulingService(self.project_path)
|
|
25
29
|
|
|
26
30
|
async def check_tool_updates(self) -> dict[str, VersionInfo]:
|
|
27
31
|
return await self._version_checker.check_tool_updates()
|