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,230 @@
1
+ from pathlib import Path
2
+
3
+ from .base import (
4
+ AgentContext,
5
+ FixResult,
6
+ Issue,
7
+ IssueType,
8
+ SubAgent,
9
+ agent_registry,
10
+ )
11
+
12
+
13
+ class FormattingAgent(SubAgent):
14
+ def __init__(self, context: AgentContext) -> None:
15
+ super().__init__(context)
16
+
17
+ def get_supported_types(self) -> set[IssueType]:
18
+ return {IssueType.FORMATTING, IssueType.IMPORT_ERROR}
19
+
20
+ async def can_handle(self, issue: Issue) -> float:
21
+ if issue.type not in self.get_supported_types():
22
+ return 0.0
23
+
24
+ message_lower = issue.message.lower()
25
+
26
+ if any(
27
+ keyword in message_lower
28
+ for keyword in (
29
+ "would reformat",
30
+ "trailing whitespace",
31
+ "missing newline",
32
+ "import sorting",
33
+ "unused import",
34
+ "ruff",
35
+ "format",
36
+ )
37
+ ):
38
+ return 1.0
39
+
40
+ if any(
41
+ keyword in message_lower
42
+ for keyword in (
43
+ "whitespace",
44
+ "indent",
45
+ "spacing",
46
+ "line length",
47
+ "import",
48
+ "style",
49
+ "format",
50
+ )
51
+ ):
52
+ return 0.8
53
+
54
+ if issue.type == IssueType.FORMATTING:
55
+ return 0.6
56
+
57
+ return 0.0
58
+
59
+ async def analyze_and_fix(self, issue: Issue) -> FixResult:
60
+ self.log(f"Analyzing formatting issue: {issue.message}")
61
+
62
+ fixes_applied: list[str] = []
63
+ files_modified: list[str] = []
64
+
65
+ try:
66
+ ruff_fixes = await self._apply_ruff_fixes()
67
+ fixes_applied.extend(ruff_fixes)
68
+
69
+ whitespace_fixes = await self._apply_whitespace_fixes()
70
+ fixes_applied.extend(whitespace_fixes)
71
+
72
+ import_fixes = await self._apply_import_fixes()
73
+ fixes_applied.extend(import_fixes)
74
+
75
+ if issue.file_path:
76
+ file_fixes = await self._fix_specific_file(issue.file_path, issue)
77
+ fixes_applied.extend(file_fixes)
78
+ if file_fixes:
79
+ files_modified.append(issue.file_path)
80
+
81
+ success = len(fixes_applied) > 0
82
+ confidence = 0.9 if success else 0.3
83
+
84
+ return FixResult(
85
+ success=success,
86
+ confidence=confidence,
87
+ fixes_applied=fixes_applied,
88
+ files_modified=files_modified,
89
+ recommendations=[
90
+ "Run ruff format regularly for consistent styling",
91
+ "Configure pre-commit hooks for automatic formatting",
92
+ ]
93
+ if not success
94
+ else [],
95
+ )
96
+
97
+ except Exception as e:
98
+ self.log(f"Error fixing formatting issue: {e}", "ERROR")
99
+ return FixResult(
100
+ success=False,
101
+ confidence=0.0,
102
+ remaining_issues=[f"Failed to apply formatting fixes: {e}"],
103
+ )
104
+
105
+ async def _apply_ruff_fixes(self) -> list[str]:
106
+ fixes: list[str] = []
107
+
108
+ returncode, _, stderr = await self.run_command(
109
+ ["uv", "run", "ruff", "format", "."],
110
+ )
111
+
112
+ if returncode == 0:
113
+ fixes.append("Applied ruff code formatting")
114
+ self.log("Successfully applied ruff formatting")
115
+ else:
116
+ self.log(f"Ruff format failed: {stderr}", "WARN")
117
+
118
+ returncode, _, stderr = await self.run_command(
119
+ ["uv", "run", "ruff", "check", ".", "--fix"],
120
+ )
121
+
122
+ if returncode == 0:
123
+ fixes.append("Applied ruff linting fixes")
124
+ self.log("Successfully applied ruff linting fixes")
125
+ else:
126
+ self.log(f"Ruff check --fix had issues: {stderr}", "WARN")
127
+
128
+ return fixes
129
+
130
+ async def _apply_whitespace_fixes(self) -> list[str]:
131
+ fixes: list[str] = []
132
+
133
+ returncode, _, _ = await self.run_command(
134
+ [
135
+ "uv",
136
+ "run",
137
+ "python",
138
+ "-m",
139
+ "crackerjack.tools.trailing_whitespace",
140
+ ],
141
+ )
142
+
143
+ if returncode == 0:
144
+ fixes.append("Fixed trailing whitespace")
145
+ self.log("Fixed trailing whitespace")
146
+
147
+ returncode, _, _ = await self.run_command(
148
+ [
149
+ "uv",
150
+ "run",
151
+ "python",
152
+ "-m",
153
+ "crackerjack.tools.end_of_file_fixer",
154
+ ],
155
+ )
156
+
157
+ if returncode == 0:
158
+ fixes.append("Fixed end-of-file formatting")
159
+ self.log("Fixed end-of-file formatting")
160
+
161
+ return fixes
162
+
163
+ async def _apply_import_fixes(self) -> list[str]:
164
+ fixes: list[str] = []
165
+
166
+ returncode, _, _ = await self.run_command(
167
+ [
168
+ "uv",
169
+ "run",
170
+ "ruff",
171
+ "check",
172
+ ".",
173
+ "--select",
174
+ "I, F401",
175
+ "--fix",
176
+ ],
177
+ )
178
+
179
+ if returncode == 0:
180
+ fixes.append("Organized imports and removed unused imports")
181
+ self.log("Fixed import organization")
182
+
183
+ return fixes
184
+
185
+ async def _fix_specific_file(self, file_path: str, issue: Issue) -> list[str]:
186
+ fixes: list[str] = []
187
+
188
+ try:
189
+ path = Path(file_path)
190
+ content = self._validate_and_get_file_content(path)
191
+ if not content:
192
+ return fixes
193
+
194
+ original_content = content
195
+ cleaned_content = self._apply_content_formatting(content)
196
+
197
+ if cleaned_content != original_content:
198
+ if self.context.write_file_content(path, cleaned_content):
199
+ fixes.append(f"Fixed formatting in {file_path}")
200
+ self.log(f"Applied file-specific fixes to {file_path}")
201
+
202
+ except Exception as e:
203
+ self.log(f"Error fixing file {file_path}: {e}", "ERROR")
204
+
205
+ return fixes
206
+
207
+ def _validate_and_get_file_content(self, path: Path) -> str | None:
208
+ if not path.exists() or not path.is_file():
209
+ return None
210
+
211
+ content = self.context.get_file_content(path)
212
+ return content or None
213
+
214
+ def _apply_content_formatting(self, content: str) -> str:
215
+ from crackerjack.services.regex_patterns import apply_formatting_fixes
216
+
217
+ content = apply_formatting_fixes(content)
218
+
219
+ if content and not content.endswith("\n"):
220
+ content += "\n"
221
+
222
+ return self._convert_tabs_to_spaces(content)
223
+
224
+ def _convert_tabs_to_spaces(self, content: str) -> str:
225
+ lines = content.split("\n")
226
+ fixed_lines = [line.expandtabs(4) for line in lines]
227
+ return "\n".join(fixed_lines)
228
+
229
+
230
+ agent_registry.register(FormattingAgent)
@@ -0,0 +1,9 @@
1
+ """Package for helper modules used by crackerjack agents.
2
+
3
+ This package contains supporting modules for various agent types:
4
+ - performance: Performance analysis and optimization helpers
5
+ - refactoring: Code refactoring utilities
6
+ - test_creation: Test generation helpers
7
+ """
8
+
9
+ # This file makes the directory a proper Python package
@@ -0,0 +1,22 @@
1
+ """Performance optimization helpers for the PerformanceAgent.
2
+
3
+ This module provides specialized helpers for detecting and fixing performance
4
+ anti-patterns while maintaining the AgentContext pattern.
5
+ """
6
+
7
+ from .performance_ast_analyzer import PerformanceASTAnalyzer
8
+ from .performance_pattern_detector import (
9
+ ListOpAnalyzer,
10
+ NestedLoopAnalyzer,
11
+ PerformancePatternDetector,
12
+ )
13
+ from .performance_recommender import OptimizationResult, PerformanceRecommender
14
+
15
+ __all__ = [
16
+ "PerformancePatternDetector",
17
+ "PerformanceASTAnalyzer",
18
+ "PerformanceRecommender",
19
+ "OptimizationResult",
20
+ "NestedLoopAnalyzer",
21
+ "ListOpAnalyzer",
22
+ ]
@@ -0,0 +1,357 @@
1
+ """AST analysis for performance complexity detection."""
2
+
3
+ import ast
4
+ import typing as t
5
+
6
+ from ...base import AgentContext
7
+
8
+
9
+ class PerformanceASTAnalyzer:
10
+ """Analyzes Python AST for performance-related complexity issues."""
11
+
12
+ def __init__(self, context: AgentContext) -> None:
13
+ """Initialize analyzer with agent context.
14
+
15
+ Args:
16
+ context: AgentContext for logging and operations
17
+ """
18
+ self.context = context
19
+
20
+ def extract_performance_critical_functions(
21
+ self, content: str
22
+ ) -> list[dict[str, t.Any]]:
23
+ """Extract functions likely to have performance issues.
24
+
25
+ Args:
26
+ content: File content
27
+
28
+ Returns:
29
+ List of performance-critical functions
30
+ """
31
+ functions: list[dict[str, t.Any]] = []
32
+ lines = content.split("\n")
33
+ current_function = None
34
+
35
+ for i, line in enumerate(lines):
36
+ stripped = line.strip()
37
+
38
+ if self._is_empty_or_comment_line(stripped):
39
+ if current_function:
40
+ current_function["body"] += line + "\n"
41
+ continue
42
+
43
+ indent = len(line) - len(line.lstrip())
44
+
45
+ if self._is_function_definition(stripped):
46
+ current_function = self._handle_function_definition(
47
+ current_function, functions, stripped, indent, i
48
+ )
49
+ elif current_function:
50
+ current_function = self._handle_function_body_line(
51
+ current_function, functions, line, stripped, indent, i
52
+ )
53
+
54
+ self._handle_last_function(current_function, functions, len(lines))
55
+ return functions
56
+
57
+ @staticmethod
58
+ def _is_empty_or_comment_line(stripped: str) -> bool:
59
+ """Check if line is empty or comment.
60
+
61
+ Args:
62
+ stripped: Stripped line
63
+
64
+ Returns:
65
+ True if empty or comment
66
+ """
67
+ return not stripped or stripped.startswith("#")
68
+
69
+ @staticmethod
70
+ def _is_function_definition(stripped: str) -> bool:
71
+ """Check if line is function definition.
72
+
73
+ Args:
74
+ stripped: Stripped line
75
+
76
+ Returns:
77
+ True if function definition
78
+ """
79
+ return stripped.startswith("def ") and "(" in stripped
80
+
81
+ def _handle_function_definition(
82
+ self,
83
+ current_function: dict[str, t.Any] | None,
84
+ functions: list[dict[str, t.Any]],
85
+ stripped: str,
86
+ indent: int,
87
+ line_number: int,
88
+ ) -> dict[str, t.Any]:
89
+ """Handle function definition line.
90
+
91
+ Args:
92
+ current_function: Current function being parsed
93
+ functions: List of functions
94
+ stripped: Stripped line
95
+ indent: Indentation level
96
+ line_number: Line number
97
+
98
+ Returns:
99
+ New function dict
100
+ """
101
+ if current_function and self._is_performance_critical(current_function):
102
+ self._finalize_function(current_function, functions, line_number)
103
+
104
+ func_name = stripped.split("(")[0].replace("def ", "").strip()
105
+ return {
106
+ "name": func_name,
107
+ "signature": stripped,
108
+ "start_line": line_number + 1,
109
+ "body": "",
110
+ "indent_level": indent,
111
+ }
112
+
113
+ def _handle_function_body_line(
114
+ self,
115
+ current_function: dict[str, t.Any],
116
+ functions: list[dict[str, t.Any]],
117
+ line: str,
118
+ stripped: str,
119
+ indent: int,
120
+ line_number: int,
121
+ ) -> dict[str, t.Any] | None:
122
+ """Handle line within function body.
123
+
124
+ Args:
125
+ current_function: Current function
126
+ functions: Functions list
127
+ line: Full line
128
+ stripped: Stripped line
129
+ indent: Indent level
130
+ line_number: Line number
131
+
132
+ Returns:
133
+ Updated current function or None
134
+ """
135
+ if self._is_still_in_function(current_function, indent, stripped):
136
+ current_function["body"] += line + "\n"
137
+ return current_function
138
+ else:
139
+ if self._is_performance_critical(current_function):
140
+ self._finalize_function(current_function, functions, line_number)
141
+ return None
142
+
143
+ @staticmethod
144
+ def _is_still_in_function(
145
+ current_function: dict[str, t.Any], indent: int, stripped: str
146
+ ) -> bool:
147
+ """Check if still inside function.
148
+
149
+ Args:
150
+ current_function: Current function
151
+ indent: Indent level
152
+ stripped: Stripped line
153
+
154
+ Returns:
155
+ True if still inside
156
+ """
157
+ return indent > current_function["indent_level"] or (
158
+ indent == current_function["indent_level"]
159
+ and stripped.startswith(('"', "'", "@"))
160
+ )
161
+
162
+ def _finalize_function(
163
+ self,
164
+ function: dict[str, t.Any],
165
+ functions: list[dict[str, t.Any]],
166
+ end_line: int,
167
+ ) -> None:
168
+ """Finalize function and add to results.
169
+
170
+ Args:
171
+ function: Function to finalize
172
+ functions: Functions list
173
+ end_line: End line number
174
+ """
175
+ function["end_line"] = end_line
176
+ function["body_sample"] = function["body"][:300]
177
+ function["estimated_complexity"] = self._estimate_complexity(function["body"])
178
+ functions.append(function)
179
+
180
+ def _handle_last_function(
181
+ self,
182
+ current_function: dict[str, t.Any] | None,
183
+ functions: list[dict[str, t.Any]],
184
+ total_lines: int,
185
+ ) -> None:
186
+ """Handle last function in file.
187
+
188
+ Args:
189
+ current_function: Last function
190
+ functions: Functions list
191
+ total_lines: Total lines
192
+ """
193
+ if current_function and self._is_performance_critical(current_function):
194
+ self._finalize_function(current_function, functions, total_lines)
195
+
196
+ @staticmethod
197
+ def _is_performance_critical(function_info: dict[str, t.Any]) -> bool:
198
+ """Determine if function is performance-critical.
199
+
200
+ Args:
201
+ function_info: Function info
202
+
203
+ Returns:
204
+ True if performance-critical
205
+ """
206
+ body = function_info.get("body", "")
207
+ name = function_info.get("name", "")
208
+
209
+ performance_indicators = [
210
+ "for " in body
211
+ and len([line for line in body.split("\n") if "for " in line]) > 1,
212
+ "while " in body,
213
+ body.count("for ") > 0 and len(body) > 200,
214
+ any(pattern in body for pattern in (".append(", "+=", ".extend(", "len(")),
215
+ any(
216
+ pattern in name
217
+ for pattern in (
218
+ "process",
219
+ "analyze",
220
+ "compute",
221
+ "calculate",
222
+ "optimize",
223
+ )
224
+ ),
225
+ "range(" in body and ("1000" in body or "len(" in body),
226
+ ]
227
+
228
+ return any(performance_indicators)
229
+
230
+ @staticmethod
231
+ def _estimate_complexity(body: str) -> int:
232
+ """Estimate computational complexity of function.
233
+
234
+ Args:
235
+ body: Function body
236
+
237
+ Returns:
238
+ Complexity score
239
+ """
240
+ complexity = 1
241
+
242
+ nested_for_loops = 0
243
+ for_depth = 0
244
+ lines = body.split("\n")
245
+
246
+ for line in lines:
247
+ stripped = line.strip()
248
+ if "for " in stripped:
249
+ for_depth += 1
250
+ nested_for_loops = max(nested_for_loops, for_depth)
251
+ elif (
252
+ stripped
253
+ and not stripped.startswith("#")
254
+ and len(line) - len(line.lstrip()) == 0
255
+ ):
256
+ for_depth = 0
257
+
258
+ complexity = max(complexity, nested_for_loops)
259
+
260
+ if ".sort(" in body or "sorted(" in body:
261
+ complexity += 1
262
+ if body.count("len(") > 5:
263
+ complexity += 1
264
+ if ".index(" in body or ".find(" in body:
265
+ complexity += 1
266
+
267
+ return complexity
268
+
269
+ def analyze_performance_patterns(
270
+ self, semantic_insight: t.Any, current_func: dict[str, t.Any]
271
+ ) -> dict[str, t.Any]:
272
+ """Analyze semantic patterns for performance insights.
273
+
274
+ Args:
275
+ semantic_insight: Semantic insight from analysis
276
+ current_func: Current function
277
+
278
+ Returns:
279
+ Analysis dict
280
+ """
281
+ analysis: dict[str, t.Any] = {
282
+ "issues_found": False,
283
+ "optimization_suggestion": "Consider reviewing similar implementations for consistency",
284
+ "pattern_insights": [],
285
+ }
286
+
287
+ if semantic_insight.high_confidence_matches > 0:
288
+ analysis["issues_found"] = True
289
+ analysis["pattern_insights"].append(
290
+ f"Found {semantic_insight.high_confidence_matches} highly similar implementations"
291
+ )
292
+
293
+ performance_concerns = []
294
+ for pattern in semantic_insight.related_patterns:
295
+ content = pattern.get("content", "").lower()
296
+ if any(
297
+ concern in content for concern in ("for", "while", "+=", "append")
298
+ ):
299
+ performance_concerns.append(pattern["file_path"])
300
+
301
+ if performance_concerns:
302
+ analysis["optimization_suggestion"] = (
303
+ f"Performance review needed: {len(performance_concerns)} similar functions "
304
+ f"may benefit from the same optimization approach"
305
+ )
306
+ analysis["pattern_insights"].append(
307
+ f"Similar performance patterns found in: {', '.join(list(set(performance_concerns))[:3])}"
308
+ )
309
+
310
+ return analysis
311
+
312
+ def analyze_code_metrics(self, tree: ast.AST) -> dict[str, t.Any]:
313
+ """Analyze code metrics from AST.
314
+
315
+ Args:
316
+ tree: AST tree
317
+
318
+ Returns:
319
+ Metrics dict
320
+ """
321
+ metrics: dict[str, t.Any] = {
322
+ "total_functions": 0,
323
+ "total_classes": 0,
324
+ "average_function_length": 0,
325
+ "max_nesting_depth": 0,
326
+ "high_complexity_functions": [],
327
+ }
328
+
329
+ class MetricsCollector(ast.NodeVisitor):
330
+ def __init__(self) -> None:
331
+ self.function_count = 0
332
+ self.class_count = 0
333
+ self.function_lengths: list[int] = []
334
+ self.max_depth = 0
335
+
336
+ def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
337
+ self.function_count += 1
338
+ length = (node.end_lineno or node.lineno) - node.lineno
339
+ self.function_lengths.append(length)
340
+ self.generic_visit(node)
341
+
342
+ def visit_ClassDef(self, node: ast.ClassDef) -> None:
343
+ self.class_count += 1
344
+ self.generic_visit(node)
345
+
346
+ collector = MetricsCollector()
347
+ collector.visit(tree)
348
+
349
+ metrics["total_functions"] = collector.function_count
350
+ metrics["total_classes"] = collector.class_count
351
+
352
+ if collector.function_lengths:
353
+ metrics["average_function_length"] = sum(collector.function_lengths) / len(
354
+ collector.function_lengths
355
+ )
356
+
357
+ return metrics