crackerjack 0.18.2__py3-none-any.whl → 0.45.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- crackerjack/README.md +19 -0
- crackerjack/__init__.py +96 -2
- crackerjack/__main__.py +637 -138
- crackerjack/adapters/README.md +18 -0
- crackerjack/adapters/__init__.py +39 -0
- crackerjack/adapters/_output_paths.py +167 -0
- crackerjack/adapters/_qa_adapter_base.py +309 -0
- crackerjack/adapters/_tool_adapter_base.py +706 -0
- crackerjack/adapters/ai/README.md +65 -0
- crackerjack/adapters/ai/__init__.py +5 -0
- crackerjack/adapters/ai/claude.py +853 -0
- crackerjack/adapters/complexity/README.md +53 -0
- crackerjack/adapters/complexity/__init__.py +10 -0
- crackerjack/adapters/complexity/complexipy.py +641 -0
- crackerjack/adapters/dependency/__init__.py +22 -0
- crackerjack/adapters/dependency/pip_audit.py +418 -0
- crackerjack/adapters/format/README.md +72 -0
- crackerjack/adapters/format/__init__.py +11 -0
- crackerjack/adapters/format/mdformat.py +313 -0
- crackerjack/adapters/format/ruff.py +516 -0
- crackerjack/adapters/lint/README.md +47 -0
- crackerjack/adapters/lint/__init__.py +11 -0
- crackerjack/adapters/lint/codespell.py +273 -0
- crackerjack/adapters/lsp/README.md +49 -0
- crackerjack/adapters/lsp/__init__.py +27 -0
- crackerjack/adapters/lsp/_base.py +194 -0
- crackerjack/adapters/lsp/_client.py +358 -0
- crackerjack/adapters/lsp/_manager.py +193 -0
- crackerjack/adapters/lsp/skylos.py +283 -0
- crackerjack/adapters/lsp/zuban.py +557 -0
- crackerjack/adapters/refactor/README.md +59 -0
- crackerjack/adapters/refactor/__init__.py +12 -0
- crackerjack/adapters/refactor/creosote.py +318 -0
- crackerjack/adapters/refactor/refurb.py +406 -0
- crackerjack/adapters/refactor/skylos.py +494 -0
- crackerjack/adapters/sast/README.md +132 -0
- crackerjack/adapters/sast/__init__.py +32 -0
- crackerjack/adapters/sast/_base.py +201 -0
- crackerjack/adapters/sast/bandit.py +423 -0
- crackerjack/adapters/sast/pyscn.py +405 -0
- crackerjack/adapters/sast/semgrep.py +241 -0
- crackerjack/adapters/security/README.md +111 -0
- crackerjack/adapters/security/__init__.py +17 -0
- crackerjack/adapters/security/gitleaks.py +339 -0
- crackerjack/adapters/type/README.md +52 -0
- crackerjack/adapters/type/__init__.py +12 -0
- crackerjack/adapters/type/pyrefly.py +402 -0
- crackerjack/adapters/type/ty.py +402 -0
- crackerjack/adapters/type/zuban.py +522 -0
- crackerjack/adapters/utility/README.md +51 -0
- crackerjack/adapters/utility/__init__.py +10 -0
- crackerjack/adapters/utility/checks.py +884 -0
- crackerjack/agents/README.md +264 -0
- crackerjack/agents/__init__.py +66 -0
- crackerjack/agents/architect_agent.py +238 -0
- crackerjack/agents/base.py +167 -0
- crackerjack/agents/claude_code_bridge.py +641 -0
- crackerjack/agents/coordinator.py +600 -0
- crackerjack/agents/documentation_agent.py +520 -0
- crackerjack/agents/dry_agent.py +585 -0
- crackerjack/agents/enhanced_coordinator.py +279 -0
- crackerjack/agents/enhanced_proactive_agent.py +185 -0
- crackerjack/agents/error_middleware.py +53 -0
- crackerjack/agents/formatting_agent.py +230 -0
- crackerjack/agents/helpers/__init__.py +9 -0
- crackerjack/agents/helpers/performance/__init__.py +22 -0
- crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
- crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
- crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
- crackerjack/agents/helpers/refactoring/__init__.py +22 -0
- crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
- crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
- crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
- crackerjack/agents/helpers/test_creation/__init__.py +19 -0
- crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
- crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
- crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
- crackerjack/agents/import_optimization_agent.py +1181 -0
- crackerjack/agents/performance_agent.py +325 -0
- crackerjack/agents/performance_helpers.py +205 -0
- crackerjack/agents/proactive_agent.py +55 -0
- crackerjack/agents/refactoring_agent.py +511 -0
- crackerjack/agents/refactoring_helpers.py +247 -0
- crackerjack/agents/security_agent.py +793 -0
- crackerjack/agents/semantic_agent.py +479 -0
- crackerjack/agents/semantic_helpers.py +356 -0
- crackerjack/agents/test_creation_agent.py +570 -0
- crackerjack/agents/test_specialist_agent.py +526 -0
- crackerjack/agents/tracker.py +110 -0
- crackerjack/api.py +647 -0
- crackerjack/cli/README.md +394 -0
- crackerjack/cli/__init__.py +24 -0
- crackerjack/cli/cache_handlers.py +209 -0
- crackerjack/cli/cache_handlers_enhanced.py +680 -0
- crackerjack/cli/facade.py +162 -0
- crackerjack/cli/formatting.py +13 -0
- crackerjack/cli/handlers/__init__.py +85 -0
- crackerjack/cli/handlers/advanced.py +103 -0
- crackerjack/cli/handlers/ai_features.py +62 -0
- crackerjack/cli/handlers/analytics.py +479 -0
- crackerjack/cli/handlers/changelog.py +271 -0
- crackerjack/cli/handlers/config_handlers.py +16 -0
- crackerjack/cli/handlers/coverage.py +84 -0
- crackerjack/cli/handlers/documentation.py +280 -0
- crackerjack/cli/handlers/main_handlers.py +497 -0
- crackerjack/cli/handlers/monitoring.py +371 -0
- crackerjack/cli/handlers.py +700 -0
- crackerjack/cli/interactive.py +488 -0
- crackerjack/cli/options.py +1216 -0
- crackerjack/cli/semantic_handlers.py +292 -0
- crackerjack/cli/utils.py +19 -0
- crackerjack/cli/version.py +19 -0
- crackerjack/code_cleaner.py +1307 -0
- crackerjack/config/README.md +472 -0
- crackerjack/config/__init__.py +275 -0
- crackerjack/config/global_lock_config.py +207 -0
- crackerjack/config/hooks.py +390 -0
- crackerjack/config/loader.py +239 -0
- crackerjack/config/settings.py +141 -0
- crackerjack/config/tool_commands.py +331 -0
- crackerjack/core/README.md +393 -0
- crackerjack/core/__init__.py +0 -0
- crackerjack/core/async_workflow_orchestrator.py +738 -0
- crackerjack/core/autofix_coordinator.py +282 -0
- crackerjack/core/container.py +105 -0
- crackerjack/core/enhanced_container.py +583 -0
- crackerjack/core/file_lifecycle.py +472 -0
- crackerjack/core/performance.py +244 -0
- crackerjack/core/performance_monitor.py +357 -0
- crackerjack/core/phase_coordinator.py +1227 -0
- crackerjack/core/proactive_workflow.py +267 -0
- crackerjack/core/resource_manager.py +425 -0
- crackerjack/core/retry.py +275 -0
- crackerjack/core/service_watchdog.py +601 -0
- crackerjack/core/session_coordinator.py +239 -0
- crackerjack/core/timeout_manager.py +563 -0
- crackerjack/core/websocket_lifecycle.py +410 -0
- crackerjack/core/workflow/__init__.py +21 -0
- crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
- crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
- crackerjack/core/workflow/workflow_issue_parser.py +714 -0
- crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
- crackerjack/core/workflow/workflow_security_gates.py +400 -0
- crackerjack/core/workflow_orchestrator.py +2243 -0
- crackerjack/data/README.md +11 -0
- crackerjack/data/__init__.py +8 -0
- crackerjack/data/models.py +79 -0
- crackerjack/data/repository.py +210 -0
- crackerjack/decorators/README.md +180 -0
- crackerjack/decorators/__init__.py +35 -0
- crackerjack/decorators/error_handling.py +649 -0
- crackerjack/decorators/error_handling_decorators.py +334 -0
- crackerjack/decorators/helpers.py +58 -0
- crackerjack/decorators/patterns.py +281 -0
- crackerjack/decorators/utils.py +58 -0
- crackerjack/docs/INDEX.md +11 -0
- crackerjack/docs/README.md +11 -0
- crackerjack/docs/generated/api/API_REFERENCE.md +10895 -0
- crackerjack/docs/generated/api/CLI_REFERENCE.md +109 -0
- crackerjack/docs/generated/api/CROSS_REFERENCES.md +1755 -0
- crackerjack/docs/generated/api/PROTOCOLS.md +3 -0
- crackerjack/docs/generated/api/SERVICES.md +1252 -0
- crackerjack/documentation/README.md +11 -0
- crackerjack/documentation/__init__.py +31 -0
- crackerjack/documentation/ai_templates.py +756 -0
- crackerjack/documentation/dual_output_generator.py +767 -0
- crackerjack/documentation/mkdocs_integration.py +518 -0
- crackerjack/documentation/reference_generator.py +1065 -0
- crackerjack/dynamic_config.py +678 -0
- crackerjack/errors.py +378 -0
- crackerjack/events/README.md +11 -0
- crackerjack/events/__init__.py +16 -0
- crackerjack/events/telemetry.py +175 -0
- crackerjack/events/workflow_bus.py +346 -0
- crackerjack/exceptions/README.md +301 -0
- crackerjack/exceptions/__init__.py +5 -0
- crackerjack/exceptions/config.py +4 -0
- crackerjack/exceptions/tool_execution_error.py +245 -0
- crackerjack/executors/README.md +591 -0
- crackerjack/executors/__init__.py +13 -0
- crackerjack/executors/async_hook_executor.py +938 -0
- crackerjack/executors/cached_hook_executor.py +316 -0
- crackerjack/executors/hook_executor.py +1295 -0
- crackerjack/executors/hook_lock_manager.py +708 -0
- crackerjack/executors/individual_hook_executor.py +739 -0
- crackerjack/executors/lsp_aware_hook_executor.py +349 -0
- crackerjack/executors/progress_hook_executor.py +282 -0
- crackerjack/executors/tool_proxy.py +433 -0
- crackerjack/hooks/README.md +485 -0
- crackerjack/hooks/lsp_hook.py +93 -0
- crackerjack/intelligence/README.md +557 -0
- crackerjack/intelligence/__init__.py +37 -0
- crackerjack/intelligence/adaptive_learning.py +693 -0
- crackerjack/intelligence/agent_orchestrator.py +485 -0
- crackerjack/intelligence/agent_registry.py +377 -0
- crackerjack/intelligence/agent_selector.py +439 -0
- crackerjack/intelligence/integration.py +250 -0
- crackerjack/interactive.py +719 -0
- crackerjack/managers/README.md +369 -0
- crackerjack/managers/__init__.py +11 -0
- crackerjack/managers/async_hook_manager.py +135 -0
- crackerjack/managers/hook_manager.py +585 -0
- crackerjack/managers/publish_manager.py +631 -0
- crackerjack/managers/test_command_builder.py +391 -0
- crackerjack/managers/test_executor.py +474 -0
- crackerjack/managers/test_manager.py +1357 -0
- crackerjack/managers/test_progress.py +187 -0
- crackerjack/mcp/README.md +374 -0
- crackerjack/mcp/__init__.py +0 -0
- crackerjack/mcp/cache.py +352 -0
- crackerjack/mcp/client_runner.py +121 -0
- crackerjack/mcp/context.py +802 -0
- crackerjack/mcp/dashboard.py +657 -0
- crackerjack/mcp/enhanced_progress_monitor.py +493 -0
- crackerjack/mcp/file_monitor.py +394 -0
- crackerjack/mcp/progress_components.py +607 -0
- crackerjack/mcp/progress_monitor.py +1016 -0
- crackerjack/mcp/rate_limiter.py +336 -0
- crackerjack/mcp/server.py +24 -0
- crackerjack/mcp/server_core.py +526 -0
- crackerjack/mcp/service_watchdog.py +505 -0
- crackerjack/mcp/state.py +407 -0
- crackerjack/mcp/task_manager.py +259 -0
- crackerjack/mcp/tools/README.md +27 -0
- crackerjack/mcp/tools/__init__.py +19 -0
- crackerjack/mcp/tools/core_tools.py +469 -0
- crackerjack/mcp/tools/error_analyzer.py +283 -0
- crackerjack/mcp/tools/execution_tools.py +384 -0
- crackerjack/mcp/tools/intelligence_tool_registry.py +46 -0
- crackerjack/mcp/tools/intelligence_tools.py +264 -0
- crackerjack/mcp/tools/monitoring_tools.py +628 -0
- crackerjack/mcp/tools/proactive_tools.py +367 -0
- crackerjack/mcp/tools/progress_tools.py +222 -0
- crackerjack/mcp/tools/semantic_tools.py +584 -0
- crackerjack/mcp/tools/utility_tools.py +358 -0
- crackerjack/mcp/tools/workflow_executor.py +699 -0
- crackerjack/mcp/websocket/README.md +31 -0
- crackerjack/mcp/websocket/__init__.py +14 -0
- crackerjack/mcp/websocket/app.py +54 -0
- crackerjack/mcp/websocket/endpoints.py +492 -0
- crackerjack/mcp/websocket/event_bridge.py +188 -0
- crackerjack/mcp/websocket/jobs.py +406 -0
- crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
- crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
- crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
- crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
- crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
- crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
- crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
- crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
- crackerjack/mcp/websocket/monitoring/factory.py +109 -0
- crackerjack/mcp/websocket/monitoring/filters.py +10 -0
- crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
- crackerjack/mcp/websocket/monitoring/models.py +90 -0
- crackerjack/mcp/websocket/monitoring/utils.py +171 -0
- crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
- crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
- crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
- crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
- crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
- crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
- crackerjack/mcp/websocket/monitoring_endpoints.py +21 -0
- crackerjack/mcp/websocket/server.py +174 -0
- crackerjack/mcp/websocket/websocket_handler.py +276 -0
- crackerjack/mcp/websocket_server.py +10 -0
- crackerjack/models/README.md +308 -0
- crackerjack/models/__init__.py +40 -0
- crackerjack/models/config.py +730 -0
- crackerjack/models/config_adapter.py +265 -0
- crackerjack/models/protocols.py +1535 -0
- crackerjack/models/pydantic_models.py +320 -0
- crackerjack/models/qa_config.py +145 -0
- crackerjack/models/qa_results.py +134 -0
- crackerjack/models/resource_protocols.py +299 -0
- crackerjack/models/results.py +35 -0
- crackerjack/models/semantic_models.py +258 -0
- crackerjack/models/task.py +173 -0
- crackerjack/models/test_models.py +60 -0
- crackerjack/monitoring/README.md +11 -0
- crackerjack/monitoring/__init__.py +0 -0
- crackerjack/monitoring/ai_agent_watchdog.py +405 -0
- crackerjack/monitoring/metrics_collector.py +427 -0
- crackerjack/monitoring/regression_prevention.py +580 -0
- crackerjack/monitoring/websocket_server.py +406 -0
- crackerjack/orchestration/README.md +340 -0
- crackerjack/orchestration/__init__.py +43 -0
- crackerjack/orchestration/advanced_orchestrator.py +894 -0
- crackerjack/orchestration/cache/README.md +312 -0
- crackerjack/orchestration/cache/__init__.py +37 -0
- crackerjack/orchestration/cache/memory_cache.py +338 -0
- crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
- crackerjack/orchestration/config.py +297 -0
- crackerjack/orchestration/coverage_improvement.py +180 -0
- crackerjack/orchestration/execution_strategies.py +361 -0
- crackerjack/orchestration/hook_orchestrator.py +1398 -0
- crackerjack/orchestration/strategies/README.md +401 -0
- crackerjack/orchestration/strategies/__init__.py +39 -0
- crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
- crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
- crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
- crackerjack/orchestration/test_progress_streamer.py +647 -0
- crackerjack/plugins/README.md +11 -0
- crackerjack/plugins/__init__.py +15 -0
- crackerjack/plugins/base.py +200 -0
- crackerjack/plugins/hooks.py +254 -0
- crackerjack/plugins/loader.py +335 -0
- crackerjack/plugins/managers.py +264 -0
- crackerjack/py313.py +191 -0
- crackerjack/security/README.md +11 -0
- crackerjack/security/__init__.py +0 -0
- crackerjack/security/audit.py +197 -0
- crackerjack/services/README.md +374 -0
- crackerjack/services/__init__.py +9 -0
- crackerjack/services/ai/README.md +295 -0
- crackerjack/services/ai/__init__.py +7 -0
- crackerjack/services/ai/advanced_optimizer.py +878 -0
- crackerjack/services/ai/contextual_ai_assistant.py +542 -0
- crackerjack/services/ai/embeddings.py +444 -0
- crackerjack/services/ai/intelligent_commit.py +328 -0
- crackerjack/services/ai/predictive_analytics.py +510 -0
- crackerjack/services/anomaly_detector.py +392 -0
- crackerjack/services/api_extractor.py +617 -0
- crackerjack/services/backup_service.py +467 -0
- crackerjack/services/bounded_status_operations.py +530 -0
- crackerjack/services/cache.py +369 -0
- crackerjack/services/changelog_automation.py +399 -0
- crackerjack/services/command_execution_service.py +305 -0
- crackerjack/services/config_integrity.py +132 -0
- crackerjack/services/config_merge.py +546 -0
- crackerjack/services/config_service.py +198 -0
- crackerjack/services/config_template.py +493 -0
- crackerjack/services/coverage_badge_service.py +173 -0
- crackerjack/services/coverage_ratchet.py +381 -0
- crackerjack/services/debug.py +733 -0
- crackerjack/services/dependency_analyzer.py +460 -0
- crackerjack/services/dependency_monitor.py +622 -0
- crackerjack/services/documentation_generator.py +493 -0
- crackerjack/services/documentation_service.py +704 -0
- crackerjack/services/enhanced_filesystem.py +497 -0
- crackerjack/services/enterprise_optimizer.py +865 -0
- crackerjack/services/error_pattern_analyzer.py +676 -0
- crackerjack/services/file_filter.py +221 -0
- crackerjack/services/file_hasher.py +149 -0
- crackerjack/services/file_io_service.py +361 -0
- crackerjack/services/file_modifier.py +615 -0
- crackerjack/services/filesystem.py +381 -0
- crackerjack/services/git.py +422 -0
- crackerjack/services/health_metrics.py +615 -0
- crackerjack/services/heatmap_generator.py +744 -0
- crackerjack/services/incremental_executor.py +380 -0
- crackerjack/services/initialization.py +823 -0
- crackerjack/services/input_validator.py +668 -0
- crackerjack/services/intelligent_commit.py +327 -0
- crackerjack/services/log_manager.py +289 -0
- crackerjack/services/logging.py +228 -0
- crackerjack/services/lsp_client.py +628 -0
- crackerjack/services/memory_optimizer.py +414 -0
- crackerjack/services/metrics.py +587 -0
- crackerjack/services/monitoring/README.md +30 -0
- crackerjack/services/monitoring/__init__.py +9 -0
- crackerjack/services/monitoring/dependency_monitor.py +678 -0
- crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
- crackerjack/services/monitoring/health_metrics.py +716 -0
- crackerjack/services/monitoring/metrics.py +587 -0
- crackerjack/services/monitoring/performance_benchmarks.py +410 -0
- crackerjack/services/monitoring/performance_cache.py +388 -0
- crackerjack/services/monitoring/performance_monitor.py +569 -0
- crackerjack/services/parallel_executor.py +527 -0
- crackerjack/services/pattern_cache.py +333 -0
- crackerjack/services/pattern_detector.py +478 -0
- crackerjack/services/patterns/__init__.py +142 -0
- crackerjack/services/patterns/agents.py +107 -0
- crackerjack/services/patterns/code/__init__.py +15 -0
- crackerjack/services/patterns/code/detection.py +118 -0
- crackerjack/services/patterns/code/imports.py +107 -0
- crackerjack/services/patterns/code/paths.py +159 -0
- crackerjack/services/patterns/code/performance.py +119 -0
- crackerjack/services/patterns/code/replacement.py +36 -0
- crackerjack/services/patterns/core.py +212 -0
- crackerjack/services/patterns/documentation/__init__.py +14 -0
- crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
- crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
- crackerjack/services/patterns/documentation/docstrings.py +89 -0
- crackerjack/services/patterns/formatting.py +226 -0
- crackerjack/services/patterns/operations.py +339 -0
- crackerjack/services/patterns/security/__init__.py +23 -0
- crackerjack/services/patterns/security/code_injection.py +122 -0
- crackerjack/services/patterns/security/credentials.py +190 -0
- crackerjack/services/patterns/security/path_traversal.py +221 -0
- crackerjack/services/patterns/security/unsafe_operations.py +216 -0
- crackerjack/services/patterns/templates.py +62 -0
- crackerjack/services/patterns/testing/__init__.py +18 -0
- crackerjack/services/patterns/testing/error_patterns.py +107 -0
- crackerjack/services/patterns/testing/pytest_output.py +126 -0
- crackerjack/services/patterns/tool_output/__init__.py +16 -0
- crackerjack/services/patterns/tool_output/bandit.py +72 -0
- crackerjack/services/patterns/tool_output/other.py +97 -0
- crackerjack/services/patterns/tool_output/pyright.py +67 -0
- crackerjack/services/patterns/tool_output/ruff.py +44 -0
- crackerjack/services/patterns/url_sanitization.py +114 -0
- crackerjack/services/patterns/utilities.py +42 -0
- crackerjack/services/patterns/utils.py +339 -0
- crackerjack/services/patterns/validation.py +46 -0
- crackerjack/services/patterns/versioning.py +62 -0
- crackerjack/services/predictive_analytics.py +523 -0
- crackerjack/services/profiler.py +280 -0
- crackerjack/services/quality/README.md +415 -0
- crackerjack/services/quality/__init__.py +11 -0
- crackerjack/services/quality/anomaly_detector.py +392 -0
- crackerjack/services/quality/pattern_cache.py +333 -0
- crackerjack/services/quality/pattern_detector.py +479 -0
- crackerjack/services/quality/qa_orchestrator.py +491 -0
- crackerjack/services/quality/quality_baseline.py +395 -0
- crackerjack/services/quality/quality_baseline_enhanced.py +649 -0
- crackerjack/services/quality/quality_intelligence.py +949 -0
- crackerjack/services/regex_patterns.py +58 -0
- crackerjack/services/regex_utils.py +483 -0
- crackerjack/services/secure_path_utils.py +524 -0
- crackerjack/services/secure_status_formatter.py +450 -0
- crackerjack/services/secure_subprocess.py +635 -0
- crackerjack/services/security.py +239 -0
- crackerjack/services/security_logger.py +495 -0
- crackerjack/services/server_manager.py +411 -0
- crackerjack/services/smart_scheduling.py +167 -0
- crackerjack/services/status_authentication.py +460 -0
- crackerjack/services/status_security_manager.py +315 -0
- crackerjack/services/terminal_utils.py +0 -0
- crackerjack/services/thread_safe_status_collector.py +441 -0
- crackerjack/services/tool_filter.py +368 -0
- crackerjack/services/tool_version_service.py +43 -0
- crackerjack/services/unified_config.py +115 -0
- crackerjack/services/validation_rate_limiter.py +220 -0
- crackerjack/services/vector_store.py +689 -0
- crackerjack/services/version_analyzer.py +461 -0
- crackerjack/services/version_checker.py +223 -0
- crackerjack/services/websocket_resource_limiter.py +438 -0
- crackerjack/services/zuban_lsp_service.py +391 -0
- crackerjack/slash_commands/README.md +11 -0
- crackerjack/slash_commands/__init__.py +59 -0
- crackerjack/slash_commands/init.md +112 -0
- crackerjack/slash_commands/run.md +197 -0
- crackerjack/slash_commands/status.md +127 -0
- crackerjack/tools/README.md +11 -0
- crackerjack/tools/__init__.py +30 -0
- crackerjack/tools/_git_utils.py +105 -0
- crackerjack/tools/check_added_large_files.py +139 -0
- crackerjack/tools/check_ast.py +105 -0
- crackerjack/tools/check_json.py +103 -0
- crackerjack/tools/check_jsonschema.py +297 -0
- crackerjack/tools/check_toml.py +103 -0
- crackerjack/tools/check_yaml.py +110 -0
- crackerjack/tools/codespell_wrapper.py +72 -0
- crackerjack/tools/end_of_file_fixer.py +202 -0
- crackerjack/tools/format_json.py +128 -0
- crackerjack/tools/mdformat_wrapper.py +114 -0
- crackerjack/tools/trailing_whitespace.py +198 -0
- crackerjack/tools/validate_input_validator_patterns.py +236 -0
- crackerjack/tools/validate_regex_patterns.py +188 -0
- crackerjack/ui/README.md +11 -0
- crackerjack/ui/__init__.py +1 -0
- crackerjack/ui/dashboard_renderer.py +28 -0
- crackerjack/ui/templates/README.md +11 -0
- crackerjack/utils/console_utils.py +13 -0
- crackerjack/utils/dependency_guard.py +230 -0
- crackerjack/utils/retry_utils.py +275 -0
- crackerjack/workflows/README.md +590 -0
- crackerjack/workflows/__init__.py +46 -0
- crackerjack/workflows/actions.py +811 -0
- crackerjack/workflows/auto_fix.py +444 -0
- crackerjack/workflows/container_builder.py +499 -0
- crackerjack/workflows/definitions.py +443 -0
- crackerjack/workflows/engine.py +177 -0
- crackerjack/workflows/event_bridge.py +242 -0
- crackerjack-0.45.2.dist-info/METADATA +1678 -0
- crackerjack-0.45.2.dist-info/RECORD +478 -0
- {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
- crackerjack-0.45.2.dist-info/entry_points.txt +2 -0
- crackerjack/.gitignore +0 -14
- crackerjack/.libcst.codemod.yaml +0 -18
- crackerjack/.pdm.toml +0 -1
- crackerjack/.pre-commit-config.yaml +0 -91
- crackerjack/.pytest_cache/.gitignore +0 -2
- crackerjack/.pytest_cache/CACHEDIR.TAG +0 -4
- crackerjack/.pytest_cache/README.md +0 -8
- crackerjack/.pytest_cache/v/cache/nodeids +0 -1
- crackerjack/.pytest_cache/v/cache/stepwise +0 -1
- crackerjack/.ruff_cache/.gitignore +0 -1
- crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
- crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
- crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
- crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
- crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
- crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
- crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
- crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
- crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
- crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
- crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
- crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
- crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
- crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
- crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
- crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
- crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
- crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
- crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
- crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
- crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
- crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
- crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
- crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
- crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
- crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
- crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
- crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
- crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
- crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
- crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
- crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
- crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
- crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
- crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
- crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
- crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
- crackerjack/.ruff_cache/CACHEDIR.TAG +0 -1
- crackerjack/crackerjack.py +0 -855
- crackerjack/pyproject.toml +0 -214
- crackerjack-0.18.2.dist-info/METADATA +0 -420
- crackerjack-0.18.2.dist-info/RECORD +0 -59
- crackerjack-0.18.2.dist-info/entry_points.txt +0 -4
- {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import time
|
|
3
|
+
import typing as t
|
|
4
|
+
from contextlib import suppress
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Final
|
|
7
|
+
from uuid import UUID, uuid4
|
|
8
|
+
|
|
9
|
+
from acb import console as acb_console
|
|
10
|
+
from acb.depends import depends
|
|
11
|
+
from mcp_common.ui import ServerPanels
|
|
12
|
+
|
|
13
|
+
# Get the actual Console instance
|
|
14
|
+
console = acb_console.console
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
import tomli
|
|
18
|
+
except ImportError:
|
|
19
|
+
tomli = None # type: ignore[assignment]
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
from fastmcp import FastMCP
|
|
23
|
+
|
|
24
|
+
_mcp_available = True
|
|
25
|
+
except ImportError:
|
|
26
|
+
_mcp_available = False
|
|
27
|
+
FastMCP = None # type: ignore[misc,assignment,no-redef]
|
|
28
|
+
|
|
29
|
+
# Import FastMCP rate limiting middleware (Phase 3 Security Hardening)
|
|
30
|
+
try:
|
|
31
|
+
from fastmcp.server.middleware.rate_limiting import RateLimitingMiddleware
|
|
32
|
+
|
|
33
|
+
RATE_LIMITING_AVAILABLE = True
|
|
34
|
+
except ImportError:
|
|
35
|
+
RATE_LIMITING_AVAILABLE = False
|
|
36
|
+
|
|
37
|
+
MCP_AVAILABLE: Final[bool] = _mcp_available
|
|
38
|
+
|
|
39
|
+
# Phase 9.1: ACB Integration - Module registration for dependency injection
|
|
40
|
+
MODULE_ID: Final[UUID] = uuid4()
|
|
41
|
+
MODULE_STATUS: Final[str] = "stable"
|
|
42
|
+
|
|
43
|
+
from .context import (
|
|
44
|
+
MCPServerConfig,
|
|
45
|
+
MCPServerContext,
|
|
46
|
+
clear_context,
|
|
47
|
+
get_context,
|
|
48
|
+
set_context,
|
|
49
|
+
)
|
|
50
|
+
from .rate_limiter import RateLimitConfig
|
|
51
|
+
from .tools import (
|
|
52
|
+
register_core_tools,
|
|
53
|
+
register_execution_tools,
|
|
54
|
+
register_intelligence_tools,
|
|
55
|
+
register_monitoring_tools,
|
|
56
|
+
register_proactive_tools,
|
|
57
|
+
register_progress_tools,
|
|
58
|
+
register_semantic_tools,
|
|
59
|
+
register_utility_tools,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# console imported from acb
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _load_mcp_config(project_path: Path) -> dict[str, t.Any]:
|
|
66
|
+
pyproject_path = project_path / "pyproject.toml"
|
|
67
|
+
|
|
68
|
+
if not pyproject_path.exists() or not tomli:
|
|
69
|
+
return {
|
|
70
|
+
"http_port": 8676,
|
|
71
|
+
"http_host": "127.0.0.1",
|
|
72
|
+
"websocket_port": 8675,
|
|
73
|
+
"http_enabled": False,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
with pyproject_path.open("rb") as f:
|
|
78
|
+
pyproject_data = tomli.load(f)
|
|
79
|
+
|
|
80
|
+
crackerjack_config = pyproject_data.get("tool", {}).get("crackerjack", {})
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
"http_port": crackerjack_config.get("mcp_http_port", 8676),
|
|
84
|
+
"http_host": crackerjack_config.get("mcp_http_host", "127.0.0.1"),
|
|
85
|
+
"websocket_port": crackerjack_config.get("mcp_websocket_port", 8675),
|
|
86
|
+
"http_enabled": crackerjack_config.get("mcp_http_enabled", False),
|
|
87
|
+
}
|
|
88
|
+
except Exception as e:
|
|
89
|
+
console.print(
|
|
90
|
+
f"[yellow]Warning: Failed to load MCP config from pyproject.toml: {e}[/yellow]"
|
|
91
|
+
)
|
|
92
|
+
return {
|
|
93
|
+
"http_port": 8676,
|
|
94
|
+
"http_host": "127.0.0.1",
|
|
95
|
+
"websocket_port": 8675,
|
|
96
|
+
"http_enabled": False,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class MCPOptions:
|
|
101
|
+
def __init__(self, **kwargs: t.Any) -> None:
|
|
102
|
+
self.commit: bool = False
|
|
103
|
+
self.interactive: bool = False
|
|
104
|
+
self.no_config_updates: bool = False
|
|
105
|
+
self.verbose: bool = False
|
|
106
|
+
self.clean: bool = False
|
|
107
|
+
self.test: bool = False
|
|
108
|
+
self.autofix: bool = True
|
|
109
|
+
self.skip_hooks: bool = False
|
|
110
|
+
self.ai_agent: bool = False
|
|
111
|
+
self.ai_debug: bool = False
|
|
112
|
+
self.publish: str | None = None
|
|
113
|
+
self.bump: str | None = None
|
|
114
|
+
self.create_pr: bool = False
|
|
115
|
+
self.testing: bool = False
|
|
116
|
+
|
|
117
|
+
for key, value in kwargs.items():
|
|
118
|
+
if hasattr(self, key):
|
|
119
|
+
setattr(self, key, value)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _validate_job_id(job_id: str) -> bool:
|
|
123
|
+
if not job_id or not isinstance(job_id, str):
|
|
124
|
+
return False
|
|
125
|
+
if len(job_id) > 50:
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
from crackerjack.services.regex_patterns import is_valid_job_id
|
|
129
|
+
|
|
130
|
+
return is_valid_job_id(job_id)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
async def _start_websocket_server() -> bool:
|
|
134
|
+
context = get_context()
|
|
135
|
+
if context:
|
|
136
|
+
return await context.start_websocket_server()
|
|
137
|
+
return False
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def create_mcp_server(config: dict[str, t.Any] | None = None) -> t.Any | None:
|
|
141
|
+
if not MCP_AVAILABLE or FastMCP is None:
|
|
142
|
+
return None
|
|
143
|
+
|
|
144
|
+
if config is None:
|
|
145
|
+
config = {"http_port": 8676, "http_host": "127.0.0.1"}
|
|
146
|
+
|
|
147
|
+
mcp_app = FastMCP("crackerjack-mcp-server", streamable_http_path="/mcp")
|
|
148
|
+
|
|
149
|
+
# Add rate limiting middleware (Phase 3 Security Hardening)
|
|
150
|
+
if RATE_LIMITING_AVAILABLE:
|
|
151
|
+
rate_limiter = RateLimitingMiddleware(
|
|
152
|
+
max_requests_per_second=12.0, # Sustainable rate for code quality operations
|
|
153
|
+
burst_capacity=35, # Allow bursts for test/lint operations
|
|
154
|
+
global_limit=True, # Protect the crackerjack server globally
|
|
155
|
+
)
|
|
156
|
+
# Use public API (Phase 3.1 C1 fix: standardize middleware access)
|
|
157
|
+
mcp_app.add_middleware(rate_limiter)
|
|
158
|
+
|
|
159
|
+
from crackerjack.slash_commands import get_slash_command_path
|
|
160
|
+
|
|
161
|
+
@mcp_app.prompt(
|
|
162
|
+
"run",
|
|
163
|
+
description="Run Crackerjack quality checks with customizable options (hooks, tests, AI fixing)",
|
|
164
|
+
)
|
|
165
|
+
async def get_crackerjack_run_prompt() -> str:
|
|
166
|
+
try:
|
|
167
|
+
command_path = get_slash_command_path("run")
|
|
168
|
+
return command_path.read_text()
|
|
169
|
+
except Exception as e:
|
|
170
|
+
msg = f"Failed to read run command: {e}"
|
|
171
|
+
raise ValueError(msg)
|
|
172
|
+
|
|
173
|
+
@mcp_app.prompt(
|
|
174
|
+
"init",
|
|
175
|
+
description="Initialize Crackerjack in a new project (creates pyproject.toml config, pre-commit hooks)",
|
|
176
|
+
)
|
|
177
|
+
async def get_crackerjack_init_prompt() -> str:
|
|
178
|
+
try:
|
|
179
|
+
command_path = get_slash_command_path("init")
|
|
180
|
+
return command_path.read_text()
|
|
181
|
+
except Exception as e:
|
|
182
|
+
msg = f"Failed to read init command: {e}"
|
|
183
|
+
raise ValueError(msg)
|
|
184
|
+
|
|
185
|
+
@mcp_app.prompt(
|
|
186
|
+
"status",
|
|
187
|
+
description="Get comprehensive Crackerjack status (hooks, coverage, git state, server health)",
|
|
188
|
+
)
|
|
189
|
+
async def get_crackerjack_status_prompt() -> str:
|
|
190
|
+
try:
|
|
191
|
+
command_path = get_slash_command_path("status")
|
|
192
|
+
return command_path.read_text()
|
|
193
|
+
except Exception as e:
|
|
194
|
+
msg = f"Failed to read status command: {e}"
|
|
195
|
+
raise ValueError(msg)
|
|
196
|
+
|
|
197
|
+
register_core_tools(mcp_app)
|
|
198
|
+
register_execution_tools(mcp_app)
|
|
199
|
+
register_intelligence_tools(mcp_app)
|
|
200
|
+
register_monitoring_tools(mcp_app)
|
|
201
|
+
register_progress_tools(mcp_app)
|
|
202
|
+
register_proactive_tools(mcp_app)
|
|
203
|
+
register_semantic_tools(mcp_app)
|
|
204
|
+
register_utility_tools(mcp_app)
|
|
205
|
+
|
|
206
|
+
return mcp_app
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def handle_mcp_server_command(
|
|
210
|
+
start: bool = False,
|
|
211
|
+
stop: bool = False,
|
|
212
|
+
restart: bool = False,
|
|
213
|
+
websocket_port: int | None = None,
|
|
214
|
+
http_mode: bool = False,
|
|
215
|
+
http_port: int | None = None,
|
|
216
|
+
) -> None:
|
|
217
|
+
if stop or restart:
|
|
218
|
+
console.print("[yellow]Stopping MCP servers...[/ yellow]")
|
|
219
|
+
|
|
220
|
+
try:
|
|
221
|
+
result = subprocess.run(
|
|
222
|
+
["pkill", "-f", "crackerjack-mcp-server"],
|
|
223
|
+
check=False,
|
|
224
|
+
capture_output=True,
|
|
225
|
+
text=True,
|
|
226
|
+
timeout=10,
|
|
227
|
+
)
|
|
228
|
+
if result.returncode == 0:
|
|
229
|
+
console.print("[green]✅ MCP servers stopped[/ green]")
|
|
230
|
+
else:
|
|
231
|
+
console.print("[dim]No MCP servers were running[/ dim]")
|
|
232
|
+
except subprocess.TimeoutExpired:
|
|
233
|
+
console.print("[red]Timeout stopping MCP servers[/ red]")
|
|
234
|
+
except Exception as e:
|
|
235
|
+
console.print(f"[red]Error stopping MCP servers: {e}[/ red]")
|
|
236
|
+
|
|
237
|
+
if stop:
|
|
238
|
+
return
|
|
239
|
+
|
|
240
|
+
time.sleep(2)
|
|
241
|
+
|
|
242
|
+
if start or restart:
|
|
243
|
+
console.print("[green]Starting MCP server...[/ green]")
|
|
244
|
+
try:
|
|
245
|
+
main(".", websocket_port, http_mode, http_port)
|
|
246
|
+
except Exception as e:
|
|
247
|
+
console.print(f"[red]Failed to start MCP server: {e}[/ red]")
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def _initialize_context(context: MCPServerContext) -> None:
|
|
251
|
+
set_context(context)
|
|
252
|
+
|
|
253
|
+
context.safe_print("MCP Server context initialized")
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def _stop_websocket_server() -> None:
|
|
257
|
+
from contextlib import suppress
|
|
258
|
+
|
|
259
|
+
with suppress(RuntimeError):
|
|
260
|
+
context = get_context()
|
|
261
|
+
if context and hasattr(context, "_stop_websocket_server"):
|
|
262
|
+
pass
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def _merge_config_with_args(
|
|
266
|
+
mcp_config: dict[str, t.Any],
|
|
267
|
+
http_port: int | None,
|
|
268
|
+
http_mode: bool,
|
|
269
|
+
) -> dict[str, t.Any]:
|
|
270
|
+
if http_port:
|
|
271
|
+
mcp_config["http_port"] = http_port
|
|
272
|
+
if http_mode:
|
|
273
|
+
mcp_config["http_enabled"] = True
|
|
274
|
+
return mcp_config
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def _setup_server_context(
|
|
278
|
+
project_path: Path,
|
|
279
|
+
websocket_port: int | None,
|
|
280
|
+
) -> MCPServerContext:
|
|
281
|
+
config = MCPServerConfig(
|
|
282
|
+
project_path=project_path,
|
|
283
|
+
rate_limit_config=RateLimitConfig(),
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
context = MCPServerContext(config)
|
|
287
|
+
context.console = console
|
|
288
|
+
|
|
289
|
+
if websocket_port:
|
|
290
|
+
context.websocket_server_port = websocket_port
|
|
291
|
+
|
|
292
|
+
_initialize_context(context)
|
|
293
|
+
return context
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def _print_server_info(
|
|
297
|
+
project_path: Path,
|
|
298
|
+
mcp_config: dict[str, t.Any],
|
|
299
|
+
websocket_port: int | None,
|
|
300
|
+
http_mode: bool,
|
|
301
|
+
) -> None:
|
|
302
|
+
if mcp_config.get("http_enabled", False) or http_mode:
|
|
303
|
+
mode = "HTTP"
|
|
304
|
+
http_endpoint = (
|
|
305
|
+
f"http://{mcp_config['http_host']}:{mcp_config['http_port']}/mcp"
|
|
306
|
+
)
|
|
307
|
+
else:
|
|
308
|
+
mode = "STDIO"
|
|
309
|
+
http_endpoint = None
|
|
310
|
+
# Use mcp-common ServerPanels info panel
|
|
311
|
+
items: dict[str, str] = {
|
|
312
|
+
"Project": project_path.name,
|
|
313
|
+
"Mode": mode,
|
|
314
|
+
}
|
|
315
|
+
if http_endpoint:
|
|
316
|
+
items["HTTP"] = http_endpoint
|
|
317
|
+
if websocket_port:
|
|
318
|
+
items["WebSocket Port"] = str(websocket_port)
|
|
319
|
+
ServerPanels.info(
|
|
320
|
+
title="Server Configuration",
|
|
321
|
+
message="Starting Crackerjack MCP Server...",
|
|
322
|
+
items=items,
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def _run_mcp_server(
|
|
327
|
+
mcp_app: t.Any, mcp_config: dict[str, t.Any], http_mode: bool
|
|
328
|
+
) -> None:
|
|
329
|
+
console.print("[yellow]MCP app created, about to run...[/ yellow]")
|
|
330
|
+
|
|
331
|
+
try:
|
|
332
|
+
if mcp_config.get("http_enabled", False) or http_mode:
|
|
333
|
+
host = mcp_config.get("http_host", "127.0.0.1")
|
|
334
|
+
port = mcp_config.get("http_port", 8676)
|
|
335
|
+
mcp_app.run(transport="streamable-http", host=host, port=port)
|
|
336
|
+
else:
|
|
337
|
+
mcp_app.run()
|
|
338
|
+
except Exception as e:
|
|
339
|
+
console.print(f"[red]MCP run failed: {e}[/ red]")
|
|
340
|
+
import traceback
|
|
341
|
+
|
|
342
|
+
traceback.print_exc()
|
|
343
|
+
raise
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def _initialize_project_and_config(
|
|
347
|
+
project_path_arg: str,
|
|
348
|
+
http_port: int | None,
|
|
349
|
+
http_mode: bool,
|
|
350
|
+
) -> tuple[Path, dict[str, t.Any]]:
|
|
351
|
+
"""Initialize project path and config."""
|
|
352
|
+
project_path = Path(project_path_arg).resolve()
|
|
353
|
+
mcp_config = _load_mcp_config(project_path)
|
|
354
|
+
mcp_config = _merge_config_with_args(mcp_config, http_port, http_mode)
|
|
355
|
+
return project_path, mcp_config
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def _create_and_validate_server(mcp_config: dict[str, t.Any]) -> t.Any | None:
|
|
359
|
+
"""Create and validate the MCP server."""
|
|
360
|
+
mcp_app = create_mcp_server(mcp_config)
|
|
361
|
+
if not mcp_app:
|
|
362
|
+
console.print("[red]Failed to create MCP server[/ red]")
|
|
363
|
+
return mcp_app
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
def _start_websocket_if_needed(websocket_port: int | None) -> None:
|
|
367
|
+
"""Start WebSocket server if needed."""
|
|
368
|
+
if websocket_port:
|
|
369
|
+
import asyncio
|
|
370
|
+
|
|
371
|
+
try:
|
|
372
|
+
asyncio.run(_start_websocket_server())
|
|
373
|
+
console.print(
|
|
374
|
+
f"[green]✅ WebSocket server auto-started on port {websocket_port}[/green]"
|
|
375
|
+
)
|
|
376
|
+
except Exception as e:
|
|
377
|
+
console.print(f"[yellow]⚠️ WebSocket server auto-start failed: {e}[/yellow]")
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def _show_server_startup_info(
|
|
381
|
+
project_path: Path,
|
|
382
|
+
mcp_config: dict[str, t.Any],
|
|
383
|
+
websocket_port: int | None,
|
|
384
|
+
http_mode: bool,
|
|
385
|
+
) -> None:
|
|
386
|
+
"""Show server startup information."""
|
|
387
|
+
_print_server_info(project_path, mcp_config, websocket_port, http_mode)
|
|
388
|
+
|
|
389
|
+
# Show final success panel before starting the server
|
|
390
|
+
if mcp_config.get("http_enabled", False) or http_mode:
|
|
391
|
+
http_endpoint = (
|
|
392
|
+
f"http://{mcp_config['http_host']}:{mcp_config['http_port']}/mcp"
|
|
393
|
+
)
|
|
394
|
+
else:
|
|
395
|
+
http_endpoint = None
|
|
396
|
+
|
|
397
|
+
websocket_monitor = f"ws://127.0.0.1:{websocket_port}" if websocket_port else None
|
|
398
|
+
|
|
399
|
+
# Final startup success panel via mcp-common
|
|
400
|
+
if websocket_monitor:
|
|
401
|
+
ServerPanels.startup_success(
|
|
402
|
+
server_name="Crackerjack MCP",
|
|
403
|
+
endpoint=http_endpoint,
|
|
404
|
+
websocket_monitor=websocket_monitor, # type: ignore[arg-type]
|
|
405
|
+
)
|
|
406
|
+
else:
|
|
407
|
+
ServerPanels.startup_success(
|
|
408
|
+
server_name="Crackerjack MCP",
|
|
409
|
+
endpoint=http_endpoint,
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def main(
|
|
414
|
+
project_path_arg: str = ".",
|
|
415
|
+
websocket_port: int | None = None,
|
|
416
|
+
http_mode: bool = False,
|
|
417
|
+
http_port: int | None = None,
|
|
418
|
+
) -> None:
|
|
419
|
+
if not MCP_AVAILABLE:
|
|
420
|
+
return
|
|
421
|
+
|
|
422
|
+
try:
|
|
423
|
+
project_path, mcp_config = _initialize_project_and_config(
|
|
424
|
+
project_path_arg, http_port, http_mode
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
_setup_server_context(project_path, websocket_port)
|
|
428
|
+
|
|
429
|
+
mcp_app = _create_and_validate_server(mcp_config)
|
|
430
|
+
if not mcp_app:
|
|
431
|
+
return
|
|
432
|
+
|
|
433
|
+
_show_server_startup_info(project_path, mcp_config, websocket_port, http_mode)
|
|
434
|
+
|
|
435
|
+
_start_websocket_if_needed(websocket_port)
|
|
436
|
+
|
|
437
|
+
_run_mcp_server(mcp_app, mcp_config, http_mode)
|
|
438
|
+
|
|
439
|
+
except KeyboardInterrupt:
|
|
440
|
+
console.print("Server stopped by user")
|
|
441
|
+
except Exception as e:
|
|
442
|
+
console.print(f"Server error: {e}")
|
|
443
|
+
import traceback
|
|
444
|
+
|
|
445
|
+
traceback.print_exc()
|
|
446
|
+
finally:
|
|
447
|
+
_stop_websocket_server()
|
|
448
|
+
clear_context()
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
if __name__ == "__main__":
|
|
452
|
+
import sys
|
|
453
|
+
|
|
454
|
+
project_path = "."
|
|
455
|
+
websocket_port = None
|
|
456
|
+
http_mode = "--http" in sys.argv
|
|
457
|
+
http_port = None
|
|
458
|
+
|
|
459
|
+
non_flag_args = [arg for arg in sys.argv[1:] if not arg.startswith("--")]
|
|
460
|
+
if non_flag_args:
|
|
461
|
+
project_path = non_flag_args[0]
|
|
462
|
+
if len(non_flag_args) > 1 and non_flag_args[1].isdigit():
|
|
463
|
+
websocket_port = int(non_flag_args[1])
|
|
464
|
+
|
|
465
|
+
if "--http-port" in sys.argv:
|
|
466
|
+
port_idx = sys.argv.index("--http-port")
|
|
467
|
+
if port_idx + 1 < len(sys.argv):
|
|
468
|
+
http_port = int(sys.argv[port_idx + 1])
|
|
469
|
+
|
|
470
|
+
main(project_path, websocket_port, http_mode, http_port)
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
# Phase 9.1: ACB Integration - Service wrapper for dependency injection
|
|
474
|
+
class MCPServerService:
|
|
475
|
+
"""Service wrapper for MCP server to enable ACB dependency injection.
|
|
476
|
+
|
|
477
|
+
This class wraps the MCP server creation and management functions,
|
|
478
|
+
providing a clean interface for dependency injection via ACB.
|
|
479
|
+
"""
|
|
480
|
+
|
|
481
|
+
def __init__(self) -> None:
|
|
482
|
+
"""Initialize MCP server service."""
|
|
483
|
+
self.module_id = MODULE_ID
|
|
484
|
+
self.module_status = MODULE_STATUS
|
|
485
|
+
|
|
486
|
+
def create_server(self, config: dict[str, t.Any] | None = None) -> t.Any | None:
|
|
487
|
+
"""Create MCP server instance with optional configuration.
|
|
488
|
+
|
|
489
|
+
Args:
|
|
490
|
+
config: Server configuration dictionary
|
|
491
|
+
|
|
492
|
+
Returns:
|
|
493
|
+
FastMCP server instance or None if MCP unavailable
|
|
494
|
+
"""
|
|
495
|
+
return create_mcp_server(config)
|
|
496
|
+
|
|
497
|
+
def start_server(
|
|
498
|
+
self,
|
|
499
|
+
project_path: str = ".",
|
|
500
|
+
websocket_port: int | None = None,
|
|
501
|
+
http_mode: bool = False,
|
|
502
|
+
http_port: int | None = None,
|
|
503
|
+
) -> None:
|
|
504
|
+
"""Start MCP server with specified configuration.
|
|
505
|
+
|
|
506
|
+
Args:
|
|
507
|
+
project_path: Path to project directory
|
|
508
|
+
websocket_port: Optional WebSocket server port
|
|
509
|
+
http_mode: Enable HTTP mode instead of STDIO
|
|
510
|
+
http_port: Optional HTTP server port
|
|
511
|
+
"""
|
|
512
|
+
main(project_path, websocket_port, http_mode, http_port)
|
|
513
|
+
|
|
514
|
+
@property
|
|
515
|
+
def is_available(self) -> bool:
|
|
516
|
+
"""Check if MCP server functionality is available.
|
|
517
|
+
|
|
518
|
+
Returns:
|
|
519
|
+
True if FastMCP library is installed and available
|
|
520
|
+
"""
|
|
521
|
+
return MCP_AVAILABLE
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
# Phase 9.1: ACB Integration - Register service with dependency injection system
|
|
525
|
+
with suppress(Exception):
|
|
526
|
+
depends.set(MCPServerService)
|