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,273 @@
|
|
|
1
|
+
"""Codespell adapter for ACB QA framework - spelling error detection.
|
|
2
|
+
|
|
3
|
+
Codespell checks for common spelling errors in code, comments, and documentation.
|
|
4
|
+
It helps maintain professional quality by catching:
|
|
5
|
+
- Typos in comments and docstrings
|
|
6
|
+
- Misspelled variable/function names
|
|
7
|
+
- Documentation errors
|
|
8
|
+
- Common spelling mistakes
|
|
9
|
+
|
|
10
|
+
ACB Patterns:
|
|
11
|
+
- MODULE_ID and MODULE_STATUS at module level
|
|
12
|
+
- depends.set() registration after class definition
|
|
13
|
+
- Extends BaseToolAdapter for tool execution
|
|
14
|
+
- Async execution with output parsing
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import typing as t
|
|
20
|
+
from contextlib import suppress
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from uuid import UUID, uuid4
|
|
23
|
+
|
|
24
|
+
from acb.depends import depends
|
|
25
|
+
from pydantic import Field
|
|
26
|
+
|
|
27
|
+
from crackerjack.adapters._tool_adapter_base import (
|
|
28
|
+
BaseToolAdapter,
|
|
29
|
+
ToolAdapterSettings,
|
|
30
|
+
ToolExecutionResult,
|
|
31
|
+
ToolIssue,
|
|
32
|
+
)
|
|
33
|
+
from crackerjack.models.qa_results import QACheckType
|
|
34
|
+
|
|
35
|
+
if t.TYPE_CHECKING:
|
|
36
|
+
from crackerjack.models.qa_config import QACheckConfig
|
|
37
|
+
|
|
38
|
+
# ACB Module Registration (REQUIRED)
|
|
39
|
+
MODULE_ID = uuid4()
|
|
40
|
+
MODULE_STATUS = "stable"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class CodespellSettings(ToolAdapterSettings):
|
|
44
|
+
"""Settings for Codespell adapter."""
|
|
45
|
+
|
|
46
|
+
tool_name: str = "codespell"
|
|
47
|
+
use_json_output: bool = False # Codespell uses text output
|
|
48
|
+
fix_enabled: bool = False # Auto-fix spelling errors
|
|
49
|
+
skip_hidden: bool = True
|
|
50
|
+
ignore_words: list[str] = Field(default_factory=list)
|
|
51
|
+
ignore_words_file: Path | None = None
|
|
52
|
+
check_filenames: bool = False
|
|
53
|
+
quiet_level: int = 2 # Only show errors
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class CodespellAdapter(BaseToolAdapter):
|
|
57
|
+
"""Adapter for Codespell - spelling error checker.
|
|
58
|
+
|
|
59
|
+
Detects and optionally fixes common spelling mistakes:
|
|
60
|
+
- Comments and docstrings
|
|
61
|
+
- String literals
|
|
62
|
+
- Variable and function names (optional)
|
|
63
|
+
- Documentation files
|
|
64
|
+
|
|
65
|
+
Features:
|
|
66
|
+
- Auto-fix support
|
|
67
|
+
- Custom ignore words
|
|
68
|
+
- Configurable scanning scope
|
|
69
|
+
- Multiple file type support
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
```python
|
|
73
|
+
settings = CodespellSettings(
|
|
74
|
+
fix_enabled=True,
|
|
75
|
+
ignore_words=["acb", "pydantic"],
|
|
76
|
+
skip_hidden=True,
|
|
77
|
+
)
|
|
78
|
+
adapter = CodespellAdapter(settings=settings)
|
|
79
|
+
await adapter.init()
|
|
80
|
+
result = await adapter.check(files=[Path("src/"), Path("docs/")])
|
|
81
|
+
```
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
settings: CodespellSettings | None = None
|
|
85
|
+
|
|
86
|
+
def __init__(self, settings: CodespellSettings | None = None) -> None:
|
|
87
|
+
"""Initialize Codespell adapter.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
settings: Optional settings override
|
|
91
|
+
"""
|
|
92
|
+
super().__init__(settings=settings)
|
|
93
|
+
|
|
94
|
+
async def init(self) -> None:
|
|
95
|
+
"""Initialize adapter with default settings."""
|
|
96
|
+
if not self.settings:
|
|
97
|
+
self.settings = await CodespellSettings.create_async()
|
|
98
|
+
await super().init()
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def adapter_name(self) -> str:
|
|
102
|
+
"""Human-readable adapter name."""
|
|
103
|
+
return "Codespell (Spelling)"
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def module_id(self) -> UUID:
|
|
107
|
+
"""Reference to module-level MODULE_ID."""
|
|
108
|
+
return MODULE_ID
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def tool_name(self) -> str:
|
|
112
|
+
"""CLI tool name."""
|
|
113
|
+
return "codespell"
|
|
114
|
+
|
|
115
|
+
def build_command(
|
|
116
|
+
self,
|
|
117
|
+
files: list[Path],
|
|
118
|
+
config: QACheckConfig | None = None,
|
|
119
|
+
) -> list[str]:
|
|
120
|
+
"""Build Codespell command.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
files: Files/directories to check
|
|
124
|
+
config: Optional configuration override
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
Command as list of strings
|
|
128
|
+
"""
|
|
129
|
+
if not self.settings:
|
|
130
|
+
raise RuntimeError("Settings not initialized")
|
|
131
|
+
|
|
132
|
+
cmd = [self.tool_name]
|
|
133
|
+
|
|
134
|
+
# Auto-fix
|
|
135
|
+
if self.settings.fix_enabled:
|
|
136
|
+
cmd.append("--write-changes")
|
|
137
|
+
|
|
138
|
+
# Skip hidden files
|
|
139
|
+
if self.settings.skip_hidden:
|
|
140
|
+
cmd.append("--skip=.*")
|
|
141
|
+
|
|
142
|
+
# Ignore specific words
|
|
143
|
+
if self.settings.ignore_words:
|
|
144
|
+
cmd.extend(["--ignore-words-list", ",".join(self.settings.ignore_words)])
|
|
145
|
+
|
|
146
|
+
# Ignore words file
|
|
147
|
+
if self.settings.ignore_words_file and self.settings.ignore_words_file.exists():
|
|
148
|
+
cmd.extend(["--ignore-words", str(self.settings.ignore_words_file)])
|
|
149
|
+
|
|
150
|
+
# Check filenames
|
|
151
|
+
if self.settings.check_filenames:
|
|
152
|
+
cmd.append("--check-filenames")
|
|
153
|
+
|
|
154
|
+
# Quiet level
|
|
155
|
+
cmd.extend(["--quiet-level", str(self.settings.quiet_level)])
|
|
156
|
+
|
|
157
|
+
# Add targets
|
|
158
|
+
cmd.extend([str(f) for f in files])
|
|
159
|
+
|
|
160
|
+
return cmd
|
|
161
|
+
|
|
162
|
+
def _parse_codespell_line(
|
|
163
|
+
self, line: str
|
|
164
|
+
) -> tuple[Path | None, int | None, str, str | None] | None:
|
|
165
|
+
"""Parse a single line from codespell output.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
line: A line from codespell output
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
Tuple of (file_path, line_number, message, suggestion) or None if parsing fails
|
|
172
|
+
"""
|
|
173
|
+
# Codespell format: "file.py:10: tyop ==> typo"
|
|
174
|
+
if ":" not in line or "==>" not in line:
|
|
175
|
+
return None
|
|
176
|
+
|
|
177
|
+
parts = line.split(":", maxsplit=2)
|
|
178
|
+
if len(parts) < 2:
|
|
179
|
+
return None
|
|
180
|
+
|
|
181
|
+
file_path = Path(parts[0].strip())
|
|
182
|
+
line_number = int(parts[1].strip()) if parts[1].strip().isdigit() else None
|
|
183
|
+
|
|
184
|
+
# Parse error and suggestion
|
|
185
|
+
error_part = parts[2].strip() if len(parts) > 2 else line
|
|
186
|
+
if "==>" in error_part:
|
|
187
|
+
wrong, correct = error_part.split("==>", maxsplit=1)
|
|
188
|
+
wrong = wrong.strip()
|
|
189
|
+
correct = correct.strip()
|
|
190
|
+
|
|
191
|
+
message = f"Spelling: '{wrong}' should be '{correct}'"
|
|
192
|
+
suggestion = f"Replace '{wrong}' with '{correct}'"
|
|
193
|
+
else:
|
|
194
|
+
message = error_part
|
|
195
|
+
suggestion = None
|
|
196
|
+
|
|
197
|
+
return file_path, line_number, message, suggestion
|
|
198
|
+
|
|
199
|
+
async def parse_output(
|
|
200
|
+
self,
|
|
201
|
+
result: ToolExecutionResult,
|
|
202
|
+
) -> list[ToolIssue]:
|
|
203
|
+
"""Parse Codespell text output into standardized issues.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
result: Raw execution result from Codespell
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
List of parsed issues
|
|
210
|
+
"""
|
|
211
|
+
if not result.raw_output:
|
|
212
|
+
return []
|
|
213
|
+
|
|
214
|
+
issues = []
|
|
215
|
+
lines = result.raw_output.strip().split("\n")
|
|
216
|
+
|
|
217
|
+
for line in lines:
|
|
218
|
+
parsed_result = self._parse_codespell_line(line)
|
|
219
|
+
if parsed_result is not None:
|
|
220
|
+
file_path, line_number, message, suggestion = parsed_result
|
|
221
|
+
|
|
222
|
+
issue = ToolIssue(
|
|
223
|
+
file_path=file_path,
|
|
224
|
+
line_number=line_number,
|
|
225
|
+
message=message,
|
|
226
|
+
code="SPELLING",
|
|
227
|
+
severity="warning",
|
|
228
|
+
suggestion=suggestion,
|
|
229
|
+
)
|
|
230
|
+
issues.append(issue)
|
|
231
|
+
|
|
232
|
+
return issues
|
|
233
|
+
|
|
234
|
+
def _get_check_type(self) -> QACheckType:
|
|
235
|
+
"""Return format check type."""
|
|
236
|
+
return QACheckType.FORMAT
|
|
237
|
+
|
|
238
|
+
def get_default_config(self) -> QACheckConfig:
|
|
239
|
+
"""Get default configuration for Codespell adapter.
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
QACheckConfig with sensible defaults
|
|
243
|
+
"""
|
|
244
|
+
from crackerjack.models.qa_config import QACheckConfig
|
|
245
|
+
|
|
246
|
+
return QACheckConfig(
|
|
247
|
+
check_id=MODULE_ID,
|
|
248
|
+
check_name=self.adapter_name,
|
|
249
|
+
check_type=QACheckType.FORMAT,
|
|
250
|
+
enabled=True,
|
|
251
|
+
file_patterns=["**/*.py", "**/*.md", "**/*.rst", "**/*.txt"],
|
|
252
|
+
exclude_patterns=[
|
|
253
|
+
"**/.git/**",
|
|
254
|
+
"**/.venv/**",
|
|
255
|
+
"**/node_modules/**",
|
|
256
|
+
"**/__pycache__/**",
|
|
257
|
+
],
|
|
258
|
+
timeout_seconds=60,
|
|
259
|
+
is_formatter=False, # Only checks, doesn't format
|
|
260
|
+
parallel_safe=True,
|
|
261
|
+
stage="fast", # Spelling checks in fast stage
|
|
262
|
+
settings={
|
|
263
|
+
"fix_enabled": False,
|
|
264
|
+
"skip_hidden": True,
|
|
265
|
+
"ignore_words": ["acb", "pydantic", "uuid"],
|
|
266
|
+
"check_filenames": False,
|
|
267
|
+
},
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
# ACB Registration (REQUIRED at module level)
|
|
272
|
+
with suppress(Exception):
|
|
273
|
+
depends.set(CodespellAdapter)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
> Crackerjack Docs: [Main](<../../../README.md>) | [Adapters](<../README.md>) | [LSP](<./README.md>)
|
|
2
|
+
|
|
3
|
+
# LSP Adapters
|
|
4
|
+
|
|
5
|
+
Rust-backed tools with Language Server Protocol integration for fast, incremental diagnostics.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
- Shared base (`_base.py`) defines `Issue`/`ToolResult` and adapter protocol
|
|
10
|
+
- Optional LSP paths for low-latency diagnostics, with CLI fallback
|
|
11
|
+
- Useful for continuous analysis in editors and orchestrated runs
|
|
12
|
+
|
|
13
|
+
## Built-in Implementations
|
|
14
|
+
|
|
15
|
+
| Module | Description | LSP | Status |
|
|
16
|
+
| ------ | ----------- | --- | ------ |
|
|
17
|
+
| `zuban.py` | Ultra-fast Python type checking with LSP and CLI fallback | Yes | Stable |
|
|
18
|
+
| `skylos.py` | Dead code detection with JSON/text parsing | N/A | Stable |
|
|
19
|
+
|
|
20
|
+
Support modules:
|
|
21
|
+
|
|
22
|
+
- `_client.py` — Optimized Zuban LSP client wrapper
|
|
23
|
+
- `_manager.py` — LSP process and workspace lifecycle helpers
|
|
24
|
+
- `_base.py` — Common protocol types and base adapter
|
|
25
|
+
|
|
26
|
+
## Zuban (LSP) Usage
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
from crackerjack.adapters.lsp.zuban import ZubanAdapter
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def typecheck_with_lsp(ctx) -> None:
|
|
34
|
+
adapter = ZubanAdapter(context=ctx, strict_mode=True, use_lsp=True)
|
|
35
|
+
result = await adapter.check_with_lsp_or_fallback([Path("src/")])
|
|
36
|
+
print("errors:", result.error_count, "warnings:", result.warning_count)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
CLI helpers are available to manage Zuban LSP via `python -m crackerjack` options (start/stop/restart).
|
|
40
|
+
|
|
41
|
+
## Notes
|
|
42
|
+
|
|
43
|
+
- LSP improves iteration speed; adapters transparently fall back to CLI
|
|
44
|
+
- Some Zuban builds may have TOML parsing issues; health checks guard usage
|
|
45
|
+
|
|
46
|
+
## Related
|
|
47
|
+
|
|
48
|
+
- [Type](<../type/README.md>) — Non-LSP type checkers and settings
|
|
49
|
+
- [Refactor](<../refactor/README.md>) — Skylos-based dead code detection
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""LSP adapter consolidation for Rust-based analysis tools.
|
|
2
|
+
|
|
3
|
+
This module consolidates all LSP-related adapter functionality:
|
|
4
|
+
- Zuban: Type checking with LSP integration
|
|
5
|
+
- Skylos: Dead code detection
|
|
6
|
+
- Base protocols and tool result structures
|
|
7
|
+
- Manager for coordinating multiple tools
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from ._base import BaseRustToolAdapter, Issue, RustToolAdapter, ToolResult
|
|
11
|
+
from ._client import ZubanLSPClient
|
|
12
|
+
from ._manager import RustToolHookManager
|
|
13
|
+
from .skylos import DeadCodeIssue, SkylosAdapter
|
|
14
|
+
from .zuban import TypeIssue, ZubanAdapter
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"RustToolAdapter",
|
|
18
|
+
"BaseRustToolAdapter",
|
|
19
|
+
"ToolResult",
|
|
20
|
+
"Issue",
|
|
21
|
+
"SkylosAdapter",
|
|
22
|
+
"DeadCodeIssue",
|
|
23
|
+
"ZubanAdapter",
|
|
24
|
+
"TypeIssue",
|
|
25
|
+
"RustToolHookManager",
|
|
26
|
+
"ZubanLSPClient",
|
|
27
|
+
]
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Base protocol and classes for Rust tool integration."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import typing as t
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Protocol
|
|
9
|
+
|
|
10
|
+
if t.TYPE_CHECKING:
|
|
11
|
+
from crackerjack.orchestration.execution_strategies import ExecutionContext
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class Issue:
|
|
16
|
+
"""Base class for tool issues."""
|
|
17
|
+
|
|
18
|
+
file_path: Path
|
|
19
|
+
line_number: int
|
|
20
|
+
message: str
|
|
21
|
+
severity: str = "error"
|
|
22
|
+
|
|
23
|
+
def to_dict(self) -> dict[str, t.Any]:
|
|
24
|
+
"""Convert issue to dictionary."""
|
|
25
|
+
return {
|
|
26
|
+
"file_path": str(self.file_path),
|
|
27
|
+
"line_number": self.line_number,
|
|
28
|
+
"message": self.message,
|
|
29
|
+
"severity": self.severity,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class ToolResult:
|
|
35
|
+
"""Unified result format for all Rust tools."""
|
|
36
|
+
|
|
37
|
+
success: bool
|
|
38
|
+
issues: list[Issue] = field(default_factory=list)
|
|
39
|
+
error: str | None = None
|
|
40
|
+
raw_output: str = ""
|
|
41
|
+
execution_time: float = 0.0
|
|
42
|
+
tool_version: str | None = None
|
|
43
|
+
_execution_mode: str | None = None
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def has_errors(self) -> bool:
|
|
47
|
+
"""Check if result contains error-level issues."""
|
|
48
|
+
return any(issue.severity == "error" for issue in self.issues)
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def error_count(self) -> int:
|
|
52
|
+
"""Count of error-level issues."""
|
|
53
|
+
return len([i for i in self.issues if i.severity == "error"])
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def warning_count(self) -> int:
|
|
57
|
+
"""Count of warning-level issues."""
|
|
58
|
+
return len([i for i in self.issues if i.severity == "warning"])
|
|
59
|
+
|
|
60
|
+
def to_dict(self) -> dict[str, t.Any]:
|
|
61
|
+
"""Convert result to dictionary."""
|
|
62
|
+
return {
|
|
63
|
+
"success": self.success,
|
|
64
|
+
"issues": [issue.to_dict() for issue in self.issues],
|
|
65
|
+
"error": self.error,
|
|
66
|
+
"raw_output": self.raw_output,
|
|
67
|
+
"execution_time": self.execution_time,
|
|
68
|
+
"tool_version": self.tool_version,
|
|
69
|
+
"error_count": self.error_count,
|
|
70
|
+
"warning_count": self.warning_count,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class RustToolAdapter(Protocol):
|
|
75
|
+
"""Protocol for Rust-based analysis tools."""
|
|
76
|
+
|
|
77
|
+
def __init__(self, context: "ExecutionContext") -> None:
|
|
78
|
+
"""Initialize adapter with execution context."""
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
def get_command_args(self, target_files: list[Path]) -> list[str]:
|
|
82
|
+
"""Get command arguments for tool execution."""
|
|
83
|
+
...
|
|
84
|
+
|
|
85
|
+
def parse_output(self, output: str) -> ToolResult:
|
|
86
|
+
"""Parse tool output into standardized result."""
|
|
87
|
+
...
|
|
88
|
+
|
|
89
|
+
def supports_json_output(self) -> bool:
|
|
90
|
+
"""Check if tool supports JSON output mode."""
|
|
91
|
+
...
|
|
92
|
+
|
|
93
|
+
def get_tool_version(self) -> str | None:
|
|
94
|
+
"""Get tool version if available."""
|
|
95
|
+
...
|
|
96
|
+
|
|
97
|
+
def validate_tool_available(self) -> bool:
|
|
98
|
+
"""Validate that the tool is available and executable."""
|
|
99
|
+
...
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class BaseRustToolAdapter(ABC):
|
|
103
|
+
"""Abstract base implementation of RustToolAdapter."""
|
|
104
|
+
|
|
105
|
+
def __init__(self, context: "ExecutionContext") -> None:
|
|
106
|
+
"""Initialize adapter with execution context."""
|
|
107
|
+
self.context = context
|
|
108
|
+
self._tool_version: str | None = None
|
|
109
|
+
|
|
110
|
+
@abstractmethod
|
|
111
|
+
def get_command_args(self, target_files: list[Path]) -> list[str]:
|
|
112
|
+
"""Get command arguments for tool execution."""
|
|
113
|
+
pass
|
|
114
|
+
|
|
115
|
+
@abstractmethod
|
|
116
|
+
def parse_output(self, output: str) -> ToolResult:
|
|
117
|
+
"""Parse tool output into standardized result."""
|
|
118
|
+
pass
|
|
119
|
+
|
|
120
|
+
@abstractmethod
|
|
121
|
+
def supports_json_output(self) -> bool:
|
|
122
|
+
"""Check if tool supports JSON output mode."""
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
@abstractmethod
|
|
126
|
+
def get_tool_name(self) -> str:
|
|
127
|
+
"""Get the name of the tool."""
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
def get_tool_version(self) -> str | None:
|
|
131
|
+
"""Get tool version if available."""
|
|
132
|
+
if self._tool_version is None:
|
|
133
|
+
self._tool_version = self._fetch_tool_version()
|
|
134
|
+
return self._tool_version
|
|
135
|
+
|
|
136
|
+
def validate_tool_available(self) -> bool:
|
|
137
|
+
"""Validate that the tool is available and executable."""
|
|
138
|
+
import subprocess
|
|
139
|
+
|
|
140
|
+
tool_name = self.get_tool_name()
|
|
141
|
+
try:
|
|
142
|
+
result = subprocess.run(
|
|
143
|
+
["which", tool_name], capture_output=True, text=True, check=False
|
|
144
|
+
)
|
|
145
|
+
return result.returncode == 0
|
|
146
|
+
except (subprocess.SubprocessError, FileNotFoundError):
|
|
147
|
+
return False
|
|
148
|
+
|
|
149
|
+
def _fetch_tool_version(self) -> str | None:
|
|
150
|
+
"""Fetch tool version from command line."""
|
|
151
|
+
import subprocess
|
|
152
|
+
|
|
153
|
+
tool_name = self.get_tool_name()
|
|
154
|
+
try:
|
|
155
|
+
result = subprocess.run(
|
|
156
|
+
[tool_name, "--version"],
|
|
157
|
+
capture_output=True,
|
|
158
|
+
text=True,
|
|
159
|
+
check=True,
|
|
160
|
+
timeout=10,
|
|
161
|
+
)
|
|
162
|
+
return result.stdout.strip().split("\\n")[0]
|
|
163
|
+
except (
|
|
164
|
+
subprocess.SubprocessError,
|
|
165
|
+
FileNotFoundError,
|
|
166
|
+
subprocess.TimeoutExpired,
|
|
167
|
+
):
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
def _should_use_json_output(self) -> bool:
|
|
171
|
+
"""Determine if JSON output should be used based on context."""
|
|
172
|
+
return self.supports_json_output() and (
|
|
173
|
+
self.context.ai_agent_mode or self.context.ai_debug_mode
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
def _parse_json_output_safe(self, output: str) -> dict[str, t.Any] | None:
|
|
177
|
+
"""Safely parse JSON output with error handling."""
|
|
178
|
+
try:
|
|
179
|
+
json_result = json.loads(output)
|
|
180
|
+
return t.cast(dict[str, t.Any] | None, json_result)
|
|
181
|
+
except json.JSONDecodeError:
|
|
182
|
+
# Log the error but don't fail completely
|
|
183
|
+
return None
|
|
184
|
+
|
|
185
|
+
def _create_error_result(
|
|
186
|
+
self, error_message: str, raw_output: str = ""
|
|
187
|
+
) -> ToolResult:
|
|
188
|
+
"""Create a ToolResult for error conditions."""
|
|
189
|
+
return ToolResult(
|
|
190
|
+
success=False,
|
|
191
|
+
error=error_message,
|
|
192
|
+
raw_output=raw_output,
|
|
193
|
+
tool_version=self.get_tool_version(),
|
|
194
|
+
)
|