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
crackerjack/models/protocols.py
CHANGED
|
@@ -2,6 +2,63 @@ import subprocess
|
|
|
2
2
|
import typing as t
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
+
from crackerjack.config.hooks import HookDefinition
|
|
6
|
+
from crackerjack.config.settings import CrackerjackSettings
|
|
7
|
+
from crackerjack.models.results import ExecutionResult, ParallelExecutionResult
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@t.runtime_checkable
|
|
11
|
+
class ServiceProtocol(t.Protocol):
|
|
12
|
+
"""Base protocol for ACB services with standardized lifecycle methods."""
|
|
13
|
+
|
|
14
|
+
def initialize(self) -> None:
|
|
15
|
+
"""Initialize service with proper lifecycle management."""
|
|
16
|
+
...
|
|
17
|
+
|
|
18
|
+
def cleanup(self) -> None:
|
|
19
|
+
"""Cleanup service resources."""
|
|
20
|
+
...
|
|
21
|
+
|
|
22
|
+
def health_check(self) -> bool:
|
|
23
|
+
"""Perform health check for service."""
|
|
24
|
+
...
|
|
25
|
+
|
|
26
|
+
def shutdown(self) -> None:
|
|
27
|
+
"""Shutdown service gracefully."""
|
|
28
|
+
...
|
|
29
|
+
|
|
30
|
+
def metrics(self) -> dict[str, t.Any]:
|
|
31
|
+
"""Get service metrics."""
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
def is_healthy(self) -> bool:
|
|
35
|
+
"""Check if service is healthy."""
|
|
36
|
+
...
|
|
37
|
+
|
|
38
|
+
def register_resource(self, resource: t.Any) -> None:
|
|
39
|
+
"""Register resource for cleanup."""
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
def cleanup_resource(self, resource: t.Any) -> None:
|
|
43
|
+
"""Cleanup specific resource."""
|
|
44
|
+
...
|
|
45
|
+
|
|
46
|
+
def record_error(self, error: Exception) -> None:
|
|
47
|
+
"""Record service error for monitoring."""
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
def increment_requests(self) -> None:
|
|
51
|
+
"""Increment request counter."""
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
def get_custom_metric(self, name: str) -> t.Any:
|
|
55
|
+
"""Get custom service metric."""
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
def set_custom_metric(self, name: str, value: t.Any) -> None:
|
|
59
|
+
"""Set custom service metric."""
|
|
60
|
+
...
|
|
61
|
+
|
|
5
62
|
|
|
6
63
|
@t.runtime_checkable
|
|
7
64
|
class CommandRunner(t.Protocol):
|
|
@@ -44,7 +101,10 @@ class OptionsProtocol(t.Protocol):
|
|
|
44
101
|
track_progress: bool = False
|
|
45
102
|
fast: bool = False
|
|
46
103
|
comp: bool = False
|
|
47
|
-
|
|
104
|
+
fast_iteration: bool = False
|
|
105
|
+
tool: str | None = None
|
|
106
|
+
changed_only: bool = False
|
|
107
|
+
advanced_batch: str | None = None
|
|
48
108
|
monitor_dashboard: str | None = None
|
|
49
109
|
skip_config_merge: bool = False
|
|
50
110
|
disable_global_locks: bool = False
|
|
@@ -83,10 +143,19 @@ class GitInterface(t.Protocol):
|
|
|
83
143
|
|
|
84
144
|
def get_staged_files(self) -> list[str]: ...
|
|
85
145
|
|
|
146
|
+
def get_changed_files_by_extension(
|
|
147
|
+
self,
|
|
148
|
+
extensions: list[str],
|
|
149
|
+
include_staged: bool = True,
|
|
150
|
+
include_unstaged: bool = True,
|
|
151
|
+
) -> list[Path]: ...
|
|
152
|
+
|
|
86
153
|
def commit(self, message: str) -> bool: ...
|
|
87
154
|
|
|
88
155
|
def push(self) -> bool: ...
|
|
89
156
|
|
|
157
|
+
def push_with_tags(self) -> bool: ...
|
|
158
|
+
|
|
90
159
|
def add_files(self, files: list[str]) -> bool: ...
|
|
91
160
|
|
|
92
161
|
def add_all_files(self) -> bool: ...
|
|
@@ -95,6 +164,10 @@ class GitInterface(t.Protocol):
|
|
|
95
164
|
|
|
96
165
|
def get_unpushed_commit_count(self) -> int: ...
|
|
97
166
|
|
|
167
|
+
def get_current_commit_hash(self) -> str | None: ...
|
|
168
|
+
|
|
169
|
+
def reset_hard(self, commit_hash: str) -> bool: ...
|
|
170
|
+
|
|
98
171
|
|
|
99
172
|
@t.runtime_checkable
|
|
100
173
|
class HookManager(t.Protocol):
|
|
@@ -121,7 +194,7 @@ class SecurityAwareHookManager(HookManager, t.Protocol):
|
|
|
121
194
|
|
|
122
195
|
|
|
123
196
|
@t.runtime_checkable
|
|
124
|
-
class CoverageRatchetProtocol(t.Protocol):
|
|
197
|
+
class CoverageRatchetProtocol(ServiceProtocol, t.Protocol):
|
|
125
198
|
def get_baseline_coverage(self) -> float: ...
|
|
126
199
|
|
|
127
200
|
def update_baseline_coverage(self, new_coverage: float) -> bool: ...
|
|
@@ -138,16 +211,7 @@ class CoverageRatchetProtocol(t.Protocol):
|
|
|
138
211
|
|
|
139
212
|
|
|
140
213
|
@t.runtime_checkable
|
|
141
|
-
class
|
|
142
|
-
def update_precommit_config(self, options: OptionsProtocol) -> bool: ...
|
|
143
|
-
|
|
144
|
-
def update_pyproject_config(self, options: OptionsProtocol) -> bool: ...
|
|
145
|
-
|
|
146
|
-
def get_temp_config_path(self) -> str | None: ...
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
@t.runtime_checkable
|
|
150
|
-
class SecurityServiceProtocol(t.Protocol):
|
|
214
|
+
class SecurityServiceProtocol(ServiceProtocol, t.Protocol):
|
|
151
215
|
def validate_file_safety(self, path: str | Path) -> bool: ...
|
|
152
216
|
|
|
153
217
|
def check_hardcoded_secrets(self, content: str) -> list[dict[str, t.Any]]: ...
|
|
@@ -162,7 +226,7 @@ class SecurityServiceProtocol(t.Protocol):
|
|
|
162
226
|
|
|
163
227
|
|
|
164
228
|
@t.runtime_checkable
|
|
165
|
-
class InitializationServiceProtocol(t.Protocol):
|
|
229
|
+
class InitializationServiceProtocol(ServiceProtocol, t.Protocol):
|
|
166
230
|
def initialize_project(self, project_path: str | Path) -> bool: ...
|
|
167
231
|
|
|
168
232
|
def validate_project_structure(self) -> bool: ...
|
|
@@ -171,16 +235,41 @@ class InitializationServiceProtocol(t.Protocol):
|
|
|
171
235
|
|
|
172
236
|
|
|
173
237
|
@t.runtime_checkable
|
|
174
|
-
class
|
|
175
|
-
|
|
238
|
+
class SmartSchedulingServiceProtocol(ServiceProtocol, t.Protocol):
|
|
239
|
+
"""Protocol for smart scheduling service."""
|
|
176
240
|
|
|
177
|
-
def
|
|
241
|
+
def should_scheduled_init(self) -> bool: ...
|
|
178
242
|
|
|
179
|
-
def
|
|
243
|
+
def record_init_timestamp(self) -> None: ...
|
|
180
244
|
|
|
181
245
|
|
|
182
246
|
@t.runtime_checkable
|
|
183
|
-
class
|
|
247
|
+
class UnifiedConfigurationServiceProtocol(ServiceProtocol, t.Protocol):
|
|
248
|
+
def get_config(self, reload: bool = False) -> CrackerjackSettings: ...
|
|
249
|
+
|
|
250
|
+
def get_precommit_config_mode(self) -> str: ...
|
|
251
|
+
|
|
252
|
+
def get_logging_config(self) -> dict[str, t.Any]: ...
|
|
253
|
+
|
|
254
|
+
def get_hook_execution_config(self) -> dict[str, t.Any]: ...
|
|
255
|
+
|
|
256
|
+
def get_testing_config(self) -> dict[str, t.Any]: ...
|
|
257
|
+
|
|
258
|
+
@staticmethod
|
|
259
|
+
def get_cache_config() -> dict[str, t.Any]: ...
|
|
260
|
+
|
|
261
|
+
def validate_current_config(self) -> bool: ...
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
@t.runtime_checkable
|
|
265
|
+
class ConfigIntegrityServiceProtocol(ServiceProtocol, t.Protocol):
|
|
266
|
+
"""Protocol for config integrity service."""
|
|
267
|
+
|
|
268
|
+
def check_config_integrity(self) -> bool: ...
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
@t.runtime_checkable
|
|
272
|
+
class TestManagerProtocol(ServiceProtocol, t.Protocol):
|
|
184
273
|
def run_tests(self, options: OptionsProtocol) -> bool: ...
|
|
185
274
|
|
|
186
275
|
def get_test_failures(self) -> list[str]: ...
|
|
@@ -190,6 +279,24 @@ class TestManagerProtocol(t.Protocol):
|
|
|
190
279
|
def get_coverage(self) -> dict[str, t.Any]: ...
|
|
191
280
|
|
|
192
281
|
|
|
282
|
+
@t.runtime_checkable
|
|
283
|
+
class BoundedStatusOperationsProtocol(ServiceProtocol, t.Protocol):
|
|
284
|
+
"""Protocol for bounded status operations service."""
|
|
285
|
+
|
|
286
|
+
async def execute_bounded_operation(
|
|
287
|
+
self,
|
|
288
|
+
operation_type: str,
|
|
289
|
+
client_id: str,
|
|
290
|
+
operation_func: t.Callable[..., t.Awaitable[t.Any]],
|
|
291
|
+
*args: t.Any,
|
|
292
|
+
**kwargs: t.Any,
|
|
293
|
+
) -> t.Any: ...
|
|
294
|
+
|
|
295
|
+
def get_operation_status(self) -> dict[str, t.Any]: ...
|
|
296
|
+
|
|
297
|
+
def reset_circuit_breaker(self, operation_type: str) -> bool: ...
|
|
298
|
+
|
|
299
|
+
|
|
193
300
|
@t.runtime_checkable
|
|
194
301
|
class PublishManager(t.Protocol):
|
|
195
302
|
def bump_version(self, version_type: str) -> str: ...
|
|
@@ -200,11 +307,13 @@ class PublishManager(t.Protocol):
|
|
|
200
307
|
|
|
201
308
|
def create_git_tag(self, version: str) -> bool: ...
|
|
202
309
|
|
|
310
|
+
def create_git_tag_local(self, version: str) -> bool: ...
|
|
311
|
+
|
|
203
312
|
def cleanup_old_releases(self, keep_releases: int) -> None: ...
|
|
204
313
|
|
|
205
314
|
|
|
206
315
|
@t.runtime_checkable
|
|
207
|
-
class ConfigMergeServiceProtocol(t.Protocol):
|
|
316
|
+
class ConfigMergeServiceProtocol(ServiceProtocol, t.Protocol):
|
|
208
317
|
def smart_merge_pyproject(
|
|
209
318
|
self,
|
|
210
319
|
source_content: dict[str, t.Any],
|
|
@@ -251,9 +360,7 @@ class ConfigMergeServiceProtocol(t.Protocol):
|
|
|
251
360
|
class HookLockManagerProtocol(t.Protocol):
|
|
252
361
|
def requires_lock(self, hook_name: str) -> bool: ...
|
|
253
362
|
|
|
254
|
-
|
|
255
|
-
self, hook_name: str
|
|
256
|
-
) -> t.AsyncContextManager[None]: ...
|
|
363
|
+
def acquire_hook_lock(self, hook_name: str) -> t.AsyncContextManager[None]: ...
|
|
257
364
|
|
|
258
365
|
def get_lock_stats(self) -> dict[str, t.Any]: ...
|
|
259
366
|
|
|
@@ -275,7 +382,7 @@ class HookLockManagerProtocol(t.Protocol):
|
|
|
275
382
|
|
|
276
383
|
|
|
277
384
|
@t.runtime_checkable
|
|
278
|
-
class DocumentationServiceProtocol(t.Protocol):
|
|
385
|
+
class DocumentationServiceProtocol(ServiceProtocol, t.Protocol):
|
|
279
386
|
"""Service for automated documentation generation and maintenance."""
|
|
280
387
|
|
|
281
388
|
def extract_api_documentation(
|
|
@@ -389,3 +496,1040 @@ class FileSystemServiceProtocol(t.Protocol):
|
|
|
389
496
|
def mkdir(self, path: str | Path, parents: bool = False) -> None: ...
|
|
390
497
|
|
|
391
498
|
def ensure_directory(self, path: str | Path) -> None: ...
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
@t.runtime_checkable
|
|
502
|
+
class EnhancedFileSystemServiceProtocol(ServiceProtocol, t.Protocol):
|
|
503
|
+
"""Protocol for enhanced file system service."""
|
|
504
|
+
|
|
505
|
+
def read_file(self, path: str | Path) -> str: ...
|
|
506
|
+
|
|
507
|
+
def write_file(self, path: str | Path, content: str) -> None: ...
|
|
508
|
+
|
|
509
|
+
async def read_file_async(self, path: Path) -> str: ...
|
|
510
|
+
|
|
511
|
+
async def write_file_async(self, path: Path, content: str) -> None: ...
|
|
512
|
+
|
|
513
|
+
async def read_multiple_files(self, paths: list[Path]) -> dict[Path, str]: ...
|
|
514
|
+
|
|
515
|
+
async def write_multiple_files(self, file_data: dict[Path, str]) -> None: ...
|
|
516
|
+
|
|
517
|
+
def file_exists(self, path: str | Path) -> bool: ...
|
|
518
|
+
|
|
519
|
+
def create_directory(self, path: str | Path) -> None: ...
|
|
520
|
+
|
|
521
|
+
def delete_file(self, path: str | Path) -> None: ...
|
|
522
|
+
|
|
523
|
+
def list_files(self, path: str | Path, pattern: str = "*") -> t.Iterator[Path]: ...
|
|
524
|
+
|
|
525
|
+
async def flush_operations(self) -> None: ...
|
|
526
|
+
|
|
527
|
+
def get_cache_stats(self) -> dict[str, t.Any]: ...
|
|
528
|
+
|
|
529
|
+
def clear_cache(self) -> None: ...
|
|
530
|
+
|
|
531
|
+
def exists(self, path: str | Path) -> bool: ...
|
|
532
|
+
|
|
533
|
+
def mkdir(self, path: str | Path, parents: bool = False) -> None: ...
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
@t.runtime_checkable
|
|
537
|
+
class QAAdapterProtocol(t.Protocol):
|
|
538
|
+
"""Protocol for quality assurance adapters (ACB-based).
|
|
539
|
+
|
|
540
|
+
All QA adapters must implement this protocol to ensure compatibility
|
|
541
|
+
with the QA orchestration system.
|
|
542
|
+
"""
|
|
543
|
+
|
|
544
|
+
settings: t.Any | None # QABaseSettings
|
|
545
|
+
|
|
546
|
+
async def init(self) -> None:
|
|
547
|
+
"""Initialize adapter (ACB standard method)."""
|
|
548
|
+
...
|
|
549
|
+
|
|
550
|
+
async def check(
|
|
551
|
+
self,
|
|
552
|
+
files: list[Path] | None = None,
|
|
553
|
+
config: t.Any | None = None,
|
|
554
|
+
) -> t.Any:
|
|
555
|
+
"""Execute the quality assurance check.
|
|
556
|
+
|
|
557
|
+
Args:
|
|
558
|
+
files: List of files to check (None = all matching files)
|
|
559
|
+
config: Optional configuration override for this check
|
|
560
|
+
|
|
561
|
+
Returns:
|
|
562
|
+
QAResult containing the check execution results
|
|
563
|
+
"""
|
|
564
|
+
...
|
|
565
|
+
|
|
566
|
+
async def validate_config(self, config: t.Any) -> bool:
|
|
567
|
+
"""Validate that the provided configuration is valid.
|
|
568
|
+
|
|
569
|
+
Args:
|
|
570
|
+
config: Configuration to validate
|
|
571
|
+
|
|
572
|
+
Returns:
|
|
573
|
+
True if configuration is valid, False otherwise
|
|
574
|
+
"""
|
|
575
|
+
...
|
|
576
|
+
|
|
577
|
+
def get_default_config(self) -> t.Any:
|
|
578
|
+
"""Get the default configuration for this adapter.
|
|
579
|
+
|
|
580
|
+
Returns:
|
|
581
|
+
QACheckConfig with sensible defaults for this check
|
|
582
|
+
"""
|
|
583
|
+
...
|
|
584
|
+
|
|
585
|
+
async def health_check(self) -> dict[str, t.Any]:
|
|
586
|
+
"""Check adapter health (ACB standard method).
|
|
587
|
+
|
|
588
|
+
Returns:
|
|
589
|
+
Dictionary with health status and metadata
|
|
590
|
+
"""
|
|
591
|
+
...
|
|
592
|
+
|
|
593
|
+
@property
|
|
594
|
+
def adapter_name(self) -> str:
|
|
595
|
+
"""Human-readable adapter name."""
|
|
596
|
+
...
|
|
597
|
+
|
|
598
|
+
@property
|
|
599
|
+
def module_id(self) -> t.Any:
|
|
600
|
+
"""Reference to module-level MODULE_ID (UUID)."""
|
|
601
|
+
...
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
@t.runtime_checkable
|
|
605
|
+
class QAOrchestratorProtocol(t.Protocol):
|
|
606
|
+
"""Protocol for QA orchestration service.
|
|
607
|
+
|
|
608
|
+
Coordinates multiple QA adapters, handles parallel execution,
|
|
609
|
+
caching, and result aggregation.
|
|
610
|
+
"""
|
|
611
|
+
|
|
612
|
+
async def run_checks(
|
|
613
|
+
self,
|
|
614
|
+
stage: str = "fast",
|
|
615
|
+
files: list[Path] | None = None,
|
|
616
|
+
) -> list[t.Any]:
|
|
617
|
+
"""Run QA checks for specified stage.
|
|
618
|
+
|
|
619
|
+
Args:
|
|
620
|
+
stage: Execution stage ('fast' or 'comprehensive')
|
|
621
|
+
files: Optional list of files to check
|
|
622
|
+
|
|
623
|
+
Returns:
|
|
624
|
+
List of QAResult objects
|
|
625
|
+
"""
|
|
626
|
+
...
|
|
627
|
+
|
|
628
|
+
async def run_all_checks(
|
|
629
|
+
self,
|
|
630
|
+
files: list[Path] | None = None,
|
|
631
|
+
) -> dict[str, t.Any]:
|
|
632
|
+
"""Run all registered QA checks.
|
|
633
|
+
|
|
634
|
+
Args:
|
|
635
|
+
files: Optional list of files to check
|
|
636
|
+
|
|
637
|
+
Returns:
|
|
638
|
+
Dictionary mapping adapter names to results
|
|
639
|
+
"""
|
|
640
|
+
...
|
|
641
|
+
|
|
642
|
+
def register_adapter(self, adapter: QAAdapterProtocol) -> None:
|
|
643
|
+
"""Register a QA adapter.
|
|
644
|
+
|
|
645
|
+
Args:
|
|
646
|
+
adapter: QA adapter to register
|
|
647
|
+
"""
|
|
648
|
+
...
|
|
649
|
+
|
|
650
|
+
def get_adapter(self, name: str) -> QAAdapterProtocol | None:
|
|
651
|
+
"""Get registered adapter by name.
|
|
652
|
+
|
|
653
|
+
Args:
|
|
654
|
+
name: Adapter name
|
|
655
|
+
|
|
656
|
+
Returns:
|
|
657
|
+
Adapter if found, None otherwise
|
|
658
|
+
"""
|
|
659
|
+
...
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
# ==================== Hook Orchestration Protocols (Phase 3) ====================
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
@t.runtime_checkable
|
|
666
|
+
class ExecutionStrategyProtocol(t.Protocol):
|
|
667
|
+
"""Protocol for hook execution strategies.
|
|
668
|
+
|
|
669
|
+
Implementations:
|
|
670
|
+
- ParallelExecutionStrategy: Concurrent execution with resource limits
|
|
671
|
+
- SequentialExecutionStrategy: One-at-a-time execution for dependencies
|
|
672
|
+
"""
|
|
673
|
+
|
|
674
|
+
async def execute(
|
|
675
|
+
self,
|
|
676
|
+
hooks: list[t.Any], # HookDefinition
|
|
677
|
+
max_parallel: int = 3,
|
|
678
|
+
timeout: int = 300,
|
|
679
|
+
) -> list[t.Any]: # list[HookResult]
|
|
680
|
+
"""Execute hooks according to strategy.
|
|
681
|
+
|
|
682
|
+
Args:
|
|
683
|
+
hooks: List of hook definitions to execute
|
|
684
|
+
max_parallel: Maximum concurrent executions (ignored for sequential)
|
|
685
|
+
timeout: Default timeout per hook in seconds
|
|
686
|
+
|
|
687
|
+
Returns:
|
|
688
|
+
List of HookResult objects
|
|
689
|
+
"""
|
|
690
|
+
...
|
|
691
|
+
|
|
692
|
+
def get_execution_order(
|
|
693
|
+
self,
|
|
694
|
+
hooks: list[t.Any], # HookDefinition
|
|
695
|
+
) -> list[list[t.Any]]: # list[list[HookDefinition]]
|
|
696
|
+
"""Return batches of hooks for execution.
|
|
697
|
+
|
|
698
|
+
Sequential strategy returns one hook per batch.
|
|
699
|
+
Parallel strategy groups independent hooks into batches.
|
|
700
|
+
|
|
701
|
+
Args:
|
|
702
|
+
hooks: List of hook definitions
|
|
703
|
+
|
|
704
|
+
Returns:
|
|
705
|
+
List of hook batches for execution
|
|
706
|
+
"""
|
|
707
|
+
...
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
@t.runtime_checkable
|
|
711
|
+
class CacheStrategyProtocol(t.Protocol):
|
|
712
|
+
"""Protocol for result caching strategies.
|
|
713
|
+
|
|
714
|
+
Implementations:
|
|
715
|
+
- ToolProxyCacheAdapter: Bridges to existing tool_proxy cache
|
|
716
|
+
- RedisCacheAdapter: Redis-backed caching (Phase 4+)
|
|
717
|
+
- MemoryCacheAdapter: In-memory LRU cache for testing
|
|
718
|
+
"""
|
|
719
|
+
|
|
720
|
+
async def get(self, key: str) -> t.Any | None: # HookResult | None
|
|
721
|
+
"""Retrieve cached result.
|
|
722
|
+
|
|
723
|
+
Args:
|
|
724
|
+
key: Cache key (computed from hook + file content)
|
|
725
|
+
|
|
726
|
+
Returns:
|
|
727
|
+
Cached HookResult if found, None otherwise
|
|
728
|
+
"""
|
|
729
|
+
...
|
|
730
|
+
|
|
731
|
+
async def set(self, key: str, result: t.Any, ttl: int = 3600) -> None:
|
|
732
|
+
"""Cache result with TTL.
|
|
733
|
+
|
|
734
|
+
Args:
|
|
735
|
+
key: Cache key
|
|
736
|
+
result: HookResult to cache
|
|
737
|
+
ttl: Time-to-live in seconds
|
|
738
|
+
"""
|
|
739
|
+
...
|
|
740
|
+
|
|
741
|
+
def compute_key(self, hook: t.Any, files: list[Path]) -> str:
|
|
742
|
+
"""Compute cache key from hook and file content.
|
|
743
|
+
|
|
744
|
+
Key format: {hook_name}:{config_hash}:{content_hash}
|
|
745
|
+
|
|
746
|
+
Args:
|
|
747
|
+
hook: HookDefinition
|
|
748
|
+
files: List of files being checked
|
|
749
|
+
|
|
750
|
+
Returns:
|
|
751
|
+
Cache key string
|
|
752
|
+
"""
|
|
753
|
+
...
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
@t.runtime_checkable
|
|
757
|
+
class HookOrchestratorProtocol(t.Protocol):
|
|
758
|
+
"""Protocol for hook orchestration.
|
|
759
|
+
|
|
760
|
+
The orchestrator manages hook lifecycle, dependency resolution,
|
|
761
|
+
and execution strategies. Supports dual execution mode for migration.
|
|
762
|
+
"""
|
|
763
|
+
|
|
764
|
+
async def init(self) -> None:
|
|
765
|
+
"""Initialize orchestrator and build dependency graph."""
|
|
766
|
+
...
|
|
767
|
+
|
|
768
|
+
async def execute_strategy(
|
|
769
|
+
self,
|
|
770
|
+
strategy: t.Any, # HookStrategy
|
|
771
|
+
execution_mode: str | None = None,
|
|
772
|
+
execution_context: t.Any | None = None,
|
|
773
|
+
) -> list[t.Any]: # list[HookResult]
|
|
774
|
+
"""Execute hook strategy with specified mode.
|
|
775
|
+
|
|
776
|
+
Args:
|
|
777
|
+
strategy: HookStrategy (fast or comprehensive)
|
|
778
|
+
execution_mode: "legacy" (pre-commit CLI) or "acb" (direct adapters)
|
|
779
|
+
execution_context: Context containing options and execution environment
|
|
780
|
+
|
|
781
|
+
Returns:
|
|
782
|
+
List of HookResult objects
|
|
783
|
+
"""
|
|
784
|
+
...
|
|
785
|
+
|
|
786
|
+
@property
|
|
787
|
+
def module_id(self) -> t.Any: # UUID
|
|
788
|
+
"""Reference to module-level MODULE_ID."""
|
|
789
|
+
...
|
|
790
|
+
|
|
791
|
+
@property
|
|
792
|
+
def adapter_name(self) -> str:
|
|
793
|
+
"""Human-readable adapter name."""
|
|
794
|
+
...
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
# ==================== Performance & Quality Protocols ====================
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
@t.runtime_checkable
|
|
801
|
+
class PerformanceMonitorProtocol(t.Protocol):
|
|
802
|
+
"""Protocol for performance monitoring."""
|
|
803
|
+
|
|
804
|
+
def start_workflow(self, workflow_id: str) -> None:
|
|
805
|
+
"""Start monitoring a workflow."""
|
|
806
|
+
...
|
|
807
|
+
|
|
808
|
+
def end_workflow(
|
|
809
|
+
self, workflow_id: str, success: bool = True
|
|
810
|
+
) -> t.Any: # WorkflowPerformance
|
|
811
|
+
"""End workflow monitoring and return performance data."""
|
|
812
|
+
...
|
|
813
|
+
|
|
814
|
+
def start_phase(self, workflow_id: str, phase_name: str) -> None:
|
|
815
|
+
"""Start monitoring a phase."""
|
|
816
|
+
...
|
|
817
|
+
|
|
818
|
+
def end_phase(
|
|
819
|
+
self, workflow_id: str, phase_name: str, success: bool = True
|
|
820
|
+
) -> t.Any: # PhasePerformance
|
|
821
|
+
"""End phase monitoring and return performance data."""
|
|
822
|
+
...
|
|
823
|
+
|
|
824
|
+
def get_performance_summary(self, last_n_workflows: int = 10) -> dict[str, t.Any]:
|
|
825
|
+
"""Get performance summary for recent workflows."""
|
|
826
|
+
...
|
|
827
|
+
|
|
828
|
+
def get_benchmark_trends(self) -> dict[str, dict[str, t.Any]]:
|
|
829
|
+
"""Get benchmark trend analysis."""
|
|
830
|
+
...
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
@t.runtime_checkable
|
|
834
|
+
class MemoryOptimizerProtocol(t.Protocol):
|
|
835
|
+
"""Protocol for memory optimization."""
|
|
836
|
+
|
|
837
|
+
def record_checkpoint(self, name: str = "") -> float:
|
|
838
|
+
"""Record a memory checkpoint and return current usage."""
|
|
839
|
+
...
|
|
840
|
+
|
|
841
|
+
def get_stats(self) -> dict[str, t.Any]:
|
|
842
|
+
"""Get memory optimization statistics."""
|
|
843
|
+
...
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
@t.runtime_checkable
|
|
847
|
+
class PerformanceCacheProtocol(t.Protocol):
|
|
848
|
+
"""Protocol for performance caching."""
|
|
849
|
+
|
|
850
|
+
def get(self, key: str) -> ExecutionResult | None:
|
|
851
|
+
"""Get cached value."""
|
|
852
|
+
...
|
|
853
|
+
|
|
854
|
+
def set(self, key: str, value: ExecutionResult, ttl: int = 3600) -> None:
|
|
855
|
+
"""Set cached value with TTL."""
|
|
856
|
+
...
|
|
857
|
+
|
|
858
|
+
def invalidate(self, key: str) -> bool:
|
|
859
|
+
"""Invalidate cache entry."""
|
|
860
|
+
...
|
|
861
|
+
|
|
862
|
+
def clear_all(self) -> None:
|
|
863
|
+
"""Clear all cache entries."""
|
|
864
|
+
...
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
@t.runtime_checkable
|
|
868
|
+
class QualityBaselineProtocol(t.Protocol):
|
|
869
|
+
"""Protocol for quality baseline tracking."""
|
|
870
|
+
|
|
871
|
+
def get_current_baseline(self) -> dict[str, t.Any]:
|
|
872
|
+
"""Get current baseline metrics."""
|
|
873
|
+
...
|
|
874
|
+
|
|
875
|
+
def update_baseline(self, metrics: dict[str, t.Any]) -> bool:
|
|
876
|
+
"""Update baseline with new metrics."""
|
|
877
|
+
...
|
|
878
|
+
|
|
879
|
+
def compare(self, current: dict[str, t.Any]) -> dict[str, t.Any]:
|
|
880
|
+
"""Compare current metrics against baseline."""
|
|
881
|
+
...
|
|
882
|
+
|
|
883
|
+
|
|
884
|
+
@t.runtime_checkable
|
|
885
|
+
class ParallelExecutorProtocol(t.Protocol):
|
|
886
|
+
"""Protocol for parallel task execution."""
|
|
887
|
+
|
|
888
|
+
async def execute_parallel(
|
|
889
|
+
self,
|
|
890
|
+
tasks: list[t.Any],
|
|
891
|
+
max_workers: int = 3,
|
|
892
|
+
) -> list[t.Any]:
|
|
893
|
+
"""Execute tasks in parallel."""
|
|
894
|
+
...
|
|
895
|
+
|
|
896
|
+
def get_results(self) -> list[t.Any]:
|
|
897
|
+
"""Get execution results."""
|
|
898
|
+
...
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
@t.runtime_checkable
|
|
902
|
+
class ParallelHookExecutorProtocol(ServiceProtocol, t.Protocol):
|
|
903
|
+
"""Protocol for parallel hook executor service."""
|
|
904
|
+
|
|
905
|
+
async def execute_hooks_parallel(
|
|
906
|
+
self,
|
|
907
|
+
hooks: list[HookDefinition],
|
|
908
|
+
hook_runner: t.Callable[[HookDefinition], t.Awaitable[ExecutionResult]],
|
|
909
|
+
) -> ParallelExecutionResult: ...
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
@t.runtime_checkable
|
|
913
|
+
class AsyncCommandExecutorProtocol(ServiceProtocol, t.Protocol):
|
|
914
|
+
"""Protocol for async command executor service."""
|
|
915
|
+
|
|
916
|
+
async def execute_command(
|
|
917
|
+
self,
|
|
918
|
+
command: list[str],
|
|
919
|
+
cwd: Path | None = None,
|
|
920
|
+
timeout: int = 60,
|
|
921
|
+
cache_ttl: int = 120,
|
|
922
|
+
) -> ExecutionResult: ...
|
|
923
|
+
|
|
924
|
+
async def execute_commands_batch(
|
|
925
|
+
self,
|
|
926
|
+
commands: list[tuple[list[str], Path | None]],
|
|
927
|
+
timeout: int = 60,
|
|
928
|
+
) -> list[ExecutionResult]: ...
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
@t.runtime_checkable
|
|
932
|
+
class PerformanceBenchmarkProtocol(t.Protocol):
|
|
933
|
+
"""Protocol for performance benchmarking."""
|
|
934
|
+
|
|
935
|
+
def run_benchmark(self, operation: str) -> dict[str, t.Any]: ...
|
|
936
|
+
|
|
937
|
+
def get_report(self) -> dict[str, t.Any]: ...
|
|
938
|
+
|
|
939
|
+
def compare_benchmarks(
|
|
940
|
+
self,
|
|
941
|
+
baseline: dict[str, t.Any],
|
|
942
|
+
current: dict[str, t.Any],
|
|
943
|
+
) -> dict[str, t.Any]: ...
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
@t.runtime_checkable
|
|
947
|
+
class PerformanceBenchmarkServiceProtocol(ServiceProtocol, t.Protocol):
|
|
948
|
+
"""Protocol for performance benchmark service."""
|
|
949
|
+
|
|
950
|
+
async def run_benchmark_suite(self) -> t.Any | None: ... # BenchmarkSuite
|
|
951
|
+
|
|
952
|
+
def export_results(
|
|
953
|
+
self, suite: t.Any, output_path: Path
|
|
954
|
+
) -> None: ... # BenchmarkSuite
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
@t.runtime_checkable
|
|
958
|
+
class DebugServiceProtocol(ServiceProtocol, t.Protocol):
|
|
959
|
+
"""Protocol for AI agent debugging services."""
|
|
960
|
+
|
|
961
|
+
def start_debug_session(self, session_id: str) -> None: ...
|
|
962
|
+
|
|
963
|
+
@property
|
|
964
|
+
def enabled(self) -> bool: ...
|
|
965
|
+
|
|
966
|
+
def log_workflow_phase(
|
|
967
|
+
self,
|
|
968
|
+
phase: str,
|
|
969
|
+
status: str,
|
|
970
|
+
details: dict[str, t.Any] | None = None,
|
|
971
|
+
duration: float | None = None,
|
|
972
|
+
) -> None: ...
|
|
973
|
+
|
|
974
|
+
def set_workflow_success(self, success: bool) -> None: ...
|
|
975
|
+
|
|
976
|
+
def print_debug_summary(self) -> None: ...
|
|
977
|
+
|
|
978
|
+
def log_iteration_start(self, iteration_number: int) -> None: ...
|
|
979
|
+
|
|
980
|
+
def log_iteration_end(self, iteration_number: int, success: bool) -> None: ...
|
|
981
|
+
|
|
982
|
+
def log_test_failures(self, count: int) -> None: ...
|
|
983
|
+
|
|
984
|
+
def log_test_fixes(self, count: int) -> None: ...
|
|
985
|
+
|
|
986
|
+
def log_hook_failures(self, count: int) -> None: ...
|
|
987
|
+
|
|
988
|
+
def log_hook_fixes(self, count: int) -> None: ...
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
@t.runtime_checkable
|
|
992
|
+
class QualityIntelligenceProtocol(ServiceProtocol, t.Protocol):
|
|
993
|
+
"""Protocol for quality intelligence services."""
|
|
994
|
+
|
|
995
|
+
def analyze_quality_trends(self) -> dict[str, t.Any]:
|
|
996
|
+
"""Analyze quality trends."""
|
|
997
|
+
...
|
|
998
|
+
|
|
999
|
+
def predict_quality_issues(self) -> list[dict[str, t.Any]]:
|
|
1000
|
+
"""Predict potential quality issues."""
|
|
1001
|
+
...
|
|
1002
|
+
|
|
1003
|
+
def recommend_improvements(self) -> list[dict[str, t.Any]]:
|
|
1004
|
+
"""Recommend quality improvements."""
|
|
1005
|
+
...
|
|
1006
|
+
|
|
1007
|
+
def get_intelligence_report(self) -> dict[str, t.Any]:
|
|
1008
|
+
"""Get quality intelligence report."""
|
|
1009
|
+
...
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
@t.runtime_checkable
|
|
1013
|
+
class CoverageRatchetServiceProtocol(ServiceProtocol, t.Protocol):
|
|
1014
|
+
"""Protocol for coverage ratchet services."""
|
|
1015
|
+
|
|
1016
|
+
def get_current_coverage(self) -> float:
|
|
1017
|
+
"""Get current test coverage percentage."""
|
|
1018
|
+
...
|
|
1019
|
+
|
|
1020
|
+
def get_coverage_history(self) -> list[dict[str, t.Any]]:
|
|
1021
|
+
"""Get coverage history."""
|
|
1022
|
+
...
|
|
1023
|
+
|
|
1024
|
+
def check_coverage_increase(self) -> bool:
|
|
1025
|
+
"""Check if coverage has increased."""
|
|
1026
|
+
...
|
|
1027
|
+
|
|
1028
|
+
def get_next_milestone(self) -> float | None:
|
|
1029
|
+
"""Get the next coverage milestone."""
|
|
1030
|
+
...
|
|
1031
|
+
|
|
1032
|
+
def update_coverage_baseline(self, new_baseline: float) -> bool:
|
|
1033
|
+
"""Update the coverage baseline."""
|
|
1034
|
+
...
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
@t.runtime_checkable
|
|
1038
|
+
class ServerManagerProtocol(ServiceProtocol, t.Protocol):
|
|
1039
|
+
"""Protocol for server management services."""
|
|
1040
|
+
|
|
1041
|
+
def find_processes(self, process_name: str) -> list[dict[str, t.Any]]:
|
|
1042
|
+
"""Find running processes matching name."""
|
|
1043
|
+
...
|
|
1044
|
+
|
|
1045
|
+
def start_server(self, command: list[str]) -> bool:
|
|
1046
|
+
"""Start a server."""
|
|
1047
|
+
...
|
|
1048
|
+
|
|
1049
|
+
def stop_server(self, process_id: int) -> bool:
|
|
1050
|
+
"""Stop a server."""
|
|
1051
|
+
...
|
|
1052
|
+
|
|
1053
|
+
def restart_server(self, command: list[str]) -> bool:
|
|
1054
|
+
"""Restart a server."""
|
|
1055
|
+
...
|
|
1056
|
+
|
|
1057
|
+
def get_server_status(self) -> dict[str, t.Any]:
|
|
1058
|
+
"""Get server status information."""
|
|
1059
|
+
...
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
@t.runtime_checkable
|
|
1063
|
+
class LogManagementProtocol(ServiceProtocol, t.Protocol):
|
|
1064
|
+
"""Protocol for log management services."""
|
|
1065
|
+
|
|
1066
|
+
def get_log_manager(self) -> t.Any:
|
|
1067
|
+
"""Get log management instance."""
|
|
1068
|
+
...
|
|
1069
|
+
|
|
1070
|
+
def setup_structured_logging(
|
|
1071
|
+
self,
|
|
1072
|
+
*,
|
|
1073
|
+
level: str = "INFO",
|
|
1074
|
+
json_output: bool = False,
|
|
1075
|
+
log_file: Path | None = None,
|
|
1076
|
+
) -> None:
|
|
1077
|
+
"""Setup structured logging."""
|
|
1078
|
+
...
|
|
1079
|
+
|
|
1080
|
+
def write_log(self, message: str, level: str = "INFO") -> None:
|
|
1081
|
+
"""Write a log message."""
|
|
1082
|
+
...
|
|
1083
|
+
|
|
1084
|
+
def get_logs(
|
|
1085
|
+
self, filter_criteria: dict[str, t.Any] | None = None
|
|
1086
|
+
) -> list[dict[str, t.Any]]:
|
|
1087
|
+
"""Get logs based on filter criteria."""
|
|
1088
|
+
...
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
# Protocol definitions for services imported directly in managers
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
@t.runtime_checkable
|
|
1095
|
+
class RegexPatternsProtocol(t.Protocol):
|
|
1096
|
+
"""Protocol for regex patterns service."""
|
|
1097
|
+
|
|
1098
|
+
def update_pyproject_version(self, content: str, new_version: str) -> str: ...
|
|
1099
|
+
|
|
1100
|
+
def remove_coverage_fail_under(self, content: str) -> str: ...
|
|
1101
|
+
|
|
1102
|
+
def update_version_in_changelog(self, content: str, new_version: str) -> str: ...
|
|
1103
|
+
|
|
1104
|
+
def mask_tokens_in_text(self, text: str) -> str: ...
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
@t.runtime_checkable
|
|
1108
|
+
class SecureStatusFormatterProtocol(t.Protocol):
|
|
1109
|
+
"""Protocol for secure status formatter service."""
|
|
1110
|
+
|
|
1111
|
+
def format_status(
|
|
1112
|
+
self,
|
|
1113
|
+
status_data: dict[str, t.Any],
|
|
1114
|
+
verbosity: t.Any, # StatusVerbosity
|
|
1115
|
+
user_context: str | None = None,
|
|
1116
|
+
) -> dict[str, t.Any]: ...
|
|
1117
|
+
|
|
1118
|
+
def format_error_response(
|
|
1119
|
+
self,
|
|
1120
|
+
error_message: str,
|
|
1121
|
+
verbosity: t.Any, # StatusVerbosity
|
|
1122
|
+
include_details: bool = False,
|
|
1123
|
+
) -> dict[str, t.Any]: ...
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
@t.runtime_checkable
|
|
1127
|
+
class GitServiceProtocol(t.Protocol):
|
|
1128
|
+
"""Protocol for Git service."""
|
|
1129
|
+
|
|
1130
|
+
def get_current_branch(self) -> str: ...
|
|
1131
|
+
|
|
1132
|
+
def get_commit_history(self, since_commit: str | None = None) -> list[str]: ...
|
|
1133
|
+
|
|
1134
|
+
def create_new_branch(self, branch_name: str) -> bool: ...
|
|
1135
|
+
|
|
1136
|
+
def commit_changes(self, message: str) -> bool: ...
|
|
1137
|
+
|
|
1138
|
+
def push_changes(self) -> bool: ...
|
|
1139
|
+
|
|
1140
|
+
def create_pull_request(self, title: str, body: str) -> bool: ...
|
|
1141
|
+
|
|
1142
|
+
def get_changed_files_since(self, since: str, project_root: Path) -> list[Path]: ...
|
|
1143
|
+
|
|
1144
|
+
def get_staged_files(self, project_root: Path) -> list[Path]: ...
|
|
1145
|
+
|
|
1146
|
+
def get_unstaged_files(self, project_root: Path) -> list[Path]: ...
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
@t.runtime_checkable
|
|
1150
|
+
class SmartFileFilterProtocol(ServiceProtocol, t.Protocol):
|
|
1151
|
+
"""Protocol for smart file filter service."""
|
|
1152
|
+
|
|
1153
|
+
def get_changed_files(self, since: str = "HEAD") -> list[Path]: ...
|
|
1154
|
+
|
|
1155
|
+
def get_staged_files(self) -> list[Path]: ...
|
|
1156
|
+
|
|
1157
|
+
def get_unstaged_files(self) -> list[Path]: ...
|
|
1158
|
+
|
|
1159
|
+
def filter_by_pattern(self, files: list[Path], pattern: str) -> list[Path]: ...
|
|
1160
|
+
|
|
1161
|
+
def filter_by_tool(self, files: list[Path], tool: str) -> list[Path]: ...
|
|
1162
|
+
|
|
1163
|
+
def get_all_modified_files(self) -> list[Path]: ...
|
|
1164
|
+
|
|
1165
|
+
def filter_by_extensions(
|
|
1166
|
+
self, files: list[Path], extensions: list[str]
|
|
1167
|
+
) -> list[Path]: ...
|
|
1168
|
+
|
|
1169
|
+
def get_python_files(self, files: list[Path]) -> list[Path]: ...
|
|
1170
|
+
|
|
1171
|
+
def get_markdown_files(self, files: list[Path]) -> list[Path]: ...
|
|
1172
|
+
|
|
1173
|
+
|
|
1174
|
+
@t.runtime_checkable
|
|
1175
|
+
class SafeFileModifierProtocol(ServiceProtocol, t.Protocol):
|
|
1176
|
+
"""Protocol for safe file modification service."""
|
|
1177
|
+
|
|
1178
|
+
async def apply_fix(
|
|
1179
|
+
self,
|
|
1180
|
+
file_path: str,
|
|
1181
|
+
fixed_content: str,
|
|
1182
|
+
dry_run: bool = False,
|
|
1183
|
+
create_backup: bool = True,
|
|
1184
|
+
) -> dict[str, t.Any]: ...
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
@t.runtime_checkable
|
|
1188
|
+
class VersionAnalyzerProtocol(t.Protocol):
|
|
1189
|
+
"""Protocol for version analysis service."""
|
|
1190
|
+
|
|
1191
|
+
def analyze_changes(self, commit_messages: list[str]) -> dict[str, t.Any]: ...
|
|
1192
|
+
|
|
1193
|
+
def recommend_next_version(self) -> str: ...
|
|
1194
|
+
|
|
1195
|
+
def get_version_bump_type(self, changes: dict[str, t.Any]) -> str: ...
|
|
1196
|
+
|
|
1197
|
+
|
|
1198
|
+
@t.runtime_checkable
|
|
1199
|
+
class HealthMetricsServiceProtocol(ServiceProtocol, t.Protocol):
|
|
1200
|
+
"""Protocol for health metrics service."""
|
|
1201
|
+
|
|
1202
|
+
def collect_current_metrics(self) -> t.Any: ... # ProjectHealth
|
|
1203
|
+
|
|
1204
|
+
def analyze_project_health(
|
|
1205
|
+
self, save_metrics: bool = True
|
|
1206
|
+
) -> t.Any: ... # ProjectHealth
|
|
1207
|
+
|
|
1208
|
+
def report_health_status(self, health: t.Any) -> None: ... # ProjectHealth
|
|
1209
|
+
|
|
1210
|
+
def get_health_trend_summary(self, days: int = 30) -> dict[str, t.Any]: ...
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
@t.runtime_checkable
|
|
1214
|
+
class ChangelogGeneratorProtocol(t.Protocol):
|
|
1215
|
+
"""Protocol for changelog generation service."""
|
|
1216
|
+
|
|
1217
|
+
def generate_changelog_entries(self, changes: dict[str, t.Any]) -> list[str]: ...
|
|
1218
|
+
|
|
1219
|
+
def write_changelog(
|
|
1220
|
+
self, entries: list[str], changelog_file: str | Path
|
|
1221
|
+
) -> bool: ...
|
|
1222
|
+
|
|
1223
|
+
def update_changelog_with_version(
|
|
1224
|
+
self, changelog_file: str | Path, version: str
|
|
1225
|
+
) -> bool: ...
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
@t.runtime_checkable
|
|
1229
|
+
class CoverageBadgeServiceProtocol(ServiceProtocol, t.Protocol):
|
|
1230
|
+
"""Protocol for coverage badge service."""
|
|
1231
|
+
|
|
1232
|
+
def update_readme_coverage_badge(self, coverage_percent: float) -> bool: ...
|
|
1233
|
+
|
|
1234
|
+
def should_update_badge(self, coverage_percent: float) -> bool: ...
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
# ============================================================================
|
|
1238
|
+
# Agent System Protocols (Phase 4)
|
|
1239
|
+
# ============================================================================
|
|
1240
|
+
|
|
1241
|
+
|
|
1242
|
+
@t.runtime_checkable
|
|
1243
|
+
class AgentCoordinatorProtocol(ServiceProtocol, t.Protocol):
|
|
1244
|
+
"""Protocol for agent coordination and issue handling.
|
|
1245
|
+
|
|
1246
|
+
The AgentCoordinator manages a pool of specialized AI agents that can
|
|
1247
|
+
diagnose and fix various code quality issues. It routes issues to
|
|
1248
|
+
appropriate agents, handles agent execution, and aggregates results.
|
|
1249
|
+
"""
|
|
1250
|
+
|
|
1251
|
+
def initialize_agents(self) -> None:
|
|
1252
|
+
"""Initialize all registered agents."""
|
|
1253
|
+
...
|
|
1254
|
+
|
|
1255
|
+
async def handle_issues(
|
|
1256
|
+
self, issues: list[t.Any]
|
|
1257
|
+
) -> t.Any: # list[Issue] -> FixResult
|
|
1258
|
+
"""Handle a batch of issues using appropriate specialist agents.
|
|
1259
|
+
|
|
1260
|
+
Args:
|
|
1261
|
+
issues: List of Issue objects to be processed
|
|
1262
|
+
|
|
1263
|
+
Returns:
|
|
1264
|
+
FixResult containing success status, confidence, and applied fixes
|
|
1265
|
+
"""
|
|
1266
|
+
...
|
|
1267
|
+
|
|
1268
|
+
async def handle_issues_proactively(
|
|
1269
|
+
self, issues: list[t.Any]
|
|
1270
|
+
) -> t.Any: # list[Issue] -> FixResult
|
|
1271
|
+
"""Handle issues with proactive architectural planning.
|
|
1272
|
+
|
|
1273
|
+
Uses ArchitectAgent to create a strategic plan before applying fixes.
|
|
1274
|
+
|
|
1275
|
+
Args:
|
|
1276
|
+
issues: List of Issue objects to be processed
|
|
1277
|
+
|
|
1278
|
+
Returns:
|
|
1279
|
+
FixResult containing success status, confidence, and applied fixes
|
|
1280
|
+
"""
|
|
1281
|
+
...
|
|
1282
|
+
|
|
1283
|
+
def get_agent_capabilities(self) -> dict[str, dict[str, t.Any]]:
|
|
1284
|
+
"""Get capabilities of all registered agents.
|
|
1285
|
+
|
|
1286
|
+
Returns:
|
|
1287
|
+
Dict mapping agent names to their supported issue types and metadata
|
|
1288
|
+
"""
|
|
1289
|
+
...
|
|
1290
|
+
|
|
1291
|
+
def set_proactive_mode(self, enabled: bool) -> None:
|
|
1292
|
+
"""Enable or disable proactive architectural planning mode.
|
|
1293
|
+
|
|
1294
|
+
Args:
|
|
1295
|
+
enabled: Whether to use proactive planning
|
|
1296
|
+
"""
|
|
1297
|
+
...
|
|
1298
|
+
|
|
1299
|
+
|
|
1300
|
+
@t.runtime_checkable
|
|
1301
|
+
class AgentTrackerProtocol(t.Protocol):
|
|
1302
|
+
"""Protocol for tracking agent execution and metrics.
|
|
1303
|
+
|
|
1304
|
+
The AgentTracker monitors agent activity, collects performance metrics,
|
|
1305
|
+
and provides insights into agent effectiveness and success rates.
|
|
1306
|
+
"""
|
|
1307
|
+
|
|
1308
|
+
def register_agents(self, agent_types: list[str]) -> None:
|
|
1309
|
+
"""Register agent types for tracking.
|
|
1310
|
+
|
|
1311
|
+
Args:
|
|
1312
|
+
agent_types: List of agent class names
|
|
1313
|
+
"""
|
|
1314
|
+
...
|
|
1315
|
+
|
|
1316
|
+
def set_coordinator_status(self, status: str) -> None:
|
|
1317
|
+
"""Set the overall coordinator status.
|
|
1318
|
+
|
|
1319
|
+
Args:
|
|
1320
|
+
status: Status string (e.g., 'active', 'idle', 'processing')
|
|
1321
|
+
"""
|
|
1322
|
+
...
|
|
1323
|
+
|
|
1324
|
+
def track_agent_processing(
|
|
1325
|
+
self, agent_name: str, issue: t.Any, confidence: float
|
|
1326
|
+
) -> None: # issue: Issue
|
|
1327
|
+
"""Track when an agent begins processing an issue.
|
|
1328
|
+
|
|
1329
|
+
Args:
|
|
1330
|
+
agent_name: Name of the agent
|
|
1331
|
+
issue: Issue being processed
|
|
1332
|
+
confidence: Agent's confidence in handling this issue (0.0-1.0)
|
|
1333
|
+
"""
|
|
1334
|
+
...
|
|
1335
|
+
|
|
1336
|
+
def track_agent_complete(
|
|
1337
|
+
self, agent_name: str, result: t.Any
|
|
1338
|
+
) -> None: # result: FixResult
|
|
1339
|
+
"""Track agent completion and results.
|
|
1340
|
+
|
|
1341
|
+
Args:
|
|
1342
|
+
agent_name: Name of the agent
|
|
1343
|
+
result: FixResult from agent execution
|
|
1344
|
+
"""
|
|
1345
|
+
...
|
|
1346
|
+
|
|
1347
|
+
def get_agent_stats(self) -> dict[str, t.Any]:
|
|
1348
|
+
"""Get aggregate statistics for all agents.
|
|
1349
|
+
|
|
1350
|
+
Returns:
|
|
1351
|
+
Dict containing success rates, average confidence, etc.
|
|
1352
|
+
"""
|
|
1353
|
+
...
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
@t.runtime_checkable
|
|
1357
|
+
class AgentDebuggerProtocol(t.Protocol):
|
|
1358
|
+
"""Protocol for agent debugging and activity logging.
|
|
1359
|
+
|
|
1360
|
+
The AgentDebugger provides detailed logging for agent activities,
|
|
1361
|
+
enabling troubleshooting and performance analysis.
|
|
1362
|
+
"""
|
|
1363
|
+
|
|
1364
|
+
def log_agent_activity(
|
|
1365
|
+
self,
|
|
1366
|
+
agent_name: str,
|
|
1367
|
+
activity: str,
|
|
1368
|
+
**metadata: t.Any,
|
|
1369
|
+
) -> None:
|
|
1370
|
+
"""Log an agent activity with optional metadata.
|
|
1371
|
+
|
|
1372
|
+
Args:
|
|
1373
|
+
agent_name: Name of the agent
|
|
1374
|
+
activity: Activity type (e.g., 'processing_started', 'processing_completed')
|
|
1375
|
+
**metadata: Additional context (issue_id, confidence, result, etc.)
|
|
1376
|
+
"""
|
|
1377
|
+
...
|
|
1378
|
+
|
|
1379
|
+
def get_activity_log(
|
|
1380
|
+
self, agent_name: str | None = None, limit: int = 100
|
|
1381
|
+
) -> list[dict[str, t.Any]]:
|
|
1382
|
+
"""Get recent activity log entries.
|
|
1383
|
+
|
|
1384
|
+
Args:
|
|
1385
|
+
agent_name: Optional filter by agent name
|
|
1386
|
+
limit: Maximum number of entries to return
|
|
1387
|
+
|
|
1388
|
+
Returns:
|
|
1389
|
+
List of activity log entries
|
|
1390
|
+
"""
|
|
1391
|
+
...
|
|
1392
|
+
|
|
1393
|
+
def enable_verbose_mode(self, enabled: bool = True) -> None:
|
|
1394
|
+
"""Enable or disable verbose debugging mode.
|
|
1395
|
+
|
|
1396
|
+
Args:
|
|
1397
|
+
enabled: Whether to enable verbose output
|
|
1398
|
+
"""
|
|
1399
|
+
...
|
|
1400
|
+
|
|
1401
|
+
|
|
1402
|
+
# ============================================================================
|
|
1403
|
+
# Orchestration Protocols (Phase 4)
|
|
1404
|
+
# ============================================================================
|
|
1405
|
+
|
|
1406
|
+
|
|
1407
|
+
@t.runtime_checkable
|
|
1408
|
+
class ServiceWatchdogProtocol(ServiceProtocol, t.Protocol):
|
|
1409
|
+
"""Protocol for service health monitoring and restart coordination.
|
|
1410
|
+
|
|
1411
|
+
The ServiceWatchdog monitors long-running services (MCP server, WebSocket
|
|
1412
|
+
server, LSP servers) and automatically restarts them on failure.
|
|
1413
|
+
"""
|
|
1414
|
+
|
|
1415
|
+
def register_service(self, config: t.Any) -> None: # config: ServiceConfig
|
|
1416
|
+
"""Register a service for monitoring.
|
|
1417
|
+
|
|
1418
|
+
Args:
|
|
1419
|
+
config: ServiceConfig with command, health checks, and restart policy
|
|
1420
|
+
"""
|
|
1421
|
+
...
|
|
1422
|
+
|
|
1423
|
+
async def start(self) -> None:
|
|
1424
|
+
"""Start the watchdog monitoring loop."""
|
|
1425
|
+
...
|
|
1426
|
+
|
|
1427
|
+
async def stop(self) -> None:
|
|
1428
|
+
"""Stop the watchdog and shutdown monitored services."""
|
|
1429
|
+
...
|
|
1430
|
+
|
|
1431
|
+
async def restart_service(self, service_name: str) -> bool:
|
|
1432
|
+
"""Manually restart a specific service.
|
|
1433
|
+
|
|
1434
|
+
Args:
|
|
1435
|
+
service_name: Name of service to restart
|
|
1436
|
+
|
|
1437
|
+
Returns:
|
|
1438
|
+
True if restart successful
|
|
1439
|
+
"""
|
|
1440
|
+
...
|
|
1441
|
+
|
|
1442
|
+
def get_service_status(
|
|
1443
|
+
self, service_name: str
|
|
1444
|
+
) -> t.Any | None: # ServiceStatus | None
|
|
1445
|
+
"""Get current status of a specific service.
|
|
1446
|
+
|
|
1447
|
+
Args:
|
|
1448
|
+
service_name: Name of service
|
|
1449
|
+
|
|
1450
|
+
Returns:
|
|
1451
|
+
ServiceStatus object or None if not found
|
|
1452
|
+
"""
|
|
1453
|
+
...
|
|
1454
|
+
|
|
1455
|
+
def get_all_services_status(self) -> dict[str, t.Any]: # dict[str, ServiceStatus]
|
|
1456
|
+
"""Get status of all monitored services.
|
|
1457
|
+
|
|
1458
|
+
Returns:
|
|
1459
|
+
Dict mapping service names to ServiceStatus objects
|
|
1460
|
+
"""
|
|
1461
|
+
...
|
|
1462
|
+
|
|
1463
|
+
async def check_service_health(self, service_name: str) -> bool:
|
|
1464
|
+
"""Perform health check on a specific service.
|
|
1465
|
+
|
|
1466
|
+
Args:
|
|
1467
|
+
service_name: Name of service to check
|
|
1468
|
+
|
|
1469
|
+
Returns:
|
|
1470
|
+
True if service is healthy
|
|
1471
|
+
"""
|
|
1472
|
+
...
|
|
1473
|
+
|
|
1474
|
+
|
|
1475
|
+
@t.runtime_checkable
|
|
1476
|
+
class TimeoutManagerProtocol(t.Protocol):
|
|
1477
|
+
"""Protocol for timeout management and strategies.
|
|
1478
|
+
|
|
1479
|
+
The TimeoutManager provides centralized timeout configuration for
|
|
1480
|
+
various operations (hooks, tests, service startups, etc).
|
|
1481
|
+
"""
|
|
1482
|
+
|
|
1483
|
+
def get_timeout(self, operation: str) -> float:
|
|
1484
|
+
"""Get timeout for a specific operation type.
|
|
1485
|
+
|
|
1486
|
+
Args:
|
|
1487
|
+
operation: Operation type (e.g., 'hook_execution', 'test_run')
|
|
1488
|
+
|
|
1489
|
+
Returns:
|
|
1490
|
+
Timeout in seconds
|
|
1491
|
+
"""
|
|
1492
|
+
...
|
|
1493
|
+
|
|
1494
|
+
def set_timeout(self, operation: str, timeout: float) -> None:
|
|
1495
|
+
"""Set timeout for a specific operation type.
|
|
1496
|
+
|
|
1497
|
+
Args:
|
|
1498
|
+
operation: Operation type
|
|
1499
|
+
timeout: Timeout in seconds
|
|
1500
|
+
"""
|
|
1501
|
+
...
|
|
1502
|
+
|
|
1503
|
+
def get_strategy(self, operation: str) -> t.Any: # TimeoutStrategy
|
|
1504
|
+
"""Get timeout strategy for an operation.
|
|
1505
|
+
|
|
1506
|
+
Args:
|
|
1507
|
+
operation: Operation type
|
|
1508
|
+
|
|
1509
|
+
Returns:
|
|
1510
|
+
TimeoutStrategy enum value
|
|
1511
|
+
"""
|
|
1512
|
+
...
|
|
1513
|
+
|
|
1514
|
+
def apply_timeout(
|
|
1515
|
+
self,
|
|
1516
|
+
operation: str,
|
|
1517
|
+
func: t.Callable[..., t.Any],
|
|
1518
|
+
*args: t.Any,
|
|
1519
|
+
**kwargs: t.Any,
|
|
1520
|
+
) -> t.Any:
|
|
1521
|
+
"""Apply timeout to a function execution.
|
|
1522
|
+
|
|
1523
|
+
Args:
|
|
1524
|
+
operation: Operation type (determines timeout value)
|
|
1525
|
+
func: Function to execute with timeout
|
|
1526
|
+
*args: Positional arguments for function
|
|
1527
|
+
**kwargs: Keyword arguments for function
|
|
1528
|
+
|
|
1529
|
+
Returns:
|
|
1530
|
+
Function result
|
|
1531
|
+
|
|
1532
|
+
Raises:
|
|
1533
|
+
TimeoutError: If operation exceeds timeout
|
|
1534
|
+
"""
|
|
1535
|
+
...
|