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,283 @@
|
|
|
1
|
+
import typing as t
|
|
2
|
+
from contextlib import suppress
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def analyze_errors_with_caching(
|
|
6
|
+
context: t.Any, use_cache: bool = True
|
|
7
|
+
) -> dict[str, t.Any]:
|
|
8
|
+
try:
|
|
9
|
+
cached_patterns = _get_cached_patterns(context, use_cache)
|
|
10
|
+
return _build_error_analysis(cached_patterns, context)
|
|
11
|
+
|
|
12
|
+
except Exception as e:
|
|
13
|
+
return {
|
|
14
|
+
"status": "error",
|
|
15
|
+
"message": f"Error analysis failed: {e}",
|
|
16
|
+
"recommendations": [],
|
|
17
|
+
"patterns": [],
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _get_cached_patterns(context: t.Any, use_cache: bool) -> list[t.Any]:
|
|
22
|
+
if not use_cache:
|
|
23
|
+
return []
|
|
24
|
+
|
|
25
|
+
with suppress(Exception):
|
|
26
|
+
cache = getattr(context, "cache", None)
|
|
27
|
+
if cache and hasattr(cache, "get_error_patterns"):
|
|
28
|
+
patterns: list[t.Any] = cache.get_error_patterns()
|
|
29
|
+
return patterns
|
|
30
|
+
|
|
31
|
+
return []
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _build_error_analysis(patterns: list[t.Any], context: t.Any) -> dict[str, t.Any]:
|
|
35
|
+
analysis = {
|
|
36
|
+
"status": "success",
|
|
37
|
+
"patterns_found": len(patterns),
|
|
38
|
+
"recommendations": [],
|
|
39
|
+
"error_categories": {},
|
|
40
|
+
"fix_suggestions": [],
|
|
41
|
+
"urgency_level": "low",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if not patterns:
|
|
45
|
+
analysis.update(
|
|
46
|
+
{
|
|
47
|
+
"message": "No cached error patterns found-this indicates clean execution history",
|
|
48
|
+
"recommendations": [
|
|
49
|
+
"Continue with current development practices",
|
|
50
|
+
"Consider running comprehensive quality checks if issues arise",
|
|
51
|
+
],
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
return analysis
|
|
55
|
+
|
|
56
|
+
categories = _categorize_error_patterns(patterns)
|
|
57
|
+
analysis["error_categories"] = categories
|
|
58
|
+
|
|
59
|
+
recommendations = _generate_error_recommendations(categories)
|
|
60
|
+
analysis["recommendations"] = recommendations
|
|
61
|
+
|
|
62
|
+
analysis["urgency_level"] = _calculate_urgency_level(categories)
|
|
63
|
+
|
|
64
|
+
analysis["fix_suggestions"] = _generate_fix_suggestions(categories)
|
|
65
|
+
|
|
66
|
+
analysis["message"] = (
|
|
67
|
+
f"Found {len(patterns)} cached error patterns across {len(categories)} categories"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
return analysis
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _categorize_error_patterns(patterns: list[t.Any]) -> dict[str, list[t.Any]]:
|
|
74
|
+
categories: dict[str, list[t.Any]] = {
|
|
75
|
+
"syntax_errors": [],
|
|
76
|
+
"import_errors": [],
|
|
77
|
+
"type_errors": [],
|
|
78
|
+
"test_failures": [],
|
|
79
|
+
"security_issues": [],
|
|
80
|
+
"complexity_issues": [],
|
|
81
|
+
"dependency_issues": [],
|
|
82
|
+
"formatting_issues": [],
|
|
83
|
+
"unknown": [],
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
for pattern in patterns:
|
|
87
|
+
category = _classify_error_pattern(pattern)
|
|
88
|
+
categories[category].append(pattern)
|
|
89
|
+
|
|
90
|
+
return {k: v for k, v in categories.items() if v}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _classify_error_pattern(pattern: t.Any) -> str:
|
|
94
|
+
pattern_str = str(pattern).lower()
|
|
95
|
+
|
|
96
|
+
if any(
|
|
97
|
+
keyword in pattern_str
|
|
98
|
+
for keyword in ("syntax", "invalid syntax", "unexpected token")
|
|
99
|
+
):
|
|
100
|
+
return "syntax_errors"
|
|
101
|
+
elif any(
|
|
102
|
+
keyword in pattern_str for keyword in ("import", "module", "no module named")
|
|
103
|
+
):
|
|
104
|
+
return "import_errors"
|
|
105
|
+
elif any(
|
|
106
|
+
keyword in pattern_str for keyword in ("type", "annotation", "mypy", "pyright")
|
|
107
|
+
):
|
|
108
|
+
return "type_errors"
|
|
109
|
+
elif any(
|
|
110
|
+
keyword in pattern_str for keyword in ("test", "assert", "pytest", "failed")
|
|
111
|
+
):
|
|
112
|
+
return "test_failures"
|
|
113
|
+
elif any(
|
|
114
|
+
keyword in pattern_str for keyword in ("security", "bandit", "vulnerability")
|
|
115
|
+
):
|
|
116
|
+
return "security_issues"
|
|
117
|
+
elif any(
|
|
118
|
+
keyword in pattern_str for keyword in ("complexity", "complex", "cognitive")
|
|
119
|
+
):
|
|
120
|
+
return "complexity_issues"
|
|
121
|
+
elif any(
|
|
122
|
+
keyword in pattern_str for keyword in ("dependency", "requirement", "package")
|
|
123
|
+
):
|
|
124
|
+
return "dependency_issues"
|
|
125
|
+
elif any(
|
|
126
|
+
keyword in pattern_str for keyword in ("format", "style", "ruff", "black")
|
|
127
|
+
):
|
|
128
|
+
return "formatting_issues"
|
|
129
|
+
return "unknown"
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _generate_error_recommendations(categories: dict[str, list[t.Any]]) -> list[str]:
|
|
133
|
+
recommendations = []
|
|
134
|
+
|
|
135
|
+
if categories.get("syntax_errors"):
|
|
136
|
+
recommendations.append(
|
|
137
|
+
"🔧 Review syntax errors and fix basic Python syntax issues"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
if categories.get("import_errors"):
|
|
141
|
+
recommendations.extend(
|
|
142
|
+
[
|
|
143
|
+
"📦 Check imports and module dependencies",
|
|
144
|
+
"🔍 Verify all required packages are installed",
|
|
145
|
+
]
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
if categories.get("type_errors"):
|
|
149
|
+
recommendations.extend(
|
|
150
|
+
[
|
|
151
|
+
"🏷️ Add missing type annotations",
|
|
152
|
+
"🔧 Fix type mismatches and annotation issues",
|
|
153
|
+
]
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
if categories.get("test_failures"):
|
|
157
|
+
recommendations.extend(
|
|
158
|
+
[
|
|
159
|
+
"🧪 Fix failing tests and improve test reliability",
|
|
160
|
+
"🔬 Review test fixtures and dependencies",
|
|
161
|
+
]
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
if categories.get("security_issues"):
|
|
165
|
+
recommendations.extend(
|
|
166
|
+
[
|
|
167
|
+
"🔒 Address security vulnerabilities immediately",
|
|
168
|
+
"🛡️ Follow security best practices",
|
|
169
|
+
]
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
if categories.get("complexity_issues"):
|
|
173
|
+
recommendations.extend(
|
|
174
|
+
[
|
|
175
|
+
"📐 Refactor complex functions to reduce cognitive load",
|
|
176
|
+
"🔄 Break down large functions into smaller components",
|
|
177
|
+
]
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
if categories.get("dependency_issues"):
|
|
181
|
+
recommendations.extend(
|
|
182
|
+
[
|
|
183
|
+
"📚 Update dependency management",
|
|
184
|
+
"🔄 Review and clean up requirements",
|
|
185
|
+
]
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
if categories.get("formatting_issues"):
|
|
189
|
+
recommendations.extend(
|
|
190
|
+
[
|
|
191
|
+
"💅 Apply code formatting and style fixes",
|
|
192
|
+
"📋 Ensure consistent code style",
|
|
193
|
+
]
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
if len(categories) > 3:
|
|
197
|
+
recommendations.extend(
|
|
198
|
+
[
|
|
199
|
+
"🎯 Consider running AI agent auto-fixing for comprehensive resolution",
|
|
200
|
+
"📊 Monitor quality metrics to prevent regression",
|
|
201
|
+
]
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
return recommendations
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _calculate_urgency_level(categories: dict[str, list[t.Any]]) -> str:
|
|
208
|
+
total_errors = sum(len(errors) for errors in categories.values())
|
|
209
|
+
|
|
210
|
+
if categories.get("security_issues"):
|
|
211
|
+
return "high"
|
|
212
|
+
|
|
213
|
+
if categories.get("test_failures") and len(categories["test_failures"]) > 5:
|
|
214
|
+
return "high"
|
|
215
|
+
|
|
216
|
+
if categories.get("syntax_errors"):
|
|
217
|
+
return "medium"
|
|
218
|
+
|
|
219
|
+
if total_errors > 20:
|
|
220
|
+
return "medium"
|
|
221
|
+
|
|
222
|
+
if len(categories) > 4:
|
|
223
|
+
return "medium"
|
|
224
|
+
|
|
225
|
+
return "low"
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _generate_fix_suggestions(
|
|
229
|
+
categories: dict[str, list[t.Any]],
|
|
230
|
+
) -> list[dict[str, str]]:
|
|
231
|
+
suggestions = []
|
|
232
|
+
|
|
233
|
+
if categories.get("formatting_issues"):
|
|
234
|
+
suggestions.append(
|
|
235
|
+
{
|
|
236
|
+
"category": "formatting",
|
|
237
|
+
"action": "Run code formatting",
|
|
238
|
+
"command": "python - m crackerjack - - skip-tests",
|
|
239
|
+
"description": "Fix formatting and style issues",
|
|
240
|
+
}
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
if categories.get("type_errors"):
|
|
244
|
+
suggestions.append(
|
|
245
|
+
{
|
|
246
|
+
"category": "types",
|
|
247
|
+
"action": "Fix type annotations",
|
|
248
|
+
"command": "python - m crackerjack - - ai-agent",
|
|
249
|
+
"description": "Add missing type hints and resolve type conflicts",
|
|
250
|
+
}
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
if categories.get("test_failures"):
|
|
254
|
+
suggestions.append(
|
|
255
|
+
{
|
|
256
|
+
"category": "tests",
|
|
257
|
+
"action": "Fix test failures",
|
|
258
|
+
"command": "python - m crackerjack - t - - ai-agent",
|
|
259
|
+
"description": "Run tests with AI auto-fixing enabled",
|
|
260
|
+
}
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
if categories.get("security_issues"):
|
|
264
|
+
suggestions.append(
|
|
265
|
+
{
|
|
266
|
+
"category": "security",
|
|
267
|
+
"action": "Address security issues",
|
|
268
|
+
"command": "python - m crackerjack - - ai - agent-t",
|
|
269
|
+
"description": "Fix security vulnerabilities with AI assistance",
|
|
270
|
+
}
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
if len(categories) > 3:
|
|
274
|
+
suggestions.append(
|
|
275
|
+
{
|
|
276
|
+
"category": "comprehensive",
|
|
277
|
+
"action": "Full quality check with AI fixing",
|
|
278
|
+
"command": "python - m crackerjack - - ai - agent-t",
|
|
279
|
+
"description": "Comprehensive quality check with autonomous fixing",
|
|
280
|
+
}
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
return suggestions
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typing as t
|
|
3
|
+
|
|
4
|
+
from crackerjack.mcp.context import get_context
|
|
5
|
+
|
|
6
|
+
from .error_analyzer import analyze_errors_with_caching
|
|
7
|
+
from .workflow_executor import execute_crackerjack_workflow
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def register_execution_tools(mcp_app: t.Any) -> None:
|
|
11
|
+
_register_execute_crackerjack_tool(mcp_app)
|
|
12
|
+
_register_smart_error_analysis_tool(mcp_app)
|
|
13
|
+
_register_init_crackerjack_tool(mcp_app)
|
|
14
|
+
_register_agent_suggestions_tool(mcp_app)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _register_execute_crackerjack_tool(mcp_app: t.Any) -> None:
|
|
18
|
+
@mcp_app.tool() # type: ignore[misc]
|
|
19
|
+
async def execute_crackerjack(args: str, kwargs: str) -> str:
|
|
20
|
+
try:
|
|
21
|
+
context = get_context()
|
|
22
|
+
validation_error = await _handle_context_validation(context)
|
|
23
|
+
if validation_error:
|
|
24
|
+
return validation_error
|
|
25
|
+
|
|
26
|
+
kwargs_result = _parse_kwargs(kwargs)
|
|
27
|
+
if "error" in kwargs_result:
|
|
28
|
+
return json.dumps(kwargs_result)
|
|
29
|
+
|
|
30
|
+
extra_kwargs = _prepare_execution_kwargs(kwargs_result["kwargs"])
|
|
31
|
+
result = await execute_crackerjack_workflow(args, extra_kwargs)
|
|
32
|
+
return json.dumps(result, indent=2)
|
|
33
|
+
except TypeError as e:
|
|
34
|
+
return _handle_type_error(e)
|
|
35
|
+
except Exception as e:
|
|
36
|
+
return _handle_general_error(e)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
async def _handle_context_validation(context: t.Any) -> str | None:
|
|
40
|
+
"""Handle context validation with proper error handling."""
|
|
41
|
+
from datetime import datetime
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
validation_error = await _validate_context_and_rate_limit(context)
|
|
45
|
+
if validation_error:
|
|
46
|
+
return validation_error
|
|
47
|
+
return None
|
|
48
|
+
except TypeError as e:
|
|
49
|
+
if "NoneType" in str(e) and "await" in str(e):
|
|
50
|
+
return json.dumps(
|
|
51
|
+
{
|
|
52
|
+
"status": "failed",
|
|
53
|
+
"error": "Context validation failed: rate limiter returned None. "
|
|
54
|
+
"MCP server may not be properly initialized.",
|
|
55
|
+
"timestamp": datetime.now().isoformat(),
|
|
56
|
+
"details": str(e),
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
raise
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _prepare_execution_kwargs(kwargs: dict[str, t.Any]) -> dict[str, t.Any]:
|
|
63
|
+
"""Prepare execution kwargs with appropriate timeout defaults."""
|
|
64
|
+
if "execution_timeout" not in kwargs:
|
|
65
|
+
if kwargs.get("test", False) or kwargs.get("testing", False):
|
|
66
|
+
kwargs["execution_timeout"] = 1200
|
|
67
|
+
else:
|
|
68
|
+
kwargs["execution_timeout"] = 900
|
|
69
|
+
return kwargs
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _handle_type_error(error: TypeError) -> str:
|
|
73
|
+
"""Handle TypeError with specific async execution error details."""
|
|
74
|
+
import traceback
|
|
75
|
+
from datetime import datetime
|
|
76
|
+
|
|
77
|
+
if "NoneType" in str(error) and "await" in str(error):
|
|
78
|
+
return json.dumps(
|
|
79
|
+
{
|
|
80
|
+
"status": "failed",
|
|
81
|
+
"error": f"Async execution error: A function returned None instead of an awaitable. {error}",
|
|
82
|
+
"traceback": traceback.format_exc(),
|
|
83
|
+
"timestamp": datetime.now().isoformat(),
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
raise error
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _handle_general_error(error: Exception) -> str:
|
|
90
|
+
"""Handle general execution errors with traceback."""
|
|
91
|
+
import traceback
|
|
92
|
+
from datetime import datetime
|
|
93
|
+
|
|
94
|
+
context = get_context()
|
|
95
|
+
return json.dumps(
|
|
96
|
+
{
|
|
97
|
+
"status": "failed",
|
|
98
|
+
"error": f"Execution failed: {error}",
|
|
99
|
+
"traceback": traceback.format_exc(),
|
|
100
|
+
"timestamp": context.get_current_time()
|
|
101
|
+
if context and hasattr(context, "get_current_time")
|
|
102
|
+
else datetime.now().isoformat(),
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _register_smart_error_analysis_tool(mcp_app: t.Any) -> None:
|
|
108
|
+
@mcp_app.tool() # type: ignore[misc]
|
|
109
|
+
async def smart_error_analysis(use_cache: bool = True) -> str:
|
|
110
|
+
context = get_context()
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
analysis = analyze_errors_with_caching(context, use_cache)
|
|
114
|
+
return json.dumps(analysis, indent=2)
|
|
115
|
+
except Exception as e:
|
|
116
|
+
return json.dumps(
|
|
117
|
+
{
|
|
118
|
+
"status": "error",
|
|
119
|
+
"message": f"Error analysis failed: {e}",
|
|
120
|
+
"recommendations": [],
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _register_init_crackerjack_tool(mcp_app: t.Any) -> None:
|
|
126
|
+
@mcp_app.tool() # type: ignore[misc]
|
|
127
|
+
def init_crackerjack(args: str = "", kwargs: str = "{}") -> str:
|
|
128
|
+
try:
|
|
129
|
+
target_path, force, error = _parse_init_arguments(args, kwargs)
|
|
130
|
+
if error:
|
|
131
|
+
return _create_init_error_response(error)
|
|
132
|
+
|
|
133
|
+
result = _execute_initialization(target_path, force)
|
|
134
|
+
return _create_init_success_response(result)
|
|
135
|
+
|
|
136
|
+
except Exception as e:
|
|
137
|
+
return _create_init_exception_response(e, args)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _register_agent_suggestions_tool(mcp_app: t.Any) -> None:
|
|
141
|
+
@mcp_app.tool() # type: ignore[misc]
|
|
142
|
+
def suggest_agents(
|
|
143
|
+
task_description: str = "",
|
|
144
|
+
project_type: str = "python",
|
|
145
|
+
current_context: str = "",
|
|
146
|
+
) -> str:
|
|
147
|
+
try:
|
|
148
|
+
recommendations = _generate_agent_recommendations(
|
|
149
|
+
task_description, project_type, current_context
|
|
150
|
+
)
|
|
151
|
+
return json.dumps(recommendations, indent=2)
|
|
152
|
+
except Exception as e:
|
|
153
|
+
return json.dumps(
|
|
154
|
+
{
|
|
155
|
+
"status": "error",
|
|
156
|
+
"message": f"Agent suggestion failed: {e}",
|
|
157
|
+
"recommendations": {},
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
async def _validate_context_and_rate_limit(context: t.Any) -> str | None:
|
|
163
|
+
if not context:
|
|
164
|
+
return json.dumps({"status": "error", "message": "MCP context not available"})
|
|
165
|
+
|
|
166
|
+
if hasattr(context, "rate_limiter"):
|
|
167
|
+
from contextlib import suppress
|
|
168
|
+
|
|
169
|
+
with suppress(Exception):
|
|
170
|
+
allowed, details = await context.rate_limiter.check_request_allowed(
|
|
171
|
+
"execute_crackerjack"
|
|
172
|
+
)
|
|
173
|
+
if not allowed:
|
|
174
|
+
return json.dumps(
|
|
175
|
+
{
|
|
176
|
+
"status": "error",
|
|
177
|
+
"message": f"Rate limit exceeded: {details}. Please wait before retrying.",
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
return None
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _parse_kwargs(kwargs: str) -> dict[str, t.Any]:
|
|
185
|
+
try:
|
|
186
|
+
return {"kwargs": json.loads(kwargs) if kwargs.strip() else {}}
|
|
187
|
+
except json.JSONDecodeError as e:
|
|
188
|
+
return {"error": f"Invalid JSON in kwargs: {e}"}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _parse_init_arguments(args: str, kwargs: str) -> tuple[t.Any, bool, str | None]:
|
|
192
|
+
try:
|
|
193
|
+
target_path = args.strip() or "."
|
|
194
|
+
kwargs_dict: dict[str, t.Any] = json.loads(kwargs) if kwargs.strip() else {}
|
|
195
|
+
force = kwargs_dict.get("force") or False
|
|
196
|
+
|
|
197
|
+
from pathlib import Path
|
|
198
|
+
|
|
199
|
+
path_obj = Path(target_path)
|
|
200
|
+
|
|
201
|
+
return path_obj, force, None
|
|
202
|
+
|
|
203
|
+
except json.JSONDecodeError:
|
|
204
|
+
return None, False, "Invalid JSON in kwargs parameter"
|
|
205
|
+
except Exception as e:
|
|
206
|
+
return None, False, f"Invalid arguments: {e}"
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _execute_initialization(target_path: t.Any, force: bool) -> dict[str, t.Any]:
|
|
210
|
+
from acb.console import Console
|
|
211
|
+
from acb.depends import Inject, depends
|
|
212
|
+
|
|
213
|
+
from crackerjack.services.filesystem import FileSystemService
|
|
214
|
+
from crackerjack.services.git import GitService
|
|
215
|
+
from crackerjack.services.initialization import InitializationService
|
|
216
|
+
|
|
217
|
+
@depends.inject
|
|
218
|
+
def _execute_initialization(
|
|
219
|
+
target_path: t.Any, force: bool, console: Inject[Console]
|
|
220
|
+
) -> dict[str, t.Any]:
|
|
221
|
+
filesystem = FileSystemService()
|
|
222
|
+
git_service = GitService(target_path)
|
|
223
|
+
return InitializationService(
|
|
224
|
+
filesystem, git_service, target_path
|
|
225
|
+
).initialize_project_full(force=force)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _create_init_error_response(message: str) -> str:
|
|
229
|
+
return json.dumps(
|
|
230
|
+
{
|
|
231
|
+
"status": "error",
|
|
232
|
+
"message": message,
|
|
233
|
+
"initialized": False,
|
|
234
|
+
}
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _create_init_success_response(result: dict[str, t.Any]) -> str:
|
|
239
|
+
return json.dumps(
|
|
240
|
+
{
|
|
241
|
+
"status": "success",
|
|
242
|
+
"message": "Crackerjack configuration initialized successfully",
|
|
243
|
+
"result": result,
|
|
244
|
+
"initialized": True,
|
|
245
|
+
},
|
|
246
|
+
indent=2,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def _create_init_exception_response(error: Exception, target_path: t.Any) -> str:
|
|
251
|
+
return json.dumps(
|
|
252
|
+
{
|
|
253
|
+
"status": "error",
|
|
254
|
+
"message": f"Initialization failed: {error}",
|
|
255
|
+
"target_path": str(target_path),
|
|
256
|
+
"initialized": False,
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def _generate_agent_recommendations(
|
|
262
|
+
task_description: str, project_type: str, current_context: str
|
|
263
|
+
) -> dict[str, t.Any]:
|
|
264
|
+
recommendations = {
|
|
265
|
+
"status": "success",
|
|
266
|
+
"task_analysis": {
|
|
267
|
+
"description": task_description,
|
|
268
|
+
"project_type": project_type,
|
|
269
|
+
"context": current_context,
|
|
270
|
+
},
|
|
271
|
+
"suggested_agents": [],
|
|
272
|
+
"workflow_recommendations": [],
|
|
273
|
+
"reasoning": "",
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
suggestions = _analyze_task_for_agents(
|
|
277
|
+
task_description, project_type, current_context
|
|
278
|
+
)
|
|
279
|
+
recommendations["suggested_agents"] = suggestions["agents"]
|
|
280
|
+
recommendations["workflow_recommendations"] = suggestions["workflows"]
|
|
281
|
+
recommendations["reasoning"] = suggestions["reasoning"]
|
|
282
|
+
|
|
283
|
+
return recommendations
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def _analyze_task_for_agents(
|
|
287
|
+
task_description: str, project_type: str, current_context: str
|
|
288
|
+
) -> dict[str, t.Any]:
|
|
289
|
+
agents = []
|
|
290
|
+
workflows = []
|
|
291
|
+
reasoning_parts = []
|
|
292
|
+
|
|
293
|
+
task_lower = task_description.lower()
|
|
294
|
+
current_context.lower()
|
|
295
|
+
|
|
296
|
+
if any(keyword in task_lower for keyword in ("test", "quality", "fix", "error")):
|
|
297
|
+
agents.extend(
|
|
298
|
+
[
|
|
299
|
+
{
|
|
300
|
+
"name": "TestCreationAgent",
|
|
301
|
+
"reason": "Task involves testing or quality assurance",
|
|
302
|
+
"confidence": 0.8,
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"name": "RefactoringAgent",
|
|
306
|
+
"reason": "Code quality improvements often require refactoring",
|
|
307
|
+
"confidence": 0.7,
|
|
308
|
+
},
|
|
309
|
+
]
|
|
310
|
+
)
|
|
311
|
+
reasoning_parts.append("Task involves testing or quality improvement")
|
|
312
|
+
|
|
313
|
+
if any(
|
|
314
|
+
keyword in task_lower for keyword in ("security", "vulnerability", "secure")
|
|
315
|
+
):
|
|
316
|
+
agents.append(
|
|
317
|
+
{
|
|
318
|
+
"name": "SecurityAgent",
|
|
319
|
+
"reason": "Task involves security considerations",
|
|
320
|
+
"confidence": 0.9,
|
|
321
|
+
}
|
|
322
|
+
)
|
|
323
|
+
reasoning_parts.append("Security concerns detected")
|
|
324
|
+
|
|
325
|
+
if any(
|
|
326
|
+
keyword in task_lower
|
|
327
|
+
for keyword in ("performance", "optimize", "speed", "slow")
|
|
328
|
+
):
|
|
329
|
+
agents.append(
|
|
330
|
+
{
|
|
331
|
+
"name": "PerformanceAgent",
|
|
332
|
+
"reason": "Task involves performance optimization",
|
|
333
|
+
"confidence": 0.8,
|
|
334
|
+
}
|
|
335
|
+
)
|
|
336
|
+
reasoning_parts.append("Performance optimization required")
|
|
337
|
+
|
|
338
|
+
if any(
|
|
339
|
+
keyword in task_lower for keyword in ("document", "readme", "doc", "explain")
|
|
340
|
+
):
|
|
341
|
+
agents.append(
|
|
342
|
+
{
|
|
343
|
+
"name": "DocumentationAgent",
|
|
344
|
+
"reason": "Task involves documentation work",
|
|
345
|
+
"confidence": 0.8,
|
|
346
|
+
}
|
|
347
|
+
)
|
|
348
|
+
reasoning_parts.append("Documentation work identified")
|
|
349
|
+
|
|
350
|
+
if any(
|
|
351
|
+
keyword in task_lower
|
|
352
|
+
for keyword in ("import", "dependency", "package", "module")
|
|
353
|
+
):
|
|
354
|
+
agents.append(
|
|
355
|
+
{
|
|
356
|
+
"name": "ImportOptimizationAgent",
|
|
357
|
+
"reason": "Task involves import or dependency management",
|
|
358
|
+
"confidence": 0.7,
|
|
359
|
+
}
|
|
360
|
+
)
|
|
361
|
+
reasoning_parts.append("Import / dependency work detected")
|
|
362
|
+
|
|
363
|
+
if project_type == "python":
|
|
364
|
+
workflows.extend(
|
|
365
|
+
[
|
|
366
|
+
"Run quality checks with AI agent auto-fixing",
|
|
367
|
+
"Use comprehensive testing with coverage tracking",
|
|
368
|
+
"Apply refactoring for code clarity",
|
|
369
|
+
]
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
if not agents:
|
|
373
|
+
agents.append(
|
|
374
|
+
{
|
|
375
|
+
"name": "RefactoringAgent",
|
|
376
|
+
"reason": "Default agent for general code improvement tasks",
|
|
377
|
+
"confidence": 0.5,
|
|
378
|
+
}
|
|
379
|
+
)
|
|
380
|
+
reasoning_parts.append("General code improvement task")
|
|
381
|
+
|
|
382
|
+
reasoning = "; ".join(reasoning_parts)
|
|
383
|
+
|
|
384
|
+
return {"agents": agents, "workflows": workflows, "reasoning": reasoning}
|