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,18 @@
|
|
|
1
|
+
# Adapters
|
|
2
|
+
|
|
3
|
+
Interfaces and adapters to external tools/services or subsystems. Each adapter follows ACB-style patterns with typed settings, async initialization, and standardized results.
|
|
4
|
+
|
|
5
|
+
## Index
|
|
6
|
+
|
|
7
|
+
- [AI](<./ai/README.md>) — Claude-powered code fixing and AI helpers
|
|
8
|
+
- [Complexity](<./complexity/README.md>) — Code complexity analysis (Complexipy)
|
|
9
|
+
- [Format](<./format/README.md>) — Code and docs formatting (Ruff, Mdformat)
|
|
10
|
+
- [Lint](<./lint/README.md>) — Spelling and simple linters (Codespell)
|
|
11
|
+
- [LSP](<./lsp/README.md>) — Rust tools with LSP (Zuban, Skylos)
|
|
12
|
+
- [Refactor](<./refactor/README.md>) — Modernization and dead-code (Refurb, Creosote, Skylos)
|
|
13
|
+
- [SAST](<./sast/README.md>) — Static application security testing (Semgrep, Bandit, Pyscn)
|
|
14
|
+
- [Security](<./security/README.md>) — Secret leak prevention and credential detection (Gitleaks)
|
|
15
|
+
- [Type](<./type/README.md>) — Static type checking (Zuban, Pyrefly, Ty)
|
|
16
|
+
- [Utility](<./utility/README.md>) — Small config-driven checks (EOF newline, regex, size)
|
|
17
|
+
|
|
18
|
+
See `crackerjack/models/qa_config.py` and `crackerjack/models/qa_results.py` for configuration and result schemas used across adapters.
|
crackerjack/adapters/__init__.py
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
|
-
"""Rust tool adapters for unified integration.
|
|
1
|
+
"""Rust tool adapters for unified integration.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
QA Framework Adapters:
|
|
4
|
+
The QA framework adapters are organized by check type in subdirectories:
|
|
5
|
+
- format/: Code formatting (ruff, mdformat)
|
|
6
|
+
- lint/: Code linting (codespell)
|
|
7
|
+
- security/: Security scanning (bandit, gitleaks)
|
|
8
|
+
- type/: Type checking (zuban)
|
|
9
|
+
- refactor/: Refactoring suggestions (refurb, creosote)
|
|
10
|
+
- complexity/: Complexity analysis (complexipy)
|
|
11
|
+
- utility/: Utility checks (text patterns, EOF, syntax, size, deps)
|
|
12
|
+
- shared/: Base classes for all QA adapters
|
|
13
|
+
|
|
14
|
+
ACB 0.19.0+ auto-discovers adapters via depends.set() at module level.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from .lsp._base import (
|
|
18
|
+
Issue,
|
|
19
|
+
RustToolAdapter,
|
|
20
|
+
ToolResult,
|
|
21
|
+
)
|
|
22
|
+
from .lsp._manager import RustToolHookManager
|
|
23
|
+
from .lsp.skylos import DeadCodeIssue, SkylosAdapter
|
|
24
|
+
from .lsp.zuban import TypeIssue, ZubanAdapter
|
|
25
|
+
|
|
26
|
+
# NOTE: ACB 0.19.0+ uses depends.set() for adapter registration at module level
|
|
27
|
+
# AI adapter registration moved to crackerjack.adapters.ai.claude module
|
|
28
|
+
# QA adapters are auto-discovered from their category subdirectories
|
|
7
29
|
|
|
8
30
|
__all__ = [
|
|
9
31
|
"RustToolAdapter",
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"""Centralized output path management for adapter files.
|
|
2
|
+
|
|
3
|
+
This module provides utilities for managing adapter output files in a centralized
|
|
4
|
+
location (.crackerjack/outputs/) to keep the project root clean.
|
|
5
|
+
|
|
6
|
+
ACB Patterns:
|
|
7
|
+
- Pure utility module (no DI registration needed)
|
|
8
|
+
- Simple, focused responsibility
|
|
9
|
+
- Consistent path management across all adapters
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from datetime import datetime
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AdapterOutputPaths:
|
|
22
|
+
"""Centralized path manager for adapter output files.
|
|
23
|
+
|
|
24
|
+
All adapter output files (JSON results, logs, temporary files) are stored in:
|
|
25
|
+
.crackerjack/outputs/
|
|
26
|
+
|
|
27
|
+
This keeps the project root clean and makes it easy to:
|
|
28
|
+
- Add to .gitignore
|
|
29
|
+
- Clean up old files
|
|
30
|
+
- Find all adapter outputs in one place
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
# Base directory for all adapter outputs
|
|
34
|
+
OUTPUTS_DIR = ".crackerjack/outputs"
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def get_output_dir(cls, adapter_name: str | None = None) -> Path:
|
|
38
|
+
"""Get the output directory for an adapter.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
adapter_name: Optional adapter-specific subdirectory
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Path to output directory (created if doesn't exist)
|
|
45
|
+
"""
|
|
46
|
+
base_dir = Path.cwd() / cls.OUTPUTS_DIR
|
|
47
|
+
|
|
48
|
+
if adapter_name:
|
|
49
|
+
output_dir = base_dir / adapter_name
|
|
50
|
+
else:
|
|
51
|
+
output_dir = base_dir
|
|
52
|
+
|
|
53
|
+
# Create directory if it doesn't exist
|
|
54
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
55
|
+
|
|
56
|
+
return output_dir
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def get_output_file(
|
|
60
|
+
cls,
|
|
61
|
+
adapter_name: str,
|
|
62
|
+
filename: str,
|
|
63
|
+
timestamped: bool = False,
|
|
64
|
+
) -> Path:
|
|
65
|
+
"""Get path for an adapter output file.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
adapter_name: Name of the adapter (e.g., 'complexipy', 'bandit')
|
|
69
|
+
filename: Base filename (e.g., 'results.json')
|
|
70
|
+
timestamped: If True, add timestamp to filename
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Full path to output file in .crackerjack/outputs/adapter_name/
|
|
74
|
+
|
|
75
|
+
Examples:
|
|
76
|
+
>>> AdapterOutputPaths.get_output_file("complexipy", "results.json")
|
|
77
|
+
PosixPath('.crackerjack/outputs/complexipy/results.json')
|
|
78
|
+
|
|
79
|
+
>>> AdapterOutputPaths.get_output_file(
|
|
80
|
+
... "bandit", "scan.json", timestamped=True
|
|
81
|
+
... )
|
|
82
|
+
PosixPath('.crackerjack/outputs/bandit/scan_2025_12_09__12:34:56.json')
|
|
83
|
+
"""
|
|
84
|
+
output_dir = cls.get_output_dir(adapter_name)
|
|
85
|
+
|
|
86
|
+
if timestamped:
|
|
87
|
+
# Add timestamp before extension
|
|
88
|
+
stem = Path(filename).stem
|
|
89
|
+
suffix = Path(filename).suffix
|
|
90
|
+
timestamp = datetime.now().strftime("%Y_%m_%d__%H:%M:%S")
|
|
91
|
+
filename = f"{stem}_{timestamp}{suffix}"
|
|
92
|
+
|
|
93
|
+
return output_dir / filename
|
|
94
|
+
|
|
95
|
+
@classmethod
|
|
96
|
+
def get_latest_output(
|
|
97
|
+
cls, adapter_name: str, pattern: str = "*.json"
|
|
98
|
+
) -> Path | None:
|
|
99
|
+
"""Get the most recently modified output file for an adapter.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
adapter_name: Name of the adapter
|
|
103
|
+
pattern: Glob pattern for files (default: *.json)
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
Path to most recent file, or None if no files found
|
|
107
|
+
"""
|
|
108
|
+
output_dir = cls.get_output_dir(adapter_name)
|
|
109
|
+
|
|
110
|
+
if not output_dir.exists():
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
files = sorted(
|
|
114
|
+
output_dir.glob(pattern),
|
|
115
|
+
key=lambda p: p.stat().st_mtime,
|
|
116
|
+
reverse=True,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
return files[0] if files else None
|
|
120
|
+
|
|
121
|
+
@classmethod
|
|
122
|
+
def cleanup_old_outputs(
|
|
123
|
+
cls,
|
|
124
|
+
adapter_name: str,
|
|
125
|
+
pattern: str = "*.json",
|
|
126
|
+
keep_latest: int = 5,
|
|
127
|
+
) -> int:
|
|
128
|
+
"""Remove old output files, keeping only the most recent ones.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
adapter_name: Name of the adapter
|
|
132
|
+
pattern: Glob pattern for files (default: *.json)
|
|
133
|
+
keep_latest: Number of most recent files to keep
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
Number of files deleted
|
|
137
|
+
"""
|
|
138
|
+
output_dir = cls.get_output_dir(adapter_name)
|
|
139
|
+
|
|
140
|
+
if not output_dir.exists():
|
|
141
|
+
return 0
|
|
142
|
+
|
|
143
|
+
files = sorted(
|
|
144
|
+
output_dir.glob(pattern),
|
|
145
|
+
key=lambda p: p.stat().st_mtime,
|
|
146
|
+
reverse=True,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# Keep the N most recent files, delete the rest
|
|
150
|
+
files_to_delete = files[keep_latest:]
|
|
151
|
+
deleted_count = 0
|
|
152
|
+
|
|
153
|
+
for file_path in files_to_delete:
|
|
154
|
+
try:
|
|
155
|
+
file_path.unlink()
|
|
156
|
+
deleted_count += 1
|
|
157
|
+
logger.debug(f"Deleted old output file: {file_path}")
|
|
158
|
+
except OSError as e:
|
|
159
|
+
logger.warning(f"Failed to delete {file_path}: {e}")
|
|
160
|
+
|
|
161
|
+
if deleted_count > 0:
|
|
162
|
+
logger.info(
|
|
163
|
+
f"Cleaned up {deleted_count} old {adapter_name} output files, "
|
|
164
|
+
f"kept {keep_latest} most recent"
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
return deleted_count
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"""Base adapter for ACB Quality Assurance framework.
|
|
2
|
+
|
|
3
|
+
This module provides the foundational classes and protocols for implementing
|
|
4
|
+
QA checks as ACB adapters following ACB 0.19.0+ patterns.
|
|
5
|
+
|
|
6
|
+
Key ACB Patterns:
|
|
7
|
+
- MODULE_ID and MODULE_STATUS are module-level constants in concrete adapters
|
|
8
|
+
- Dependency injection via module-level depends.set() after class definition
|
|
9
|
+
- Runtime-checkable protocols for type safety
|
|
10
|
+
- Concrete base class for shared implementation
|
|
11
|
+
- Settings extend acb.config.Settings with validators
|
|
12
|
+
- Async init() method for lazy initialization
|
|
13
|
+
|
|
14
|
+
CRITICAL: Imports protocols from models.protocols, not local definitions.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import asyncio
|
|
20
|
+
import typing as t
|
|
21
|
+
from contextlib import asynccontextmanager
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
from acb.config import Settings
|
|
25
|
+
from pydantic import Field, field_validator
|
|
26
|
+
|
|
27
|
+
# Import protocol from models.protocols per crackerjack pattern
|
|
28
|
+
from crackerjack.models.protocols import QAAdapterProtocol
|
|
29
|
+
|
|
30
|
+
if t.TYPE_CHECKING:
|
|
31
|
+
from uuid import UUID
|
|
32
|
+
|
|
33
|
+
from crackerjack.models.qa_config import QACheckConfig
|
|
34
|
+
from crackerjack.models.qa_results import QAResult
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class QABaseSettings(Settings):
|
|
38
|
+
"""Base settings for quality assurance adapters.
|
|
39
|
+
|
|
40
|
+
All QA adapter settings should inherit from this class to ensure
|
|
41
|
+
consistent configuration patterns across all checks.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
enabled: bool = True
|
|
45
|
+
timeout_seconds: int = Field(300, ge=1, le=7200)
|
|
46
|
+
file_patterns: list[str] = Field(default_factory=lambda: ["**/*.py"])
|
|
47
|
+
exclude_patterns: list[str] = Field(default_factory=list)
|
|
48
|
+
fail_on_error: bool = True
|
|
49
|
+
verbose: bool = False
|
|
50
|
+
cache_enabled: bool = True
|
|
51
|
+
cache_ttl: int = 3600
|
|
52
|
+
max_workers: int = Field(4, ge=1, le=16)
|
|
53
|
+
|
|
54
|
+
@field_validator("timeout_seconds")
|
|
55
|
+
@classmethod
|
|
56
|
+
def validate_timeout(cls, v: int) -> int:
|
|
57
|
+
"""Validate timeout is within reasonable bounds."""
|
|
58
|
+
if v < 1 or v > 3600:
|
|
59
|
+
raise ValueError("Timeout must be between 1 and 3600 seconds")
|
|
60
|
+
return v
|
|
61
|
+
|
|
62
|
+
@field_validator("max_workers")
|
|
63
|
+
@classmethod
|
|
64
|
+
def validate_workers(cls, v: int) -> int:
|
|
65
|
+
"""Validate worker count is reasonable."""
|
|
66
|
+
if v < 1 or v > 16:
|
|
67
|
+
raise ValueError("Max workers must be between 1 and 16")
|
|
68
|
+
return v
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# QAAdapterProtocol is imported from models.protocols per crackerjack pattern
|
|
72
|
+
# See crackerjack/models/protocols.py for protocol definition
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
from acb.adapters import AdapterMetadata
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class QAAdapterBase:
|
|
79
|
+
"""Concrete base class for quality assurance adapters.
|
|
80
|
+
|
|
81
|
+
Provides shared implementation for all QA adapters following ACB patterns.
|
|
82
|
+
Unlike traditional abstract base classes, this is concrete and provides
|
|
83
|
+
default implementations where sensible.
|
|
84
|
+
|
|
85
|
+
IMPORTANT ACB Patterns:
|
|
86
|
+
- MODULE_ID must be defined at module level in concrete adapters (not here)
|
|
87
|
+
- depends.set() registration happens at module level after class definition
|
|
88
|
+
- Use async init() for lazy initialization, not __init__
|
|
89
|
+
- Subclasses override specific methods as needed
|
|
90
|
+
|
|
91
|
+
Example:
|
|
92
|
+
```python
|
|
93
|
+
# In concrete adapter file (e.g., ruff_lint.py)
|
|
94
|
+
import uuid
|
|
95
|
+
from contextlib import suppress
|
|
96
|
+
from acb.depends import depends
|
|
97
|
+
from crackerjack.adapters.qa.base import QAAdapterBase, QABaseSettings
|
|
98
|
+
|
|
99
|
+
# MODULE_ID at module level (REQUIRED by ACB)
|
|
100
|
+
MODULE_ID = uuid.UUID("01937d86-5f2a-7b3c-9d1e-a2b3c4d5e6f7")
|
|
101
|
+
MODULE_STATUS = "stable"
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class RuffLintSettings(QABaseSettings):
|
|
105
|
+
select_rules: list[str] = []
|
|
106
|
+
ignore_rules: list[str] = []
|
|
107
|
+
fix_enabled: bool = False
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class RuffLintAdapter(QAAdapterBase):
|
|
111
|
+
settings: RuffLintSettings | None = None
|
|
112
|
+
|
|
113
|
+
async def init(self) -> None:
|
|
114
|
+
if not self.settings:
|
|
115
|
+
self.settings = RuffLintSettings()
|
|
116
|
+
await super().init()
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def adapter_name(self) -> str:
|
|
120
|
+
return "Ruff Linter"
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def module_id(self) -> uuid.UUID:
|
|
124
|
+
return MODULE_ID
|
|
125
|
+
|
|
126
|
+
async def check(self, files=None, config=None):
|
|
127
|
+
# Implementation here
|
|
128
|
+
return QAResult(...)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# Register at module level (REQUIRED by ACB)
|
|
132
|
+
with suppress(Exception):
|
|
133
|
+
depends.set(RuffLintAdapter)
|
|
134
|
+
```
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
settings: QABaseSettings | None = None
|
|
138
|
+
metadata: AdapterMetadata | None = None
|
|
139
|
+
|
|
140
|
+
def __init__(self) -> None:
|
|
141
|
+
"""Initialize adapter instance.
|
|
142
|
+
|
|
143
|
+
Note: ACB pattern is to do minimal work here. Use async init()
|
|
144
|
+
for expensive setup operations.
|
|
145
|
+
"""
|
|
146
|
+
self._initialized = False
|
|
147
|
+
self._semaphore: asyncio.Semaphore | None = None
|
|
148
|
+
|
|
149
|
+
async def init(self) -> None:
|
|
150
|
+
"""ACB standard initialization method.
|
|
151
|
+
|
|
152
|
+
Called lazily before first check. Override in subclasses to:
|
|
153
|
+
- Load settings
|
|
154
|
+
- Setup async resources
|
|
155
|
+
- Initialize clients/connections
|
|
156
|
+
- Validate configuration
|
|
157
|
+
"""
|
|
158
|
+
if not self.settings:
|
|
159
|
+
self.settings = QABaseSettings()
|
|
160
|
+
|
|
161
|
+
# Create semaphore for concurrency control
|
|
162
|
+
max_workers = self.settings.max_workers
|
|
163
|
+
self._semaphore = asyncio.Semaphore(max_workers)
|
|
164
|
+
|
|
165
|
+
self._initialized = True
|
|
166
|
+
|
|
167
|
+
@property
|
|
168
|
+
def adapter_name(self) -> str:
|
|
169
|
+
"""Human-readable adapter name.
|
|
170
|
+
|
|
171
|
+
Override in subclasses for better identification.
|
|
172
|
+
"""
|
|
173
|
+
return self.__class__.__name__
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def module_id(self) -> UUID:
|
|
177
|
+
"""Reference to module-level MODULE_ID.
|
|
178
|
+
|
|
179
|
+
Must be overridden in concrete adapters to return the
|
|
180
|
+
module-level MODULE_ID constant.
|
|
181
|
+
"""
|
|
182
|
+
raise NotImplementedError(
|
|
183
|
+
f"{self.__class__.__name__} must implement module_id property "
|
|
184
|
+
"that returns the module-level MODULE_ID constant"
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
async def check(
|
|
188
|
+
self,
|
|
189
|
+
files: list[Path] | None = None,
|
|
190
|
+
config: QACheckConfig | None = None,
|
|
191
|
+
) -> QAResult:
|
|
192
|
+
"""Execute the quality assurance check.
|
|
193
|
+
|
|
194
|
+
Must be overridden in concrete adapters.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
files: List of files to check (None = check all files matching patterns)
|
|
198
|
+
config: Optional configuration override for this check
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
QAResult containing the check execution results
|
|
202
|
+
"""
|
|
203
|
+
raise NotImplementedError(
|
|
204
|
+
f"{self.__class__.__name__} must implement check() method"
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
async def validate_config(self, config: QACheckConfig) -> bool:
|
|
208
|
+
"""Validate configuration.
|
|
209
|
+
|
|
210
|
+
Default implementation provides basic validation.
|
|
211
|
+
Override for adapter-specific validation.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
config: Configuration to validate
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
True if configuration is valid, False otherwise
|
|
218
|
+
"""
|
|
219
|
+
return config is not None
|
|
220
|
+
|
|
221
|
+
def get_default_config(self) -> QACheckConfig:
|
|
222
|
+
"""Get default configuration.
|
|
223
|
+
|
|
224
|
+
Must be overridden in concrete adapters.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
QACheckConfig with sensible defaults for this check
|
|
228
|
+
"""
|
|
229
|
+
raise NotImplementedError(
|
|
230
|
+
f"{self.__class__.__name__} must implement get_default_config() method"
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
async def health_check(self) -> dict[str, t.Any]:
|
|
234
|
+
"""ACB standard health check method.
|
|
235
|
+
|
|
236
|
+
Provides basic health status. Override for more detailed checks.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
Dictionary with health status and metadata
|
|
240
|
+
"""
|
|
241
|
+
return {
|
|
242
|
+
"status": "healthy" if self._initialized else "not_initialized",
|
|
243
|
+
"adapter": self.adapter_name,
|
|
244
|
+
"module_id": str(self.module_id) if self._initialized else "unknown",
|
|
245
|
+
"settings_loaded": self.settings is not None,
|
|
246
|
+
"metadata": self.metadata.dict() if self.metadata else None,
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
def _should_check_file(self, file_path: Path, config: QACheckConfig) -> bool:
|
|
250
|
+
"""Determine if a file should be checked based on patterns.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
file_path: Path to the file
|
|
254
|
+
config: Configuration containing file patterns
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
True if file should be checked, False otherwise
|
|
258
|
+
"""
|
|
259
|
+
# Check if file matches any include patterns
|
|
260
|
+
matches_include = any(
|
|
261
|
+
file_path.match(pattern) for pattern in config.file_patterns
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
if not matches_include:
|
|
265
|
+
return False
|
|
266
|
+
|
|
267
|
+
# Check if file matches any exclude patterns
|
|
268
|
+
matches_exclude = any(
|
|
269
|
+
file_path.match(pattern) for pattern in config.exclude_patterns
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
return not matches_exclude
|
|
273
|
+
|
|
274
|
+
@asynccontextmanager
|
|
275
|
+
async def _lifecycle(self) -> t.AsyncIterator[QAAdapterBase]:
|
|
276
|
+
"""ACB pattern for resource lifecycle management.
|
|
277
|
+
|
|
278
|
+
Use this context manager for proper setup/teardown:
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
async with adapter._lifecycle():
|
|
282
|
+
result = await adapter.check(files)
|
|
283
|
+
```
|
|
284
|
+
"""
|
|
285
|
+
try:
|
|
286
|
+
if not self._initialized:
|
|
287
|
+
await self.init()
|
|
288
|
+
yield self
|
|
289
|
+
finally:
|
|
290
|
+
await self._cleanup()
|
|
291
|
+
|
|
292
|
+
async def _cleanup(self) -> None:
|
|
293
|
+
"""Cleanup async resources.
|
|
294
|
+
|
|
295
|
+
Override in subclasses to clean up:
|
|
296
|
+
- Close connections
|
|
297
|
+
- Release resources
|
|
298
|
+
- Flush caches
|
|
299
|
+
"""
|
|
300
|
+
# Base implementation - subclasses can extend
|
|
301
|
+
self._semaphore = None
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
# Export the main classes and protocol
|
|
305
|
+
__all__ = [
|
|
306
|
+
"QAAdapterBase",
|
|
307
|
+
"QAAdapterProtocol",
|
|
308
|
+
"QABaseSettings",
|
|
309
|
+
]
|