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,714 @@
|
|
|
1
|
+
"""Issue parsing and classification for workflow failures.
|
|
2
|
+
|
|
3
|
+
Parses test and hook failures into structured Issue objects for AI agent processing.
|
|
4
|
+
Extracted from WorkflowOrchestrator to improve modularity and testability.
|
|
5
|
+
|
|
6
|
+
This module handles:
|
|
7
|
+
- Collection of test failure issues
|
|
8
|
+
- Collection of hook failure issues
|
|
9
|
+
- Classification of issues by type and priority
|
|
10
|
+
- Detection of specific error patterns (complexity, type, security, etc.)
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import typing as t
|
|
16
|
+
|
|
17
|
+
from acb.console import Console
|
|
18
|
+
from acb.depends import Inject, depends
|
|
19
|
+
|
|
20
|
+
from crackerjack.agents.base import Issue, IssueType, Priority
|
|
21
|
+
from crackerjack.models.protocols import (
|
|
22
|
+
DebugServiceProtocol,
|
|
23
|
+
LoggerProtocol,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class WorkflowIssueParser:
|
|
28
|
+
"""Parses and classifies workflow failures into structured issues.
|
|
29
|
+
|
|
30
|
+
This parser extracts issues from test failures and hook execution results,
|
|
31
|
+
classifying them by type (complexity, security, type errors, etc.) and
|
|
32
|
+
priority level for AI agent processing.
|
|
33
|
+
|
|
34
|
+
Uses dependency injection for all required services (Console, Logger, Debug).
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
@depends.inject
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
console: Inject[Console],
|
|
41
|
+
logger: Inject[LoggerProtocol],
|
|
42
|
+
debugger: Inject[DebugServiceProtocol],
|
|
43
|
+
) -> None:
|
|
44
|
+
"""Initialize the issue parser with injected dependencies.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
console: Console for output
|
|
48
|
+
logger: Logger for diagnostic messages
|
|
49
|
+
debugger: Debug service for detailed diagnostics
|
|
50
|
+
"""
|
|
51
|
+
self.console = console
|
|
52
|
+
self.logger = logger
|
|
53
|
+
self.debugger = debugger
|
|
54
|
+
|
|
55
|
+
async def _collect_issues_from_failures(
|
|
56
|
+
self,
|
|
57
|
+
phases: t.Any,
|
|
58
|
+
session: t.Any,
|
|
59
|
+
debug_enabled: bool = False,
|
|
60
|
+
) -> list[Issue]:
|
|
61
|
+
"""Collect all issues from test and hook failures.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
phases: PhaseCoordinator instance with test_manager and hook_manager
|
|
65
|
+
session: SessionCoordinator instance with session_tracker
|
|
66
|
+
debug_enabled: Whether debug mode is enabled
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
List of structured Issue objects for AI agent processing
|
|
70
|
+
"""
|
|
71
|
+
issues: list[Issue] = []
|
|
72
|
+
|
|
73
|
+
test_issues, test_count = self._collect_test_failure_issues(phases)
|
|
74
|
+
hook_issues, hook_count = self._collect_hook_failure_issues(phases, session)
|
|
75
|
+
|
|
76
|
+
issues.extend(test_issues)
|
|
77
|
+
issues.extend(hook_issues)
|
|
78
|
+
|
|
79
|
+
self._log_failure_counts_if_debugging(test_count, hook_count, debug_enabled)
|
|
80
|
+
|
|
81
|
+
return issues
|
|
82
|
+
|
|
83
|
+
def _collect_test_failure_issues(self, phases: t.Any) -> tuple[list[Issue], int]:
|
|
84
|
+
"""Collect issues from test failures.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
phases: PhaseCoordinator instance with test_manager
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Tuple of (list of test failure issues, count of test failures)
|
|
91
|
+
"""
|
|
92
|
+
issues: list[Issue] = []
|
|
93
|
+
test_count = 0
|
|
94
|
+
|
|
95
|
+
if hasattr(phases, "test_manager") and hasattr(
|
|
96
|
+
phases.test_manager,
|
|
97
|
+
"get_test_failures",
|
|
98
|
+
):
|
|
99
|
+
test_failures = phases.test_manager.get_test_failures()
|
|
100
|
+
test_count = len(test_failures)
|
|
101
|
+
for i, failure in enumerate(
|
|
102
|
+
test_failures[:20],
|
|
103
|
+
):
|
|
104
|
+
issue = Issue(
|
|
105
|
+
id=f"test_failure_{i}",
|
|
106
|
+
type=IssueType.TEST_FAILURE,
|
|
107
|
+
severity=Priority.HIGH,
|
|
108
|
+
message=failure.strip(),
|
|
109
|
+
stage="tests",
|
|
110
|
+
)
|
|
111
|
+
issues.append(issue)
|
|
112
|
+
|
|
113
|
+
return issues, test_count
|
|
114
|
+
|
|
115
|
+
def _collect_hook_failure_issues(
|
|
116
|
+
self, phases: t.Any, session: t.Any
|
|
117
|
+
) -> tuple[list[Issue], int]:
|
|
118
|
+
"""Collect issues from hook execution failures.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
phases: PhaseCoordinator instance with hook_manager
|
|
122
|
+
session: SessionCoordinator instance with session_tracker
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
Tuple of (list of hook failure issues, count of hook failures)
|
|
126
|
+
"""
|
|
127
|
+
issues: list[Issue] = []
|
|
128
|
+
hook_count = 0
|
|
129
|
+
|
|
130
|
+
try:
|
|
131
|
+
hook_results = phases.hook_manager.run_comprehensive_hooks()
|
|
132
|
+
issues, hook_count = self._process_hook_results(hook_results)
|
|
133
|
+
except Exception:
|
|
134
|
+
issues, hook_count = self._fallback_to_session_tracker(session)
|
|
135
|
+
|
|
136
|
+
return issues, hook_count
|
|
137
|
+
|
|
138
|
+
def _process_hook_results(self, hook_results: t.Any) -> tuple[list[Issue], int]:
|
|
139
|
+
"""Process hook execution results into issues.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
hook_results: Results from hook manager execution
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Tuple of (list of issues, count of failed hooks)
|
|
146
|
+
"""
|
|
147
|
+
issues: list[Issue] = []
|
|
148
|
+
hook_count = 0
|
|
149
|
+
|
|
150
|
+
for result in hook_results:
|
|
151
|
+
if not self._is_hook_result_failed(result):
|
|
152
|
+
continue
|
|
153
|
+
|
|
154
|
+
hook_count += 1
|
|
155
|
+
result_issues = self._extract_issues_from_hook_result(result)
|
|
156
|
+
issues.extend(result_issues)
|
|
157
|
+
|
|
158
|
+
return issues, hook_count
|
|
159
|
+
|
|
160
|
+
def _is_hook_result_failed(self, result: t.Any) -> bool:
|
|
161
|
+
"""Check if a hook result indicates failure.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
result: Hook execution result object
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
True if the hook failed, error occurred, or timed out
|
|
168
|
+
"""
|
|
169
|
+
return result.status in ("failed", "error", "timeout")
|
|
170
|
+
|
|
171
|
+
def _extract_issues_from_hook_result(self, result: t.Any) -> list[Issue]:
|
|
172
|
+
"""Extract structured issues from a failed hook result.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
result: Failed hook execution result
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
List of Issue objects parsed from the hook failure
|
|
179
|
+
"""
|
|
180
|
+
if result.issues_found:
|
|
181
|
+
return self._create_specific_issues_from_hook_result(result)
|
|
182
|
+
return [self._create_generic_issue_from_hook_result(result)]
|
|
183
|
+
|
|
184
|
+
def _create_specific_issues_from_hook_result(self, result: t.Any) -> list[Issue]:
|
|
185
|
+
"""Create specific issues from hook result with detailed issue information.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
result: Hook result with issues_found list
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
List of parsed and classified issues
|
|
192
|
+
"""
|
|
193
|
+
issues: list[Issue] = []
|
|
194
|
+
hook_context = f"{result.name}: "
|
|
195
|
+
|
|
196
|
+
for issue_text in result.issues_found:
|
|
197
|
+
parsed_issues = self._parse_issues_for_agents([hook_context + issue_text])
|
|
198
|
+
issues.extend(parsed_issues)
|
|
199
|
+
|
|
200
|
+
return issues
|
|
201
|
+
|
|
202
|
+
def _create_generic_issue_from_hook_result(self, result: t.Any) -> Issue:
|
|
203
|
+
"""Create a generic issue from a hook result without specific details.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
result: Failed hook execution result
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
Generic Issue object for the hook failure
|
|
210
|
+
"""
|
|
211
|
+
issue_type = self._determine_hook_issue_type(result.name)
|
|
212
|
+
return Issue(
|
|
213
|
+
id=f"hook_failure_{result.name}",
|
|
214
|
+
type=issue_type,
|
|
215
|
+
severity=Priority.MEDIUM,
|
|
216
|
+
message=f"Hook {result.name} failed with no specific details",
|
|
217
|
+
stage="comprehensive",
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
def _determine_hook_issue_type(self, hook_name: str) -> IssueType:
|
|
221
|
+
"""Determine issue type from hook name.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
hook_name: Name of the failed hook
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
IssueType classification based on hook name
|
|
228
|
+
"""
|
|
229
|
+
formatting_hooks = {
|
|
230
|
+
"trailing-whitespace",
|
|
231
|
+
"end-of-file-fixer",
|
|
232
|
+
"ruff-format",
|
|
233
|
+
"ruff-check",
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if hook_name == "validate-regex-patterns":
|
|
237
|
+
return IssueType.REGEX_VALIDATION
|
|
238
|
+
|
|
239
|
+
return (
|
|
240
|
+
IssueType.FORMATTING
|
|
241
|
+
if hook_name in formatting_hooks
|
|
242
|
+
else IssueType.TYPE_ERROR
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
def _fallback_to_session_tracker(self, session: t.Any) -> tuple[list[Issue], int]:
|
|
246
|
+
"""Fallback to session tracker when hook manager fails.
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
session: SessionCoordinator instance with session_tracker
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
Tuple of (list of issues, count of failed hooks)
|
|
253
|
+
"""
|
|
254
|
+
issues: list[Issue] = []
|
|
255
|
+
hook_count = 0
|
|
256
|
+
|
|
257
|
+
if not session.session_tracker:
|
|
258
|
+
return issues, hook_count
|
|
259
|
+
|
|
260
|
+
for task_id, task_data in session.session_tracker.tasks.items():
|
|
261
|
+
if self._is_failed_hook_task(task_data, task_id):
|
|
262
|
+
hook_count += 1
|
|
263
|
+
hook_issues = self._process_hook_failure(task_id, task_data)
|
|
264
|
+
issues.extend(hook_issues)
|
|
265
|
+
|
|
266
|
+
return issues, hook_count
|
|
267
|
+
|
|
268
|
+
def _is_failed_hook_task(self, task_data: t.Any, task_id: str) -> bool:
|
|
269
|
+
"""Check if a task is a failed hook task.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
task_data: Task data from session tracker
|
|
273
|
+
task_id: Task identifier
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
True if task is a failed hook task
|
|
277
|
+
"""
|
|
278
|
+
return task_data.status == "failed" and task_id in (
|
|
279
|
+
"fast_hooks",
|
|
280
|
+
"comprehensive_hooks",
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
def _process_hook_failure(self, task_id: str, task_data: t.Any) -> list[Issue]:
|
|
284
|
+
"""Process a hook failure from session tracker.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
task_id: Task identifier
|
|
288
|
+
task_data: Failed task data
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
List of issues parsed from the hook failure
|
|
292
|
+
"""
|
|
293
|
+
error_msg = getattr(task_data, "error_message", "Unknown error")
|
|
294
|
+
specific_issues = self._parse_hook_error_details(task_id, error_msg)
|
|
295
|
+
|
|
296
|
+
if specific_issues:
|
|
297
|
+
return specific_issues
|
|
298
|
+
|
|
299
|
+
return [self._create_generic_hook_issue(task_id, error_msg)]
|
|
300
|
+
|
|
301
|
+
def _create_generic_hook_issue(self, task_id: str, error_msg: str) -> Issue:
|
|
302
|
+
"""Create a generic issue from a hook task failure.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
task_id: Task identifier
|
|
306
|
+
error_msg: Error message from the task
|
|
307
|
+
|
|
308
|
+
Returns:
|
|
309
|
+
Generic Issue object for the hook failure
|
|
310
|
+
"""
|
|
311
|
+
issue_type = IssueType.FORMATTING if "fast" in task_id else IssueType.TYPE_ERROR
|
|
312
|
+
return Issue(
|
|
313
|
+
id=f"hook_failure_{task_id}",
|
|
314
|
+
type=issue_type,
|
|
315
|
+
severity=Priority.MEDIUM,
|
|
316
|
+
message=error_msg,
|
|
317
|
+
stage=task_id.replace("_hooks", ""),
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
def _parse_hook_error_details(self, task_id: str, error_msg: str) -> list[Issue]:
|
|
321
|
+
"""Parse specific error details from hook error messages.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
task_id: Task identifier
|
|
325
|
+
error_msg: Error message to parse
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
List of specific issues, or empty list if no patterns match
|
|
329
|
+
"""
|
|
330
|
+
issues: list[Issue] = []
|
|
331
|
+
|
|
332
|
+
if task_id == "comprehensive_hooks":
|
|
333
|
+
issues.extend(self._parse_comprehensive_hook_errors(error_msg))
|
|
334
|
+
elif task_id == "fast_hooks":
|
|
335
|
+
issues.append(self._create_fast_hook_issue())
|
|
336
|
+
|
|
337
|
+
return issues
|
|
338
|
+
|
|
339
|
+
def _parse_comprehensive_hook_errors(self, error_msg: str) -> list[Issue]:
|
|
340
|
+
"""Parse comprehensive hook errors using pattern checkers.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
error_msg: Error message from comprehensive hooks
|
|
344
|
+
|
|
345
|
+
Returns:
|
|
346
|
+
List of specific issues found in the error message
|
|
347
|
+
"""
|
|
348
|
+
error_lower = error_msg.lower()
|
|
349
|
+
error_checkers = self._get_comprehensive_error_checkers()
|
|
350
|
+
|
|
351
|
+
issues = []
|
|
352
|
+
for check_func in error_checkers:
|
|
353
|
+
issue = check_func(error_lower)
|
|
354
|
+
if issue:
|
|
355
|
+
issues.append(issue)
|
|
356
|
+
|
|
357
|
+
return issues
|
|
358
|
+
|
|
359
|
+
def _get_comprehensive_error_checkers(
|
|
360
|
+
self,
|
|
361
|
+
) -> list[t.Callable[[str], Issue | None]]:
|
|
362
|
+
"""Get list of error checking functions for comprehensive hooks.
|
|
363
|
+
|
|
364
|
+
Returns:
|
|
365
|
+
List of checker functions that return Issue if pattern matches
|
|
366
|
+
"""
|
|
367
|
+
return [
|
|
368
|
+
self._check_complexity_error,
|
|
369
|
+
self._check_type_error,
|
|
370
|
+
self._check_security_error,
|
|
371
|
+
self._check_performance_error,
|
|
372
|
+
self._check_dead_code_error,
|
|
373
|
+
self._check_regex_validation_error,
|
|
374
|
+
]
|
|
375
|
+
|
|
376
|
+
def _check_complexity_error(self, error_lower: str) -> Issue | None:
|
|
377
|
+
"""Check for complexity violation errors.
|
|
378
|
+
|
|
379
|
+
Args:
|
|
380
|
+
error_lower: Lowercase error message
|
|
381
|
+
|
|
382
|
+
Returns:
|
|
383
|
+
Issue if complexity error detected, None otherwise
|
|
384
|
+
"""
|
|
385
|
+
if "complexipy" in error_lower or "c901" in error_lower:
|
|
386
|
+
return Issue(
|
|
387
|
+
id="complexity_violation",
|
|
388
|
+
type=IssueType.COMPLEXITY,
|
|
389
|
+
severity=Priority.HIGH,
|
|
390
|
+
message="Code complexity violation detected",
|
|
391
|
+
stage="comprehensive",
|
|
392
|
+
)
|
|
393
|
+
return None
|
|
394
|
+
|
|
395
|
+
def _check_type_error(self, error_lower: str) -> Issue | None:
|
|
396
|
+
"""Check for type checking errors.
|
|
397
|
+
|
|
398
|
+
Args:
|
|
399
|
+
error_lower: Lowercase error message
|
|
400
|
+
|
|
401
|
+
Returns:
|
|
402
|
+
Issue if type error detected, None otherwise
|
|
403
|
+
"""
|
|
404
|
+
if "pyright" in error_lower:
|
|
405
|
+
return Issue(
|
|
406
|
+
id="pyright_type_error",
|
|
407
|
+
type=IssueType.TYPE_ERROR,
|
|
408
|
+
severity=Priority.HIGH,
|
|
409
|
+
message="Type checking errors detected by pyright",
|
|
410
|
+
stage="comprehensive",
|
|
411
|
+
)
|
|
412
|
+
return None
|
|
413
|
+
|
|
414
|
+
def _check_security_error(self, error_lower: str) -> Issue | None:
|
|
415
|
+
"""Check for security vulnerability errors.
|
|
416
|
+
|
|
417
|
+
Args:
|
|
418
|
+
error_lower: Lowercase error message
|
|
419
|
+
|
|
420
|
+
Returns:
|
|
421
|
+
Issue if security error detected, None otherwise
|
|
422
|
+
"""
|
|
423
|
+
if "bandit" in error_lower:
|
|
424
|
+
return Issue(
|
|
425
|
+
id="bandit_security_issue",
|
|
426
|
+
type=IssueType.SECURITY,
|
|
427
|
+
severity=Priority.HIGH,
|
|
428
|
+
message="Security vulnerabilities detected by bandit",
|
|
429
|
+
stage="comprehensive",
|
|
430
|
+
)
|
|
431
|
+
return None
|
|
432
|
+
|
|
433
|
+
def _check_performance_error(self, error_lower: str) -> Issue | None:
|
|
434
|
+
"""Check for performance/quality errors.
|
|
435
|
+
|
|
436
|
+
Args:
|
|
437
|
+
error_lower: Lowercase error message
|
|
438
|
+
|
|
439
|
+
Returns:
|
|
440
|
+
Issue if performance error detected, None otherwise
|
|
441
|
+
"""
|
|
442
|
+
if "refurb" in error_lower:
|
|
443
|
+
return Issue(
|
|
444
|
+
id="refurb_quality_issue",
|
|
445
|
+
type=IssueType.PERFORMANCE,
|
|
446
|
+
severity=Priority.MEDIUM,
|
|
447
|
+
message="Code quality issues detected by refurb",
|
|
448
|
+
stage="comprehensive",
|
|
449
|
+
)
|
|
450
|
+
return None
|
|
451
|
+
|
|
452
|
+
def _check_dead_code_error(self, error_lower: str) -> Issue | None:
|
|
453
|
+
"""Check for dead code errors.
|
|
454
|
+
|
|
455
|
+
Args:
|
|
456
|
+
error_lower: Lowercase error message
|
|
457
|
+
|
|
458
|
+
Returns:
|
|
459
|
+
Issue if dead code detected, None otherwise
|
|
460
|
+
"""
|
|
461
|
+
if "vulture" in error_lower:
|
|
462
|
+
return Issue(
|
|
463
|
+
id="vulture_dead_code",
|
|
464
|
+
type=IssueType.DEAD_CODE,
|
|
465
|
+
severity=Priority.MEDIUM,
|
|
466
|
+
message="Dead code detected by vulture",
|
|
467
|
+
stage="comprehensive",
|
|
468
|
+
)
|
|
469
|
+
return None
|
|
470
|
+
|
|
471
|
+
def _check_regex_validation_error(self, error_lower: str) -> Issue | None:
|
|
472
|
+
"""Check for regex validation errors.
|
|
473
|
+
|
|
474
|
+
Args:
|
|
475
|
+
error_lower: Lowercase error message
|
|
476
|
+
|
|
477
|
+
Returns:
|
|
478
|
+
Issue if regex validation error detected, None otherwise
|
|
479
|
+
"""
|
|
480
|
+
regex_keywords = ("raw regex", "regex pattern", r"\g<", "replacement")
|
|
481
|
+
if "validate-regex-patterns" in error_lower or any(
|
|
482
|
+
keyword in error_lower for keyword in regex_keywords
|
|
483
|
+
):
|
|
484
|
+
return Issue(
|
|
485
|
+
id="regex_validation_failure",
|
|
486
|
+
type=IssueType.REGEX_VALIDATION,
|
|
487
|
+
severity=Priority.HIGH,
|
|
488
|
+
message="Unsafe regex patterns detected by validate-regex-patterns",
|
|
489
|
+
stage="fast",
|
|
490
|
+
)
|
|
491
|
+
return None
|
|
492
|
+
|
|
493
|
+
def _create_fast_hook_issue(self) -> Issue:
|
|
494
|
+
"""Create an issue for fast hook formatting failures.
|
|
495
|
+
|
|
496
|
+
Returns:
|
|
497
|
+
Issue object for fast hook formatting failure
|
|
498
|
+
"""
|
|
499
|
+
return Issue(
|
|
500
|
+
id="fast_hooks_formatting",
|
|
501
|
+
type=IssueType.FORMATTING,
|
|
502
|
+
severity=Priority.LOW,
|
|
503
|
+
message="Code formatting issues detected",
|
|
504
|
+
stage="fast",
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
def _parse_issues_for_agents(self, issue_strings: list[str]) -> list[Issue]:
|
|
508
|
+
"""Parse issue strings into classified Issue objects.
|
|
509
|
+
|
|
510
|
+
Args:
|
|
511
|
+
issue_strings: List of issue description strings
|
|
512
|
+
|
|
513
|
+
Returns:
|
|
514
|
+
List of classified Issue objects
|
|
515
|
+
"""
|
|
516
|
+
issues: list[Issue] = []
|
|
517
|
+
|
|
518
|
+
for i, issue_str in enumerate(issue_strings):
|
|
519
|
+
issue_type, priority = self._classify_issue(issue_str)
|
|
520
|
+
|
|
521
|
+
issue = Issue(
|
|
522
|
+
id=f"parsed_issue_{i}",
|
|
523
|
+
type=issue_type,
|
|
524
|
+
severity=priority,
|
|
525
|
+
message=issue_str.strip(),
|
|
526
|
+
stage="comprehensive",
|
|
527
|
+
)
|
|
528
|
+
issues.append(issue)
|
|
529
|
+
|
|
530
|
+
return issues
|
|
531
|
+
|
|
532
|
+
def _classify_issue(self, issue_str: str) -> tuple[IssueType, Priority]:
|
|
533
|
+
"""Classify an issue string by type and priority.
|
|
534
|
+
|
|
535
|
+
Args:
|
|
536
|
+
issue_str: Issue description string
|
|
537
|
+
|
|
538
|
+
Returns:
|
|
539
|
+
Tuple of (IssueType, Priority) based on content analysis
|
|
540
|
+
"""
|
|
541
|
+
issue_lower = issue_str.lower()
|
|
542
|
+
|
|
543
|
+
# Check high priority issues first
|
|
544
|
+
high_priority_result = self._check_high_priority_issues(issue_lower)
|
|
545
|
+
if high_priority_result:
|
|
546
|
+
return high_priority_result
|
|
547
|
+
|
|
548
|
+
# Check medium priority issues
|
|
549
|
+
medium_priority_result = self._check_medium_priority_issues(issue_lower)
|
|
550
|
+
if medium_priority_result:
|
|
551
|
+
return medium_priority_result
|
|
552
|
+
|
|
553
|
+
# Default to formatting issue
|
|
554
|
+
return IssueType.FORMATTING, Priority.MEDIUM
|
|
555
|
+
|
|
556
|
+
def _check_high_priority_issues(
|
|
557
|
+
self, issue_lower: str
|
|
558
|
+
) -> tuple[IssueType, Priority] | None:
|
|
559
|
+
"""Check for high priority issue types.
|
|
560
|
+
|
|
561
|
+
Args:
|
|
562
|
+
issue_lower: Lowercase issue string
|
|
563
|
+
|
|
564
|
+
Returns:
|
|
565
|
+
Tuple of issue type and priority if found, None otherwise
|
|
566
|
+
"""
|
|
567
|
+
high_priority_checks = [
|
|
568
|
+
(self._is_type_error, IssueType.TYPE_ERROR),
|
|
569
|
+
(self._is_security_issue, IssueType.SECURITY),
|
|
570
|
+
(self._is_complexity_issue, IssueType.COMPLEXITY),
|
|
571
|
+
(self._is_regex_validation_issue, IssueType.REGEX_VALIDATION),
|
|
572
|
+
]
|
|
573
|
+
|
|
574
|
+
for check_func, issue_type in high_priority_checks:
|
|
575
|
+
if check_func(issue_lower):
|
|
576
|
+
return issue_type, Priority.HIGH
|
|
577
|
+
|
|
578
|
+
return None
|
|
579
|
+
|
|
580
|
+
def _check_medium_priority_issues(
|
|
581
|
+
self, issue_lower: str
|
|
582
|
+
) -> tuple[IssueType, Priority] | None:
|
|
583
|
+
"""Check for medium priority issue types.
|
|
584
|
+
|
|
585
|
+
Args:
|
|
586
|
+
issue_lower: Lowercase issue string
|
|
587
|
+
|
|
588
|
+
Returns:
|
|
589
|
+
Tuple of issue type and priority if found, None otherwise
|
|
590
|
+
"""
|
|
591
|
+
medium_priority_checks = [
|
|
592
|
+
(self._is_dead_code_issue, IssueType.DEAD_CODE),
|
|
593
|
+
(self._is_performance_issue, IssueType.PERFORMANCE),
|
|
594
|
+
(self._is_import_error, IssueType.IMPORT_ERROR),
|
|
595
|
+
]
|
|
596
|
+
|
|
597
|
+
for check_func, issue_type in medium_priority_checks:
|
|
598
|
+
if check_func(issue_lower):
|
|
599
|
+
return issue_type, Priority.MEDIUM
|
|
600
|
+
|
|
601
|
+
return None
|
|
602
|
+
|
|
603
|
+
def _is_type_error(self, issue_lower: str) -> bool:
|
|
604
|
+
"""Check if issue is a type error.
|
|
605
|
+
|
|
606
|
+
Args:
|
|
607
|
+
issue_lower: Lowercase issue string
|
|
608
|
+
|
|
609
|
+
Returns:
|
|
610
|
+
True if type error pattern detected
|
|
611
|
+
"""
|
|
612
|
+
return any(
|
|
613
|
+
keyword in issue_lower for keyword in ("type", "annotation", "pyright")
|
|
614
|
+
)
|
|
615
|
+
|
|
616
|
+
def _is_security_issue(self, issue_lower: str) -> bool:
|
|
617
|
+
"""Check if issue is a security concern.
|
|
618
|
+
|
|
619
|
+
Args:
|
|
620
|
+
issue_lower: Lowercase issue string
|
|
621
|
+
|
|
622
|
+
Returns:
|
|
623
|
+
True if security pattern detected
|
|
624
|
+
"""
|
|
625
|
+
return any(
|
|
626
|
+
keyword in issue_lower for keyword in ("security", "bandit", "hardcoded")
|
|
627
|
+
)
|
|
628
|
+
|
|
629
|
+
def _is_complexity_issue(self, issue_lower: str) -> bool:
|
|
630
|
+
"""Check if issue is a complexity violation.
|
|
631
|
+
|
|
632
|
+
Args:
|
|
633
|
+
issue_lower: Lowercase issue string
|
|
634
|
+
|
|
635
|
+
Returns:
|
|
636
|
+
True if complexity pattern detected
|
|
637
|
+
"""
|
|
638
|
+
return any(
|
|
639
|
+
keyword in issue_lower
|
|
640
|
+
for keyword in ("complexity", "complexipy", "c901", "too complex")
|
|
641
|
+
)
|
|
642
|
+
|
|
643
|
+
def _is_regex_validation_issue(self, issue_lower: str) -> bool:
|
|
644
|
+
"""Check if issue is a regex validation problem.
|
|
645
|
+
|
|
646
|
+
Args:
|
|
647
|
+
issue_lower: Lowercase issue string
|
|
648
|
+
|
|
649
|
+
Returns:
|
|
650
|
+
True if regex validation pattern detected
|
|
651
|
+
"""
|
|
652
|
+
return any(
|
|
653
|
+
keyword in issue_lower
|
|
654
|
+
for keyword in (
|
|
655
|
+
"regex",
|
|
656
|
+
"pattern",
|
|
657
|
+
"validate-regex-patterns",
|
|
658
|
+
r"\g<",
|
|
659
|
+
"replacement",
|
|
660
|
+
)
|
|
661
|
+
)
|
|
662
|
+
|
|
663
|
+
def _is_dead_code_issue(self, issue_lower: str) -> bool:
|
|
664
|
+
"""Check if issue is dead/unused code.
|
|
665
|
+
|
|
666
|
+
Args:
|
|
667
|
+
issue_lower: Lowercase issue string
|
|
668
|
+
|
|
669
|
+
Returns:
|
|
670
|
+
True if dead code pattern detected
|
|
671
|
+
"""
|
|
672
|
+
return any(keyword in issue_lower for keyword in ("unused", "dead", "vulture"))
|
|
673
|
+
|
|
674
|
+
def _is_performance_issue(self, issue_lower: str) -> bool:
|
|
675
|
+
"""Check if issue is a performance concern.
|
|
676
|
+
|
|
677
|
+
Args:
|
|
678
|
+
issue_lower: Lowercase issue string
|
|
679
|
+
|
|
680
|
+
Returns:
|
|
681
|
+
True if performance pattern detected
|
|
682
|
+
"""
|
|
683
|
+
return any(
|
|
684
|
+
keyword in issue_lower for keyword in ("performance", "refurb", "furb")
|
|
685
|
+
)
|
|
686
|
+
|
|
687
|
+
def _is_import_error(self, issue_lower: str) -> bool:
|
|
688
|
+
"""Check if issue is an import error.
|
|
689
|
+
|
|
690
|
+
Args:
|
|
691
|
+
issue_lower: Lowercase issue string
|
|
692
|
+
|
|
693
|
+
Returns:
|
|
694
|
+
True if import error pattern detected
|
|
695
|
+
"""
|
|
696
|
+
return any(keyword in issue_lower for keyword in ("import", "creosote"))
|
|
697
|
+
|
|
698
|
+
def _log_failure_counts_if_debugging(
|
|
699
|
+
self, test_count: int, hook_count: int, debug_enabled: bool
|
|
700
|
+
) -> None:
|
|
701
|
+
"""Log failure counts when debugging is enabled.
|
|
702
|
+
|
|
703
|
+
Args:
|
|
704
|
+
test_count: Number of test failures
|
|
705
|
+
hook_count: Number of hook failures
|
|
706
|
+
debug_enabled: Whether debug mode is enabled
|
|
707
|
+
"""
|
|
708
|
+
if debug_enabled:
|
|
709
|
+
self.debugger.log_test_failures(test_count)
|
|
710
|
+
self.debugger.log_hook_failures(hook_count)
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
# Register with ACB dependency injection
|
|
714
|
+
depends.set(WorkflowIssueParser, WorkflowIssueParser)
|