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.
Files changed (533) hide show
  1. crackerjack/README.md +19 -0
  2. crackerjack/__init__.py +96 -2
  3. crackerjack/__main__.py +637 -138
  4. crackerjack/adapters/README.md +18 -0
  5. crackerjack/adapters/__init__.py +39 -0
  6. crackerjack/adapters/_output_paths.py +167 -0
  7. crackerjack/adapters/_qa_adapter_base.py +309 -0
  8. crackerjack/adapters/_tool_adapter_base.py +706 -0
  9. crackerjack/adapters/ai/README.md +65 -0
  10. crackerjack/adapters/ai/__init__.py +5 -0
  11. crackerjack/adapters/ai/claude.py +853 -0
  12. crackerjack/adapters/complexity/README.md +53 -0
  13. crackerjack/adapters/complexity/__init__.py +10 -0
  14. crackerjack/adapters/complexity/complexipy.py +641 -0
  15. crackerjack/adapters/dependency/__init__.py +22 -0
  16. crackerjack/adapters/dependency/pip_audit.py +418 -0
  17. crackerjack/adapters/format/README.md +72 -0
  18. crackerjack/adapters/format/__init__.py +11 -0
  19. crackerjack/adapters/format/mdformat.py +313 -0
  20. crackerjack/adapters/format/ruff.py +516 -0
  21. crackerjack/adapters/lint/README.md +47 -0
  22. crackerjack/adapters/lint/__init__.py +11 -0
  23. crackerjack/adapters/lint/codespell.py +273 -0
  24. crackerjack/adapters/lsp/README.md +49 -0
  25. crackerjack/adapters/lsp/__init__.py +27 -0
  26. crackerjack/adapters/lsp/_base.py +194 -0
  27. crackerjack/adapters/lsp/_client.py +358 -0
  28. crackerjack/adapters/lsp/_manager.py +193 -0
  29. crackerjack/adapters/lsp/skylos.py +283 -0
  30. crackerjack/adapters/lsp/zuban.py +557 -0
  31. crackerjack/adapters/refactor/README.md +59 -0
  32. crackerjack/adapters/refactor/__init__.py +12 -0
  33. crackerjack/adapters/refactor/creosote.py +318 -0
  34. crackerjack/adapters/refactor/refurb.py +406 -0
  35. crackerjack/adapters/refactor/skylos.py +494 -0
  36. crackerjack/adapters/sast/README.md +132 -0
  37. crackerjack/adapters/sast/__init__.py +32 -0
  38. crackerjack/adapters/sast/_base.py +201 -0
  39. crackerjack/adapters/sast/bandit.py +423 -0
  40. crackerjack/adapters/sast/pyscn.py +405 -0
  41. crackerjack/adapters/sast/semgrep.py +241 -0
  42. crackerjack/adapters/security/README.md +111 -0
  43. crackerjack/adapters/security/__init__.py +17 -0
  44. crackerjack/adapters/security/gitleaks.py +339 -0
  45. crackerjack/adapters/type/README.md +52 -0
  46. crackerjack/adapters/type/__init__.py +12 -0
  47. crackerjack/adapters/type/pyrefly.py +402 -0
  48. crackerjack/adapters/type/ty.py +402 -0
  49. crackerjack/adapters/type/zuban.py +522 -0
  50. crackerjack/adapters/utility/README.md +51 -0
  51. crackerjack/adapters/utility/__init__.py +10 -0
  52. crackerjack/adapters/utility/checks.py +884 -0
  53. crackerjack/agents/README.md +264 -0
  54. crackerjack/agents/__init__.py +66 -0
  55. crackerjack/agents/architect_agent.py +238 -0
  56. crackerjack/agents/base.py +167 -0
  57. crackerjack/agents/claude_code_bridge.py +641 -0
  58. crackerjack/agents/coordinator.py +600 -0
  59. crackerjack/agents/documentation_agent.py +520 -0
  60. crackerjack/agents/dry_agent.py +585 -0
  61. crackerjack/agents/enhanced_coordinator.py +279 -0
  62. crackerjack/agents/enhanced_proactive_agent.py +185 -0
  63. crackerjack/agents/error_middleware.py +53 -0
  64. crackerjack/agents/formatting_agent.py +230 -0
  65. crackerjack/agents/helpers/__init__.py +9 -0
  66. crackerjack/agents/helpers/performance/__init__.py +22 -0
  67. crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
  68. crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
  69. crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
  70. crackerjack/agents/helpers/refactoring/__init__.py +22 -0
  71. crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
  72. crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
  73. crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
  74. crackerjack/agents/helpers/test_creation/__init__.py +19 -0
  75. crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
  76. crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
  77. crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
  78. crackerjack/agents/import_optimization_agent.py +1181 -0
  79. crackerjack/agents/performance_agent.py +325 -0
  80. crackerjack/agents/performance_helpers.py +205 -0
  81. crackerjack/agents/proactive_agent.py +55 -0
  82. crackerjack/agents/refactoring_agent.py +511 -0
  83. crackerjack/agents/refactoring_helpers.py +247 -0
  84. crackerjack/agents/security_agent.py +793 -0
  85. crackerjack/agents/semantic_agent.py +479 -0
  86. crackerjack/agents/semantic_helpers.py +356 -0
  87. crackerjack/agents/test_creation_agent.py +570 -0
  88. crackerjack/agents/test_specialist_agent.py +526 -0
  89. crackerjack/agents/tracker.py +110 -0
  90. crackerjack/api.py +647 -0
  91. crackerjack/cli/README.md +394 -0
  92. crackerjack/cli/__init__.py +24 -0
  93. crackerjack/cli/cache_handlers.py +209 -0
  94. crackerjack/cli/cache_handlers_enhanced.py +680 -0
  95. crackerjack/cli/facade.py +162 -0
  96. crackerjack/cli/formatting.py +13 -0
  97. crackerjack/cli/handlers/__init__.py +85 -0
  98. crackerjack/cli/handlers/advanced.py +103 -0
  99. crackerjack/cli/handlers/ai_features.py +62 -0
  100. crackerjack/cli/handlers/analytics.py +479 -0
  101. crackerjack/cli/handlers/changelog.py +271 -0
  102. crackerjack/cli/handlers/config_handlers.py +16 -0
  103. crackerjack/cli/handlers/coverage.py +84 -0
  104. crackerjack/cli/handlers/documentation.py +280 -0
  105. crackerjack/cli/handlers/main_handlers.py +497 -0
  106. crackerjack/cli/handlers/monitoring.py +371 -0
  107. crackerjack/cli/handlers.py +700 -0
  108. crackerjack/cli/interactive.py +488 -0
  109. crackerjack/cli/options.py +1216 -0
  110. crackerjack/cli/semantic_handlers.py +292 -0
  111. crackerjack/cli/utils.py +19 -0
  112. crackerjack/cli/version.py +19 -0
  113. crackerjack/code_cleaner.py +1307 -0
  114. crackerjack/config/README.md +472 -0
  115. crackerjack/config/__init__.py +275 -0
  116. crackerjack/config/global_lock_config.py +207 -0
  117. crackerjack/config/hooks.py +390 -0
  118. crackerjack/config/loader.py +239 -0
  119. crackerjack/config/settings.py +141 -0
  120. crackerjack/config/tool_commands.py +331 -0
  121. crackerjack/core/README.md +393 -0
  122. crackerjack/core/__init__.py +0 -0
  123. crackerjack/core/async_workflow_orchestrator.py +738 -0
  124. crackerjack/core/autofix_coordinator.py +282 -0
  125. crackerjack/core/container.py +105 -0
  126. crackerjack/core/enhanced_container.py +583 -0
  127. crackerjack/core/file_lifecycle.py +472 -0
  128. crackerjack/core/performance.py +244 -0
  129. crackerjack/core/performance_monitor.py +357 -0
  130. crackerjack/core/phase_coordinator.py +1227 -0
  131. crackerjack/core/proactive_workflow.py +267 -0
  132. crackerjack/core/resource_manager.py +425 -0
  133. crackerjack/core/retry.py +275 -0
  134. crackerjack/core/service_watchdog.py +601 -0
  135. crackerjack/core/session_coordinator.py +239 -0
  136. crackerjack/core/timeout_manager.py +563 -0
  137. crackerjack/core/websocket_lifecycle.py +410 -0
  138. crackerjack/core/workflow/__init__.py +21 -0
  139. crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
  140. crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
  141. crackerjack/core/workflow/workflow_issue_parser.py +714 -0
  142. crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
  143. crackerjack/core/workflow/workflow_security_gates.py +400 -0
  144. crackerjack/core/workflow_orchestrator.py +2243 -0
  145. crackerjack/data/README.md +11 -0
  146. crackerjack/data/__init__.py +8 -0
  147. crackerjack/data/models.py +79 -0
  148. crackerjack/data/repository.py +210 -0
  149. crackerjack/decorators/README.md +180 -0
  150. crackerjack/decorators/__init__.py +35 -0
  151. crackerjack/decorators/error_handling.py +649 -0
  152. crackerjack/decorators/error_handling_decorators.py +334 -0
  153. crackerjack/decorators/helpers.py +58 -0
  154. crackerjack/decorators/patterns.py +281 -0
  155. crackerjack/decorators/utils.py +58 -0
  156. crackerjack/docs/INDEX.md +11 -0
  157. crackerjack/docs/README.md +11 -0
  158. crackerjack/docs/generated/api/API_REFERENCE.md +10895 -0
  159. crackerjack/docs/generated/api/CLI_REFERENCE.md +109 -0
  160. crackerjack/docs/generated/api/CROSS_REFERENCES.md +1755 -0
  161. crackerjack/docs/generated/api/PROTOCOLS.md +3 -0
  162. crackerjack/docs/generated/api/SERVICES.md +1252 -0
  163. crackerjack/documentation/README.md +11 -0
  164. crackerjack/documentation/__init__.py +31 -0
  165. crackerjack/documentation/ai_templates.py +756 -0
  166. crackerjack/documentation/dual_output_generator.py +767 -0
  167. crackerjack/documentation/mkdocs_integration.py +518 -0
  168. crackerjack/documentation/reference_generator.py +1065 -0
  169. crackerjack/dynamic_config.py +678 -0
  170. crackerjack/errors.py +378 -0
  171. crackerjack/events/README.md +11 -0
  172. crackerjack/events/__init__.py +16 -0
  173. crackerjack/events/telemetry.py +175 -0
  174. crackerjack/events/workflow_bus.py +346 -0
  175. crackerjack/exceptions/README.md +301 -0
  176. crackerjack/exceptions/__init__.py +5 -0
  177. crackerjack/exceptions/config.py +4 -0
  178. crackerjack/exceptions/tool_execution_error.py +245 -0
  179. crackerjack/executors/README.md +591 -0
  180. crackerjack/executors/__init__.py +13 -0
  181. crackerjack/executors/async_hook_executor.py +938 -0
  182. crackerjack/executors/cached_hook_executor.py +316 -0
  183. crackerjack/executors/hook_executor.py +1295 -0
  184. crackerjack/executors/hook_lock_manager.py +708 -0
  185. crackerjack/executors/individual_hook_executor.py +739 -0
  186. crackerjack/executors/lsp_aware_hook_executor.py +349 -0
  187. crackerjack/executors/progress_hook_executor.py +282 -0
  188. crackerjack/executors/tool_proxy.py +433 -0
  189. crackerjack/hooks/README.md +485 -0
  190. crackerjack/hooks/lsp_hook.py +93 -0
  191. crackerjack/intelligence/README.md +557 -0
  192. crackerjack/intelligence/__init__.py +37 -0
  193. crackerjack/intelligence/adaptive_learning.py +693 -0
  194. crackerjack/intelligence/agent_orchestrator.py +485 -0
  195. crackerjack/intelligence/agent_registry.py +377 -0
  196. crackerjack/intelligence/agent_selector.py +439 -0
  197. crackerjack/intelligence/integration.py +250 -0
  198. crackerjack/interactive.py +719 -0
  199. crackerjack/managers/README.md +369 -0
  200. crackerjack/managers/__init__.py +11 -0
  201. crackerjack/managers/async_hook_manager.py +135 -0
  202. crackerjack/managers/hook_manager.py +585 -0
  203. crackerjack/managers/publish_manager.py +631 -0
  204. crackerjack/managers/test_command_builder.py +391 -0
  205. crackerjack/managers/test_executor.py +474 -0
  206. crackerjack/managers/test_manager.py +1357 -0
  207. crackerjack/managers/test_progress.py +187 -0
  208. crackerjack/mcp/README.md +374 -0
  209. crackerjack/mcp/__init__.py +0 -0
  210. crackerjack/mcp/cache.py +352 -0
  211. crackerjack/mcp/client_runner.py +121 -0
  212. crackerjack/mcp/context.py +802 -0
  213. crackerjack/mcp/dashboard.py +657 -0
  214. crackerjack/mcp/enhanced_progress_monitor.py +493 -0
  215. crackerjack/mcp/file_monitor.py +394 -0
  216. crackerjack/mcp/progress_components.py +607 -0
  217. crackerjack/mcp/progress_monitor.py +1016 -0
  218. crackerjack/mcp/rate_limiter.py +336 -0
  219. crackerjack/mcp/server.py +24 -0
  220. crackerjack/mcp/server_core.py +526 -0
  221. crackerjack/mcp/service_watchdog.py +505 -0
  222. crackerjack/mcp/state.py +407 -0
  223. crackerjack/mcp/task_manager.py +259 -0
  224. crackerjack/mcp/tools/README.md +27 -0
  225. crackerjack/mcp/tools/__init__.py +19 -0
  226. crackerjack/mcp/tools/core_tools.py +469 -0
  227. crackerjack/mcp/tools/error_analyzer.py +283 -0
  228. crackerjack/mcp/tools/execution_tools.py +384 -0
  229. crackerjack/mcp/tools/intelligence_tool_registry.py +46 -0
  230. crackerjack/mcp/tools/intelligence_tools.py +264 -0
  231. crackerjack/mcp/tools/monitoring_tools.py +628 -0
  232. crackerjack/mcp/tools/proactive_tools.py +367 -0
  233. crackerjack/mcp/tools/progress_tools.py +222 -0
  234. crackerjack/mcp/tools/semantic_tools.py +584 -0
  235. crackerjack/mcp/tools/utility_tools.py +358 -0
  236. crackerjack/mcp/tools/workflow_executor.py +699 -0
  237. crackerjack/mcp/websocket/README.md +31 -0
  238. crackerjack/mcp/websocket/__init__.py +14 -0
  239. crackerjack/mcp/websocket/app.py +54 -0
  240. crackerjack/mcp/websocket/endpoints.py +492 -0
  241. crackerjack/mcp/websocket/event_bridge.py +188 -0
  242. crackerjack/mcp/websocket/jobs.py +406 -0
  243. crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
  244. crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
  245. crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
  246. crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
  247. crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
  248. crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
  249. crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
  250. crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
  251. crackerjack/mcp/websocket/monitoring/factory.py +109 -0
  252. crackerjack/mcp/websocket/monitoring/filters.py +10 -0
  253. crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
  254. crackerjack/mcp/websocket/monitoring/models.py +90 -0
  255. crackerjack/mcp/websocket/monitoring/utils.py +171 -0
  256. crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
  257. crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
  258. crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
  259. crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
  260. crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
  261. crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
  262. crackerjack/mcp/websocket/monitoring_endpoints.py +21 -0
  263. crackerjack/mcp/websocket/server.py +174 -0
  264. crackerjack/mcp/websocket/websocket_handler.py +276 -0
  265. crackerjack/mcp/websocket_server.py +10 -0
  266. crackerjack/models/README.md +308 -0
  267. crackerjack/models/__init__.py +40 -0
  268. crackerjack/models/config.py +730 -0
  269. crackerjack/models/config_adapter.py +265 -0
  270. crackerjack/models/protocols.py +1535 -0
  271. crackerjack/models/pydantic_models.py +320 -0
  272. crackerjack/models/qa_config.py +145 -0
  273. crackerjack/models/qa_results.py +134 -0
  274. crackerjack/models/resource_protocols.py +299 -0
  275. crackerjack/models/results.py +35 -0
  276. crackerjack/models/semantic_models.py +258 -0
  277. crackerjack/models/task.py +173 -0
  278. crackerjack/models/test_models.py +60 -0
  279. crackerjack/monitoring/README.md +11 -0
  280. crackerjack/monitoring/__init__.py +0 -0
  281. crackerjack/monitoring/ai_agent_watchdog.py +405 -0
  282. crackerjack/monitoring/metrics_collector.py +427 -0
  283. crackerjack/monitoring/regression_prevention.py +580 -0
  284. crackerjack/monitoring/websocket_server.py +406 -0
  285. crackerjack/orchestration/README.md +340 -0
  286. crackerjack/orchestration/__init__.py +43 -0
  287. crackerjack/orchestration/advanced_orchestrator.py +894 -0
  288. crackerjack/orchestration/cache/README.md +312 -0
  289. crackerjack/orchestration/cache/__init__.py +37 -0
  290. crackerjack/orchestration/cache/memory_cache.py +338 -0
  291. crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
  292. crackerjack/orchestration/config.py +297 -0
  293. crackerjack/orchestration/coverage_improvement.py +180 -0
  294. crackerjack/orchestration/execution_strategies.py +361 -0
  295. crackerjack/orchestration/hook_orchestrator.py +1398 -0
  296. crackerjack/orchestration/strategies/README.md +401 -0
  297. crackerjack/orchestration/strategies/__init__.py +39 -0
  298. crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
  299. crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
  300. crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
  301. crackerjack/orchestration/test_progress_streamer.py +647 -0
  302. crackerjack/plugins/README.md +11 -0
  303. crackerjack/plugins/__init__.py +15 -0
  304. crackerjack/plugins/base.py +200 -0
  305. crackerjack/plugins/hooks.py +254 -0
  306. crackerjack/plugins/loader.py +335 -0
  307. crackerjack/plugins/managers.py +264 -0
  308. crackerjack/py313.py +191 -0
  309. crackerjack/security/README.md +11 -0
  310. crackerjack/security/__init__.py +0 -0
  311. crackerjack/security/audit.py +197 -0
  312. crackerjack/services/README.md +374 -0
  313. crackerjack/services/__init__.py +9 -0
  314. crackerjack/services/ai/README.md +295 -0
  315. crackerjack/services/ai/__init__.py +7 -0
  316. crackerjack/services/ai/advanced_optimizer.py +878 -0
  317. crackerjack/services/ai/contextual_ai_assistant.py +542 -0
  318. crackerjack/services/ai/embeddings.py +444 -0
  319. crackerjack/services/ai/intelligent_commit.py +328 -0
  320. crackerjack/services/ai/predictive_analytics.py +510 -0
  321. crackerjack/services/anomaly_detector.py +392 -0
  322. crackerjack/services/api_extractor.py +617 -0
  323. crackerjack/services/backup_service.py +467 -0
  324. crackerjack/services/bounded_status_operations.py +530 -0
  325. crackerjack/services/cache.py +369 -0
  326. crackerjack/services/changelog_automation.py +399 -0
  327. crackerjack/services/command_execution_service.py +305 -0
  328. crackerjack/services/config_integrity.py +132 -0
  329. crackerjack/services/config_merge.py +546 -0
  330. crackerjack/services/config_service.py +198 -0
  331. crackerjack/services/config_template.py +493 -0
  332. crackerjack/services/coverage_badge_service.py +173 -0
  333. crackerjack/services/coverage_ratchet.py +381 -0
  334. crackerjack/services/debug.py +733 -0
  335. crackerjack/services/dependency_analyzer.py +460 -0
  336. crackerjack/services/dependency_monitor.py +622 -0
  337. crackerjack/services/documentation_generator.py +493 -0
  338. crackerjack/services/documentation_service.py +704 -0
  339. crackerjack/services/enhanced_filesystem.py +497 -0
  340. crackerjack/services/enterprise_optimizer.py +865 -0
  341. crackerjack/services/error_pattern_analyzer.py +676 -0
  342. crackerjack/services/file_filter.py +221 -0
  343. crackerjack/services/file_hasher.py +149 -0
  344. crackerjack/services/file_io_service.py +361 -0
  345. crackerjack/services/file_modifier.py +615 -0
  346. crackerjack/services/filesystem.py +381 -0
  347. crackerjack/services/git.py +422 -0
  348. crackerjack/services/health_metrics.py +615 -0
  349. crackerjack/services/heatmap_generator.py +744 -0
  350. crackerjack/services/incremental_executor.py +380 -0
  351. crackerjack/services/initialization.py +823 -0
  352. crackerjack/services/input_validator.py +668 -0
  353. crackerjack/services/intelligent_commit.py +327 -0
  354. crackerjack/services/log_manager.py +289 -0
  355. crackerjack/services/logging.py +228 -0
  356. crackerjack/services/lsp_client.py +628 -0
  357. crackerjack/services/memory_optimizer.py +414 -0
  358. crackerjack/services/metrics.py +587 -0
  359. crackerjack/services/monitoring/README.md +30 -0
  360. crackerjack/services/monitoring/__init__.py +9 -0
  361. crackerjack/services/monitoring/dependency_monitor.py +678 -0
  362. crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
  363. crackerjack/services/monitoring/health_metrics.py +716 -0
  364. crackerjack/services/monitoring/metrics.py +587 -0
  365. crackerjack/services/monitoring/performance_benchmarks.py +410 -0
  366. crackerjack/services/monitoring/performance_cache.py +388 -0
  367. crackerjack/services/monitoring/performance_monitor.py +569 -0
  368. crackerjack/services/parallel_executor.py +527 -0
  369. crackerjack/services/pattern_cache.py +333 -0
  370. crackerjack/services/pattern_detector.py +478 -0
  371. crackerjack/services/patterns/__init__.py +142 -0
  372. crackerjack/services/patterns/agents.py +107 -0
  373. crackerjack/services/patterns/code/__init__.py +15 -0
  374. crackerjack/services/patterns/code/detection.py +118 -0
  375. crackerjack/services/patterns/code/imports.py +107 -0
  376. crackerjack/services/patterns/code/paths.py +159 -0
  377. crackerjack/services/patterns/code/performance.py +119 -0
  378. crackerjack/services/patterns/code/replacement.py +36 -0
  379. crackerjack/services/patterns/core.py +212 -0
  380. crackerjack/services/patterns/documentation/__init__.py +14 -0
  381. crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
  382. crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
  383. crackerjack/services/patterns/documentation/docstrings.py +89 -0
  384. crackerjack/services/patterns/formatting.py +226 -0
  385. crackerjack/services/patterns/operations.py +339 -0
  386. crackerjack/services/patterns/security/__init__.py +23 -0
  387. crackerjack/services/patterns/security/code_injection.py +122 -0
  388. crackerjack/services/patterns/security/credentials.py +190 -0
  389. crackerjack/services/patterns/security/path_traversal.py +221 -0
  390. crackerjack/services/patterns/security/unsafe_operations.py +216 -0
  391. crackerjack/services/patterns/templates.py +62 -0
  392. crackerjack/services/patterns/testing/__init__.py +18 -0
  393. crackerjack/services/patterns/testing/error_patterns.py +107 -0
  394. crackerjack/services/patterns/testing/pytest_output.py +126 -0
  395. crackerjack/services/patterns/tool_output/__init__.py +16 -0
  396. crackerjack/services/patterns/tool_output/bandit.py +72 -0
  397. crackerjack/services/patterns/tool_output/other.py +97 -0
  398. crackerjack/services/patterns/tool_output/pyright.py +67 -0
  399. crackerjack/services/patterns/tool_output/ruff.py +44 -0
  400. crackerjack/services/patterns/url_sanitization.py +114 -0
  401. crackerjack/services/patterns/utilities.py +42 -0
  402. crackerjack/services/patterns/utils.py +339 -0
  403. crackerjack/services/patterns/validation.py +46 -0
  404. crackerjack/services/patterns/versioning.py +62 -0
  405. crackerjack/services/predictive_analytics.py +523 -0
  406. crackerjack/services/profiler.py +280 -0
  407. crackerjack/services/quality/README.md +415 -0
  408. crackerjack/services/quality/__init__.py +11 -0
  409. crackerjack/services/quality/anomaly_detector.py +392 -0
  410. crackerjack/services/quality/pattern_cache.py +333 -0
  411. crackerjack/services/quality/pattern_detector.py +479 -0
  412. crackerjack/services/quality/qa_orchestrator.py +491 -0
  413. crackerjack/services/quality/quality_baseline.py +395 -0
  414. crackerjack/services/quality/quality_baseline_enhanced.py +649 -0
  415. crackerjack/services/quality/quality_intelligence.py +949 -0
  416. crackerjack/services/regex_patterns.py +58 -0
  417. crackerjack/services/regex_utils.py +483 -0
  418. crackerjack/services/secure_path_utils.py +524 -0
  419. crackerjack/services/secure_status_formatter.py +450 -0
  420. crackerjack/services/secure_subprocess.py +635 -0
  421. crackerjack/services/security.py +239 -0
  422. crackerjack/services/security_logger.py +495 -0
  423. crackerjack/services/server_manager.py +411 -0
  424. crackerjack/services/smart_scheduling.py +167 -0
  425. crackerjack/services/status_authentication.py +460 -0
  426. crackerjack/services/status_security_manager.py +315 -0
  427. crackerjack/services/terminal_utils.py +0 -0
  428. crackerjack/services/thread_safe_status_collector.py +441 -0
  429. crackerjack/services/tool_filter.py +368 -0
  430. crackerjack/services/tool_version_service.py +43 -0
  431. crackerjack/services/unified_config.py +115 -0
  432. crackerjack/services/validation_rate_limiter.py +220 -0
  433. crackerjack/services/vector_store.py +689 -0
  434. crackerjack/services/version_analyzer.py +461 -0
  435. crackerjack/services/version_checker.py +223 -0
  436. crackerjack/services/websocket_resource_limiter.py +438 -0
  437. crackerjack/services/zuban_lsp_service.py +391 -0
  438. crackerjack/slash_commands/README.md +11 -0
  439. crackerjack/slash_commands/__init__.py +59 -0
  440. crackerjack/slash_commands/init.md +112 -0
  441. crackerjack/slash_commands/run.md +197 -0
  442. crackerjack/slash_commands/status.md +127 -0
  443. crackerjack/tools/README.md +11 -0
  444. crackerjack/tools/__init__.py +30 -0
  445. crackerjack/tools/_git_utils.py +105 -0
  446. crackerjack/tools/check_added_large_files.py +139 -0
  447. crackerjack/tools/check_ast.py +105 -0
  448. crackerjack/tools/check_json.py +103 -0
  449. crackerjack/tools/check_jsonschema.py +297 -0
  450. crackerjack/tools/check_toml.py +103 -0
  451. crackerjack/tools/check_yaml.py +110 -0
  452. crackerjack/tools/codespell_wrapper.py +72 -0
  453. crackerjack/tools/end_of_file_fixer.py +202 -0
  454. crackerjack/tools/format_json.py +128 -0
  455. crackerjack/tools/mdformat_wrapper.py +114 -0
  456. crackerjack/tools/trailing_whitespace.py +198 -0
  457. crackerjack/tools/validate_input_validator_patterns.py +236 -0
  458. crackerjack/tools/validate_regex_patterns.py +188 -0
  459. crackerjack/ui/README.md +11 -0
  460. crackerjack/ui/__init__.py +1 -0
  461. crackerjack/ui/dashboard_renderer.py +28 -0
  462. crackerjack/ui/templates/README.md +11 -0
  463. crackerjack/utils/console_utils.py +13 -0
  464. crackerjack/utils/dependency_guard.py +230 -0
  465. crackerjack/utils/retry_utils.py +275 -0
  466. crackerjack/workflows/README.md +590 -0
  467. crackerjack/workflows/__init__.py +46 -0
  468. crackerjack/workflows/actions.py +811 -0
  469. crackerjack/workflows/auto_fix.py +444 -0
  470. crackerjack/workflows/container_builder.py +499 -0
  471. crackerjack/workflows/definitions.py +443 -0
  472. crackerjack/workflows/engine.py +177 -0
  473. crackerjack/workflows/event_bridge.py +242 -0
  474. crackerjack-0.45.2.dist-info/METADATA +1678 -0
  475. crackerjack-0.45.2.dist-info/RECORD +478 -0
  476. {crackerjack-0.18.2.dist-info โ†’ crackerjack-0.45.2.dist-info}/WHEEL +1 -1
  477. crackerjack-0.45.2.dist-info/entry_points.txt +2 -0
  478. crackerjack/.gitignore +0 -14
  479. crackerjack/.libcst.codemod.yaml +0 -18
  480. crackerjack/.pdm.toml +0 -1
  481. crackerjack/.pre-commit-config.yaml +0 -91
  482. crackerjack/.pytest_cache/.gitignore +0 -2
  483. crackerjack/.pytest_cache/CACHEDIR.TAG +0 -4
  484. crackerjack/.pytest_cache/README.md +0 -8
  485. crackerjack/.pytest_cache/v/cache/nodeids +0 -1
  486. crackerjack/.pytest_cache/v/cache/stepwise +0 -1
  487. crackerjack/.ruff_cache/.gitignore +0 -1
  488. crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
  489. crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
  490. crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
  491. crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
  492. crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
  493. crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
  494. crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
  495. crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
  496. crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
  497. crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
  498. crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
  499. crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
  500. crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
  501. crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
  502. crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
  503. crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
  504. crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
  505. crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
  506. crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
  507. crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
  508. crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
  509. crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
  510. crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
  511. crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
  512. crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
  513. crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
  514. crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
  515. crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
  516. crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
  517. crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
  518. crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
  519. crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
  520. crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
  521. crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
  522. crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
  523. crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
  524. crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
  525. crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
  526. crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
  527. crackerjack/.ruff_cache/CACHEDIR.TAG +0 -1
  528. crackerjack/crackerjack.py +0 -855
  529. crackerjack/pyproject.toml +0 -214
  530. crackerjack-0.18.2.dist-info/METADATA +0 -420
  531. crackerjack-0.18.2.dist-info/RECORD +0 -59
  532. crackerjack-0.18.2.dist-info/entry_points.txt +0 -4
  533. {crackerjack-0.18.2.dist-info โ†’ crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,488 @@
1
+ import time
2
+ import typing as t
3
+ from enum import Enum, auto
4
+
5
+ from acb.console import Console
6
+ from acb.depends import depends
7
+ from rich.box import ROUNDED
8
+ from rich.layout import Layout
9
+ from rich.live import Live
10
+ from rich.panel import Panel
11
+ from rich.prompt import Confirm, Prompt
12
+ from rich.table import Table
13
+ from rich.text import Text
14
+ from rich.tree import Tree
15
+
16
+ from crackerjack.core.workflow_orchestrator import WorkflowOrchestrator
17
+ from crackerjack.errors import CrackerjackError, ErrorCode, handle_error
18
+ from crackerjack.models.protocols import OptionsProtocol
19
+
20
+
21
+ class TaskStatus(Enum):
22
+ PENDING = auto()
23
+ RUNNING = auto()
24
+ SUCCESS = auto()
25
+ FAILED = auto()
26
+ SKIPPED = auto()
27
+
28
+
29
+ class InteractiveTask:
30
+ def __init__(
31
+ self,
32
+ name: str,
33
+ description: str,
34
+ phase_method: str,
35
+ dependencies: list["InteractiveTask"] | None = None,
36
+ ) -> None:
37
+ self.name = name
38
+ self.description = description
39
+ self.phase_method = phase_method
40
+ self.dependencies = dependencies or []
41
+ self.status = TaskStatus.PENDING
42
+ self.start_time: float | None = None
43
+ self.end_time: float | None = None
44
+ self.error: CrackerjackError | None = None
45
+
46
+ @property
47
+ def duration(self) -> float | None:
48
+ if self.start_time is None:
49
+ return None
50
+ end = self.end_time or time.time()
51
+ return end - self.start_time
52
+
53
+ def start(self) -> None:
54
+ self.status = TaskStatus.RUNNING
55
+ self.start_time = time.time()
56
+
57
+ def complete(self, success: bool = True) -> None:
58
+ self.end_time = time.time()
59
+ self.status = TaskStatus.SUCCESS if success else TaskStatus.FAILED
60
+
61
+ def skip(self) -> None:
62
+ self.status = TaskStatus.SKIPPED
63
+
64
+ def fail(self, error: CrackerjackError) -> None:
65
+ self.end_time = time.time()
66
+ self.status = TaskStatus.FAILED
67
+ self.error = error
68
+
69
+ def can_run(self) -> bool:
70
+ return all(
71
+ dep.status in (TaskStatus.SUCCESS, TaskStatus.SKIPPED)
72
+ for dep in self.dependencies
73
+ )
74
+
75
+ def __str__(self) -> str:
76
+ return f"{self.name} ({self.status.name})"
77
+
78
+
79
+ class InteractiveWorkflowManager:
80
+ def __init__(self, console: Console, orchestrator: WorkflowOrchestrator) -> None:
81
+ self.console = console
82
+ self.orchestrator = orchestrator
83
+ self.tasks: dict[str, InteractiveTask] = {}
84
+ self.current_task: InteractiveTask | None = None
85
+ self.layout = Layout()
86
+ self._setup_layout()
87
+
88
+ def _setup_layout(self) -> None:
89
+ self.layout.split_column(
90
+ Layout(name="header", size=3),
91
+ Layout(name="main"),
92
+ Layout(name="footer", size=3),
93
+ )
94
+ self.layout["main"].split_row(
95
+ Layout(name="tasks", minimum_size=40),
96
+ Layout(name="details", ratio=2),
97
+ )
98
+
99
+ def setup_workflow(self, options: OptionsProtocol) -> None:
100
+ self.tasks.clear()
101
+ self._setup_cleaning_task(options)
102
+ self._setup_hooks_task(options)
103
+ self._setup_testing_task(options)
104
+ self._setup_publishing_task(options)
105
+ self._setup_commit_task(options)
106
+
107
+ def _setup_cleaning_task(self, options: OptionsProtocol) -> None:
108
+ if options.clean:
109
+ self.add_task(
110
+ "cleaning",
111
+ "Clean code (remove docstrings, comments)",
112
+ "run_cleaning_phase",
113
+ )
114
+
115
+ def _setup_hooks_task(self, options: OptionsProtocol) -> None:
116
+ if not options.skip_hooks:
117
+ deps = ["cleaning"] if options.clean else []
118
+ self.add_task(
119
+ "hooks",
120
+ "Run quality hooks (fast + comprehensive)",
121
+ "run_hooks_phase",
122
+ dependencies=deps,
123
+ )
124
+
125
+ def _setup_testing_task(self, options: OptionsProtocol) -> None:
126
+ if options.test:
127
+ deps = (
128
+ ["hooks"]
129
+ if not options.skip_hooks
130
+ else (["cleaning"] if options.clean else [])
131
+ )
132
+ self.add_task(
133
+ "testing",
134
+ "Run tests with coverage",
135
+ "run_testing_phase",
136
+ dependencies=deps,
137
+ )
138
+
139
+ def _setup_publishing_task(self, options: OptionsProtocol) -> None:
140
+ if options.publish or options.all or options.bump:
141
+ all_deps = self._get_publishing_dependencies()
142
+ self.add_task(
143
+ "publishing",
144
+ "Version bump and publish to PyPI",
145
+ "run_publishing_phase",
146
+ dependencies=all_deps,
147
+ )
148
+
149
+ def _setup_commit_task(self, options: OptionsProtocol) -> None:
150
+ if options.commit:
151
+ all_deps = list[t.Any](self.tasks.keys())
152
+ self.add_task(
153
+ "commit",
154
+ "Commit changes and push to Git",
155
+ "run_commit_phase",
156
+ dependencies=all_deps[:-1] if all_deps else [],
157
+ )
158
+
159
+ def _get_publishing_dependencies(self) -> list[str]:
160
+ if "testing" in self.tasks:
161
+ return ["testing"]
162
+ elif "hooks" in self.tasks:
163
+ return ["hooks"]
164
+ elif "cleaning" in self.tasks:
165
+ return ["cleaning"]
166
+ return []
167
+
168
+ def add_task(
169
+ self,
170
+ name: str,
171
+ description: str,
172
+ phase_method: str,
173
+ dependencies: list[str] | None = None,
174
+ ) -> InteractiveTask:
175
+ dep_tasks: list[InteractiveTask] = []
176
+ if dependencies:
177
+ for dep_name in dependencies:
178
+ if dep_name not in self.tasks:
179
+ msg = f"Dependency task '{dep_name}' not found"
180
+ raise ValueError(msg)
181
+ dep_tasks.append(self.tasks[dep_name])
182
+
183
+ task = InteractiveTask(name, description, phase_method, dep_tasks)
184
+ self.tasks[name] = task
185
+ return task
186
+
187
+ def get_next_task(self) -> InteractiveTask | None:
188
+ for task in self.tasks.values():
189
+ if task.status == TaskStatus.PENDING and task.can_run():
190
+ return task
191
+ return None
192
+
193
+ def execute_task(self, task: InteractiveTask, options: OptionsProtocol) -> bool:
194
+ self.current_task = task
195
+ task.start()
196
+ try:
197
+ phase_method = getattr(self.orchestrator, task.phase_method)
198
+ success_result = phase_method(options)
199
+ success_bool = bool(success_result)
200
+ task.complete(success_bool)
201
+ return success_bool
202
+ except Exception as e:
203
+ error = CrackerjackError(
204
+ message=str(e),
205
+ error_code=ErrorCode.COMMAND_EXECUTION_ERROR,
206
+ )
207
+ task.fail(error)
208
+ return False
209
+ finally:
210
+ self.current_task = None
211
+
212
+ def create_task_tree(self) -> Tree:
213
+ tree = Tree("๐Ÿ”ง Workflow Tasks")
214
+ for task in self.tasks.values():
215
+ status_emoji = {
216
+ TaskStatus.PENDING: "โณ",
217
+ TaskStatus.RUNNING: "๐Ÿ”„",
218
+ TaskStatus.SUCCESS: "โœ…",
219
+ TaskStatus.FAILED: "โŒ",
220
+ TaskStatus.SKIPPED: "โญ๏ธ",
221
+ }
222
+ emoji = status_emoji.get(task.status, "โ“")
223
+ label = f"{emoji} {task.name}"
224
+ if task.duration is not None:
225
+ label += f" ({task.duration: .1f}s)"
226
+ task_node = tree.add(label)
227
+ task_node.add(f"๐Ÿ“ {task.description}")
228
+ if task.error:
229
+ task_node.add(f"โŒ {task.error.message}")
230
+
231
+ return tree
232
+
233
+ def create_details_panel(self) -> Panel:
234
+ if self.current_task is None:
235
+ content = Text("No task currently running", style="dim")
236
+ else:
237
+ task = self.current_task
238
+ content = Text()
239
+ content.append(f"๐Ÿ”„ Running: {task.name}\n", style="bold cyan")
240
+ content.append(f"๐Ÿ“ {task.description}\n")
241
+ if task.duration is not None:
242
+ content.append(f"โฑ๏ธ Duration: {task.duration: .1f}s\n")
243
+ if task.dependencies:
244
+ content.append("\n๐Ÿ“‹ Dependencies: \n", style="bold")
245
+ for dep in task.dependencies:
246
+ status_emoji = "โœ…" if dep.status == TaskStatus.SUCCESS else "โŒ"
247
+ content.append(f" {status_emoji} {dep.name}\n")
248
+
249
+ return Panel(content, title="Current Task", border_style="cyan")
250
+
251
+ def create_header(self, pkg_version: str) -> Panel:
252
+ header_text = Text()
253
+ header_text.append("๐Ÿš€ Crackerjack Interactive Mode ", style="bold cyan")
254
+ header_text.append(f"v{pkg_version}", style="dim")
255
+
256
+ return Panel(header_text, style="cyan")
257
+
258
+ def create_footer(self) -> Panel:
259
+ footer_text = Text()
260
+ footer_text.append("Press ", style="dim")
261
+ footer_text.append("Ctrl + C", style="bold red")
262
+ footer_text.append(" to cancel โ€ข ", style="dim")
263
+ footer_text.append("Enter", style="bold green")
264
+ footer_text.append(" to continue", style="dim")
265
+
266
+ return Panel(footer_text, style="green")
267
+
268
+ def update_layout(self, pkg_version: str) -> None:
269
+ self.layout["header"].update(self.create_header(pkg_version))
270
+ self.layout["tasks"].update(
271
+ Panel(self.create_task_tree(), title="Tasks", border_style="blue"),
272
+ )
273
+ self.layout["details"].update(self.create_details_panel())
274
+ self.layout["footer"].update(self.create_footer())
275
+
276
+ def run_workflow(self, options: OptionsProtocol, pkg_version: str) -> bool:
277
+ if not self._initialize_workflow(options, pkg_version):
278
+ return False
279
+
280
+ with Live(self.layout) as live:
281
+ if not self._execute_workflow_tasks(live, options, pkg_version):
282
+ return False
283
+
284
+ return self._finalize_workflow()
285
+
286
+ def _initialize_workflow(self, options: OptionsProtocol, pkg_version: str) -> bool:
287
+ self.setup_workflow(options)
288
+ if not self.tasks:
289
+ self.console.print(
290
+ "[yellow]โš ๏ธ No tasks to execute based on options[/ yellow]",
291
+ )
292
+ return True
293
+
294
+ self.update_layout(pkg_version)
295
+ self.console.print(self.layout)
296
+
297
+ if not Confirm.ask("\n๐Ÿš€ Start workflow?", default=True):
298
+ self.console.print("[yellow]โน๏ธ Workflow cancelled[/ yellow]")
299
+ return False
300
+
301
+ return True
302
+
303
+ def _execute_workflow_tasks(
304
+ self,
305
+ live: Live,
306
+ options: OptionsProtocol,
307
+ pkg_version: str,
308
+ ) -> bool:
309
+ while True:
310
+ next_task = self.get_next_task()
311
+ if next_task is None:
312
+ break
313
+
314
+ self.update_layout(pkg_version)
315
+ live.update(self.layout)
316
+
317
+ success = self.execute_task(next_task, options)
318
+ self.update_layout(pkg_version)
319
+ live.update(self.layout)
320
+
321
+ if not success and not self._handle_task_failure(live, next_task):
322
+ return False
323
+
324
+ return True
325
+
326
+ def _handle_task_failure(self, live: Live, failed_task: InteractiveTask) -> bool:
327
+ live.stop()
328
+ retry = Confirm.ask(
329
+ f"\nโŒ Task '{failed_task.name}' failed. Continue anyway?",
330
+ default=False,
331
+ )
332
+
333
+ if not retry:
334
+ self.console.print("[red]โน๏ธ Workflow stopped due to task failure[/ red]")
335
+ return False
336
+
337
+ failed_task.skip()
338
+ live.start()
339
+ return True
340
+
341
+ def _finalize_workflow(self) -> bool:
342
+ self.show_final_results()
343
+
344
+ success_count = sum(
345
+ 1 for task in self.tasks.values() if task.status == TaskStatus.SUCCESS
346
+ )
347
+ total_tasks = len(self.tasks)
348
+
349
+ return success_count == total_tasks or all(
350
+ task.status in (TaskStatus.SUCCESS, TaskStatus.SKIPPED)
351
+ for task in self.tasks.values()
352
+ )
353
+
354
+ def show_final_results(self) -> None:
355
+ success_count = sum(
356
+ 1 for task in self.tasks.values() if task.status == TaskStatus.SUCCESS
357
+ )
358
+ failed_count = sum(
359
+ 1 for task in self.tasks.values() if task.status == TaskStatus.FAILED
360
+ )
361
+ skipped_count = sum(
362
+ 1 for task in self.tasks.values() if task.status == TaskStatus.SKIPPED
363
+ )
364
+ table = Table(title="๐Ÿ“Š Workflow Results", box=ROUNDED)
365
+ table.add_column("Task", style="bold")
366
+ table.add_column("Status", justify="center")
367
+ table.add_column("Duration", justify="right")
368
+ table.add_column("Details")
369
+ for task in self.tasks.values():
370
+ status_styles = {
371
+ TaskStatus.SUCCESS: "green",
372
+ TaskStatus.FAILED: "red",
373
+ TaskStatus.SKIPPED: "yellow",
374
+ TaskStatus.PENDING: "dim",
375
+ TaskStatus.RUNNING: "cyan",
376
+ }
377
+ status_text = task.status.name
378
+ style = status_styles.get(task.status, "white")
379
+ duration_text = f"{task.duration: .1f}s" if task.duration else "-"
380
+ details = task.error.message if task.error else task.description
381
+ table.add_row(
382
+ task.name,
383
+ f"[{style}]{status_text}[/{style}]",
384
+ duration_text,
385
+ details,
386
+ )
387
+ from rich.panel import Panel
388
+
389
+ self.console.print("\n")
390
+ self.console.print(Panel(table, border_style="magenta"))
391
+ if failed_count == 0:
392
+ self.console.print(
393
+ f"\n[bold green]๐ŸŽ‰ Workflow completed ! {success_count} / {len(self.tasks)} tasks successful[/ bold green]",
394
+ )
395
+ else:
396
+ self.console.print(
397
+ f"\n[bold yellow]โš ๏ธ Workflow completed with issues: {failed_count} failed, {skipped_count} skipped[/ bold yellow]",
398
+ )
399
+
400
+
401
+ class InteractiveCLI:
402
+ def __init__(self, pkg_version: str, console: Console | None = None) -> None:
403
+ self.pkg_version = pkg_version
404
+ self.console = console or depends.get_sync(Console)
405
+ self.orchestrator = WorkflowOrchestrator()
406
+ self.workflow_manager = InteractiveWorkflowManager(
407
+ self.console,
408
+ self.orchestrator,
409
+ )
410
+
411
+ def launch(self, options: OptionsProtocol) -> None:
412
+ try:
413
+ self._show_welcome()
414
+ updated_options = self._get_user_preferences(options)
415
+ success = self.workflow_manager.run_workflow(
416
+ updated_options,
417
+ self.pkg_version,
418
+ )
419
+ if not success:
420
+ raise SystemExit(1)
421
+ except KeyboardInterrupt:
422
+ self.console.print("\n[yellow]โน๏ธ Interactive session cancelled[/ yellow]")
423
+ raise SystemExit(130)
424
+ except Exception as e:
425
+ error = CrackerjackError(
426
+ message=str(e),
427
+ error_code=ErrorCode.UNEXPECTED_ERROR,
428
+ )
429
+ handle_error(error, self.console)
430
+ raise SystemExit(1)
431
+
432
+ def _show_welcome(self) -> None:
433
+ welcome_panel = Panel(
434
+ f"[bold cyan]Welcome to Crackerjack Interactive Mode ! [/ bold cyan]\n\n"
435
+ f"Version: {self.pkg_version}\n"
436
+ f"This interactive interface will guide you through the crackerjack workflow\n"
437
+ f"with real-time feedback and customizable options.",
438
+ title="๐Ÿš€ Crackerjack Interactive",
439
+ border_style="cyan",
440
+ )
441
+ self.console.print(welcome_panel)
442
+ self.console.print()
443
+
444
+ def _get_user_preferences(self, options: OptionsProtocol) -> OptionsProtocol:
445
+ self.console.print("[bold]๐Ÿ”ง Workflow Configuration[/ bold]")
446
+ self.console.print("Configure your crackerjack workflow: \n")
447
+ updated_options = type(options)(**vars(options))
448
+ updated_options.clean = Confirm.ask(
449
+ "๐Ÿงน Clean code (remove docstrings, comments)?",
450
+ default=options.clean,
451
+ )
452
+ updated_options.test = Confirm.ask("๐Ÿงช Run tests?", default=options.test)
453
+
454
+ # Only ask about commit if not explicitly set via command line
455
+ # Check if commit was explicitly provided by looking at original vs default
456
+ from ..cli.options import Options
457
+
458
+ default_options = Options()
459
+ if options.commit != default_options.commit:
460
+ # Command line flag was used, preserve it
461
+ self.console.print(f"๐Ÿ“ Using command line flag: --commit={options.commit}")
462
+ updated_options.commit = options.commit # Preserve the command line value
463
+ else:
464
+ # No command line flag, ask user
465
+ updated_options.commit = Confirm.ask(
466
+ "๐Ÿ“ Commit changes to git?",
467
+ default=options.commit,
468
+ )
469
+ if not any([options.publish, options.all, options.bump]):
470
+ if Confirm.ask("๐Ÿ“ฆ Bump version and publish?", default=False):
471
+ version_type = Prompt.ask(
472
+ "Version bump type",
473
+ choices=["patch", "minor", "major", "interactive"],
474
+ default="patch",
475
+ )
476
+ updated_options.publish = version_type
477
+ if Confirm.ask("\nโš™๏ธ Configure advanced options?", default=False):
478
+ updated_options.verbose = Confirm.ask(
479
+ "Enable verbose output?",
480
+ default=options.verbose,
481
+ )
482
+ self.console.print()
483
+ return updated_options
484
+
485
+
486
+ def launch_interactive_cli(pkg_version: str, options: OptionsProtocol) -> None:
487
+ cli = InteractiveCLI(pkg_version)
488
+ cli.launch(options)