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,704 @@
1
+ """Main documentation service for automated API documentation generation."""
2
+
3
+ import typing as t
4
+ from pathlib import Path
5
+
6
+ from acb.console import Console
7
+ from acb.depends import Inject, depends
8
+
9
+ from ..models.protocols import (
10
+ APIExtractorProtocol,
11
+ DocumentationGeneratorProtocol,
12
+ DocumentationServiceProtocol,
13
+ )
14
+ from .api_extractor import APIExtractorImpl
15
+ from .documentation_generator import DocumentationGeneratorImpl
16
+
17
+
18
+ class DocumentationServiceImpl(DocumentationServiceProtocol):
19
+ """Main service for automated documentation generation and maintenance."""
20
+
21
+ @depends.inject
22
+ def __init__(
23
+ self,
24
+ console: Inject[Console],
25
+ pkg_path: Path,
26
+ api_extractor: APIExtractorProtocol | None = None,
27
+ doc_generator: DocumentationGeneratorProtocol | None = None,
28
+ ) -> None:
29
+ self.console = console
30
+ self.pkg_path = pkg_path
31
+ self.api_extractor = api_extractor or APIExtractorImpl()
32
+ self.doc_generator = doc_generator or DocumentationGeneratorImpl()
33
+
34
+ # Define standard paths
35
+ self.docs_dir = pkg_path / "docs"
36
+ self.generated_docs_dir = self.docs_dir / "generated"
37
+ self.api_docs_dir = self.generated_docs_dir / "api"
38
+ self.guides_dir = self.generated_docs_dir / "guides"
39
+
40
+ # Ensure directories exist
41
+ self._ensure_directories()
42
+
43
+ def _categorize_source_files(
44
+ self, source_paths: list[Path]
45
+ ) -> dict[str, list[Path]]:
46
+ """Categorize source files by type."""
47
+ python_files = [p for p in source_paths if p.suffix == ".py"]
48
+
49
+ return {
50
+ "python": python_files,
51
+ "protocol": [p for p in python_files if p.name == "protocols.py"],
52
+ "service": [p for p in python_files if "/services/" in str(p)],
53
+ "manager": [p for p in python_files if "/managers/" in str(p)],
54
+ "cli": [p for p in python_files if "/cli/" in str(p)],
55
+ "mcp": [
56
+ p
57
+ for p in source_paths
58
+ if "/mcp/" in str(p) or p.suffix in (".py", ".md")
59
+ ],
60
+ }
61
+
62
+ def _extract_specialized_apis(
63
+ self, categorized_files: dict[str, list[Path]]
64
+ ) -> dict[str, t.Any]:
65
+ """Extract specialized API documentation."""
66
+ api_data = {}
67
+
68
+ # Extract protocol definitions
69
+ if categorized_files["protocol"]:
70
+ for protocol_file in categorized_files["protocol"]:
71
+ protocol_data = self.api_extractor.extract_protocol_definitions(
72
+ protocol_file
73
+ )
74
+ api_data.update(protocol_data)
75
+
76
+ # Extract service interfaces
77
+ if categorized_files["service"]:
78
+ service_data = self.api_extractor.extract_service_interfaces(
79
+ categorized_files["service"]
80
+ )
81
+ api_data.update(service_data)
82
+
83
+ # Extract manager interfaces
84
+ if categorized_files["manager"]:
85
+ manager_data = self.api_extractor.extract_service_interfaces(
86
+ categorized_files["manager"]
87
+ )
88
+ if "services" in manager_data:
89
+ api_data["managers"] = manager_data["services"]
90
+
91
+ # Extract CLI commands
92
+ if categorized_files["cli"]:
93
+ cli_data = self.api_extractor.extract_cli_commands(categorized_files["cli"])
94
+ api_data.update(cli_data)
95
+
96
+ # Extract MCP tools
97
+ if categorized_files["mcp"]:
98
+ mcp_data = self.api_extractor.extract_mcp_tools(categorized_files["mcp"])
99
+ api_data.update(mcp_data)
100
+
101
+ return api_data
102
+
103
+ def extract_api_documentation(self, source_paths: list[Path]) -> dict[str, t.Any]:
104
+ """Extract API documentation from source code files."""
105
+ self.console.print(
106
+ "[cyan]📖[/cyan] Extracting API documentation from source files..."
107
+ )
108
+
109
+ categorized_files = self._categorize_source_files(source_paths)
110
+ api_data = {}
111
+
112
+ # Extract from Python files
113
+ if categorized_files["python"]:
114
+ python_data = self.api_extractor.extract_from_python_files(
115
+ categorized_files["python"]
116
+ )
117
+ api_data.update(python_data)
118
+
119
+ # Extract specialized APIs
120
+ api_data.update(self._extract_specialized_apis(categorized_files))
121
+
122
+ self.console.print(
123
+ f"[green]✅[/green] Extracted documentation from {len(source_paths)} files"
124
+ )
125
+ return api_data
126
+
127
+ def generate_documentation(
128
+ self, template_name: str, context: dict[str, t.Any]
129
+ ) -> str:
130
+ """Generate documentation using specified template."""
131
+ try:
132
+ return self.doc_generator.render_template(Path(template_name), context)
133
+ except (FileNotFoundError, ValueError):
134
+ # Try built-in templates
135
+ return self.doc_generator.generate_api_reference(context)
136
+
137
+ def validate_documentation(self, doc_paths: list[Path]) -> list[dict[str, str]]:
138
+ """Validate documentation for issues and inconsistencies."""
139
+ issues = []
140
+
141
+ for doc_path in doc_paths:
142
+ if not doc_path.exists():
143
+ issues.append(
144
+ {
145
+ "type": "missing_file",
146
+ "path": str(doc_path),
147
+ "message": "Documentation file does not exist",
148
+ }
149
+ )
150
+ continue
151
+
152
+ try:
153
+ content = doc_path.read_text(encoding="utf-8")
154
+
155
+ # Check for broken internal links
156
+ broken_links = self._check_internal_links(content, doc_path)
157
+ issues.extend(broken_links)
158
+
159
+ # Check for empty sections
160
+ empty_sections = self._check_empty_sections(content, doc_path)
161
+ issues.extend(empty_sections)
162
+
163
+ # Check for outdated version references
164
+ outdated_refs = self._check_version_references(content, doc_path)
165
+ issues.extend(outdated_refs)
166
+
167
+ except Exception as e:
168
+ issues.append(
169
+ {
170
+ "type": "read_error",
171
+ "path": str(doc_path),
172
+ "message": f"Could not read file: {e}",
173
+ }
174
+ )
175
+
176
+ return issues
177
+
178
+ def update_documentation_index(self) -> bool:
179
+ """Update the main documentation index with links to all docs."""
180
+ try:
181
+ index_path = self.docs_dir / "INDEX.md"
182
+
183
+ # Collect all documentation files
184
+ api_docs = (
185
+ list[t.Any](self.api_docs_dir.glob("*.md"))
186
+ if self.api_docs_dir.exists()
187
+ else []
188
+ )
189
+ guide_docs = (
190
+ list[t.Any](self.guides_dir.glob("*.md"))
191
+ if self.guides_dir.exists()
192
+ else []
193
+ )
194
+ root_docs = [
195
+ f
196
+ for f in self.docs_dir.glob("*.md")
197
+ if f.name not in ("INDEX.md", "README.md")
198
+ ]
199
+
200
+ # Generate index content
201
+ index_content = self._generate_index_content(
202
+ api_docs, guide_docs, root_docs
203
+ )
204
+
205
+ # Write index file
206
+ index_path.write_text(index_content, encoding="utf-8")
207
+
208
+ self.console.print(
209
+ f"[green]✅[/green] Updated documentation index at {index_path}"
210
+ )
211
+ return True
212
+
213
+ except Exception as e:
214
+ self.console.print(
215
+ f"[red]❌[/red] Failed to update documentation index: {e}"
216
+ )
217
+ return False
218
+
219
+ def get_documentation_coverage(self) -> dict[str, t.Any]:
220
+ """Calculate documentation coverage metrics."""
221
+ # Find all source files
222
+ source_files = self._find_source_files()
223
+
224
+ # Extract API data
225
+ api_data = self.extract_api_documentation(source_files)
226
+
227
+ # Count documented vs undocumented items
228
+ total_items, documented_items = self._count_documentation_items(api_data)
229
+
230
+ # Calculate coverage percentage
231
+ coverage_percentage = (
232
+ (documented_items / total_items * 100) if total_items > 0 else 0.0
233
+ )
234
+
235
+ return {
236
+ "total_items": total_items,
237
+ "documented_items": documented_items,
238
+ "coverage_percentage": coverage_percentage,
239
+ "undocumented_items": total_items - documented_items,
240
+ }
241
+
242
+ def _find_source_files(self) -> list[Path]:
243
+ """Find all Python source files excluding hidden directories."""
244
+ source_files = list[t.Any](self.pkg_path.glob("**/*.py"))
245
+ return [
246
+ f for f in source_files if not any(part.startswith(".") for part in f.parts)
247
+ ]
248
+
249
+ def _count_documentation_items(self, api_data: dict[str, t.Any]) -> tuple[int, int]:
250
+ """Count total and documented items in API data."""
251
+ total_items = 0
252
+ documented_items = 0
253
+
254
+ # Count protocols
255
+ protocol_total, protocol_documented = self._count_protocol_items(
256
+ api_data.get("protocols", {})
257
+ )
258
+ total_items += protocol_total
259
+ documented_items += protocol_documented
260
+
261
+ # Count modules (classes and functions)
262
+ module_total, module_documented = self._count_module_items(
263
+ api_data.get("modules", {})
264
+ )
265
+ total_items += module_total
266
+ documented_items += module_documented
267
+
268
+ return total_items, documented_items
269
+
270
+ def _count_protocol_items(self, protocols: dict[str, t.Any]) -> tuple[int, int]:
271
+ """Count protocol-related documentation items."""
272
+ total_items = 0
273
+ documented_items = 0
274
+
275
+ for protocol_info in protocols.values():
276
+ # Count protocol itself
277
+ total_items += 1
278
+ if protocol_info.get("docstring", {}).get("description"):
279
+ documented_items += 1
280
+
281
+ # Count protocol methods
282
+ method_total, method_documented = self._count_method_items(
283
+ protocol_info.get("methods", [])
284
+ )
285
+ total_items += method_total
286
+ documented_items += method_documented
287
+
288
+ return total_items, documented_items
289
+
290
+ def _count_module_items(self, modules: dict[str, t.Any]) -> tuple[int, int]:
291
+ """Count module-related documentation items."""
292
+ total_items = 0
293
+ documented_items = 0
294
+
295
+ for module_data in modules.values():
296
+ # Count classes
297
+ class_total, class_documented = self._count_class_items(
298
+ module_data.get("classes", [])
299
+ )
300
+ total_items += class_total
301
+ documented_items += class_documented
302
+
303
+ # Count functions
304
+ func_total, func_documented = self._count_function_items(
305
+ module_data.get("functions", [])
306
+ )
307
+ total_items += func_total
308
+ documented_items += func_documented
309
+
310
+ return total_items, documented_items
311
+
312
+ def _count_class_items(self, classes: list[dict[str, t.Any]]) -> tuple[int, int]:
313
+ """Count class-related documentation items."""
314
+ total_items = 0
315
+ documented_items = 0
316
+
317
+ for class_info in classes:
318
+ # Count class itself
319
+ total_items += 1
320
+ if class_info.get("docstring", {}).get("description"):
321
+ documented_items += 1
322
+
323
+ # Count class methods
324
+ method_total, method_documented = self._count_method_items(
325
+ class_info.get("methods", [])
326
+ )
327
+ total_items += method_total
328
+ documented_items += method_documented
329
+
330
+ return total_items, documented_items
331
+
332
+ def _count_function_items(
333
+ self, functions: list[dict[str, t.Any]]
334
+ ) -> tuple[int, int]:
335
+ """Count function documentation items."""
336
+ total_items = len(functions)
337
+ documented_items = sum(
338
+ 1
339
+ for func_info in functions
340
+ if func_info.get("docstring", {}).get("description")
341
+ )
342
+ return total_items, documented_items
343
+
344
+ def _count_method_items(self, methods: list[dict[str, t.Any]]) -> tuple[int, int]:
345
+ """Count method documentation items."""
346
+ total_items = len(methods)
347
+ documented_items = sum(
348
+ 1 for method in methods if method.get("docstring", {}).get("description")
349
+ )
350
+ return total_items, documented_items
351
+
352
+ def generate_full_api_documentation(self) -> bool:
353
+ """Generate complete API documentation for the project."""
354
+ try:
355
+ self.console.print(
356
+ "[cyan]📚[/cyan] Generating complete API documentation..."
357
+ )
358
+
359
+ # Find all source files
360
+ source_files = list[t.Any](self.pkg_path.glob("**/*.py"))
361
+ source_files = [
362
+ f
363
+ for f in source_files
364
+ if not any(part.startswith(".") for part in f.parts)
365
+ ]
366
+
367
+ # Extract API data
368
+ api_data = self.extract_api_documentation(source_files)
369
+
370
+ # Generate API reference
371
+ api_reference = self.doc_generator.generate_api_reference(api_data)
372
+ api_ref_path = self.api_docs_dir / "API_REFERENCE.md"
373
+ api_ref_path.write_text(api_reference, encoding="utf-8")
374
+
375
+ # Generate protocol documentation
376
+ if "protocols" in api_data:
377
+ protocol_docs = self._generate_protocol_documentation(
378
+ api_data["protocols"]
379
+ )
380
+ protocol_path = self.api_docs_dir / "PROTOCOLS.md"
381
+ protocol_path.write_text(protocol_docs, encoding="utf-8")
382
+
383
+ # Generate service documentation
384
+ if "services" in api_data:
385
+ service_docs = self._generate_service_documentation(
386
+ api_data["services"]
387
+ )
388
+ service_path = self.api_docs_dir / "SERVICES.md"
389
+ service_path.write_text(service_docs, encoding="utf-8")
390
+
391
+ # Generate CLI documentation
392
+ if "commands" in api_data:
393
+ cli_docs = self._generate_cli_documentation(api_data["commands"])
394
+ cli_path = self.api_docs_dir / "CLI_REFERENCE.md"
395
+ cli_path.write_text(cli_docs, encoding="utf-8")
396
+
397
+ # Update cross-references
398
+ cross_refs = self.doc_generator.generate_cross_references(api_data)
399
+ if cross_refs:
400
+ cross_ref_path = self.api_docs_dir / "CROSS_REFERENCES.md"
401
+ cross_ref_content = self._format_cross_references(cross_refs)
402
+ cross_ref_path.write_text(cross_ref_content, encoding="utf-8")
403
+
404
+ # Update documentation index
405
+ self.update_documentation_index()
406
+
407
+ self.console.print(
408
+ "[green]🎉[/green] API documentation generation completed!"
409
+ )
410
+ return True
411
+
412
+ except Exception as e:
413
+ self.console.print(
414
+ f"[red]❌[/red] Failed to generate API documentation: {e}"
415
+ )
416
+ return False
417
+
418
+ def _ensure_directories(self) -> None:
419
+ """Ensure all necessary documentation directories exist."""
420
+ directories = [
421
+ self.docs_dir,
422
+ self.generated_docs_dir,
423
+ self.api_docs_dir,
424
+ self.guides_dir,
425
+ ]
426
+
427
+ for directory in directories:
428
+ directory.mkdir(parents=True, exist_ok=True)
429
+
430
+ def _check_internal_links(
431
+ self, content: str, doc_path: Path
432
+ ) -> list[dict[str, str]]:
433
+ """Check for broken internal links in documentation."""
434
+ from .regex_patterns import SAFE_PATTERNS
435
+
436
+ issues = []
437
+
438
+ # Find markdown links [text](path)
439
+ link_pattern = SAFE_PATTERNS["extract_markdown_links"]._get_compiled_pattern()
440
+ matches = link_pattern.findall(content)
441
+
442
+ for link_text, link_path in matches:
443
+ if link_path.startswith(("http://", "https://", "mailto:")):
444
+ continue # Skip external links
445
+
446
+ # Resolve relative path
447
+ if link_path.startswith("/"):
448
+ target_path = self.pkg_path / link_path.lstrip("/")
449
+ else:
450
+ target_path = doc_path.parent / link_path
451
+
452
+ if not target_path.exists():
453
+ issues.append(
454
+ {
455
+ "type": "broken_link",
456
+ "path": str(doc_path),
457
+ "message": f"Broken internal link: [{link_text}]({link_path})",
458
+ }
459
+ )
460
+
461
+ return issues
462
+
463
+ def _check_empty_sections(
464
+ self, content: str, doc_path: Path
465
+ ) -> list[dict[str, str]]:
466
+ """Check for empty sections in documentation."""
467
+ import re
468
+
469
+ issues = []
470
+
471
+ # Find headers followed immediately by another header (empty section)
472
+ empty_section_pattern = re.compile( # REGEX OK: markdown section parsing
473
+ r"(#{1,6}\s+[^\n]+)\n\s*(#{1,6}\s+[^\n]+)", re.MULTILINE
474
+ )
475
+ matches = empty_section_pattern.findall(content)
476
+
477
+ for header1, header2 in matches:
478
+ issues.append(
479
+ {
480
+ "type": "empty_section",
481
+ "path": str(doc_path),
482
+ "message": f"Empty section found: {header1.strip()}",
483
+ }
484
+ )
485
+
486
+ return issues
487
+
488
+ def _check_version_references(
489
+ self, content: str, doc_path: Path
490
+ ) -> list[dict[str, str]]:
491
+ """Check for outdated version references."""
492
+ from .regex_patterns import SAFE_PATTERNS
493
+
494
+ issues = []
495
+
496
+ # Look for version patterns
497
+ version_pattern = SAFE_PATTERNS[
498
+ "extract_version_numbers"
499
+ ]._get_compiled_pattern()
500
+ matches = version_pattern.findall(content)
501
+
502
+ # This is a placeholder - in a real implementation you'd compare with current version
503
+ for version in matches:
504
+ if version != "1.0.0": # Placeholder version check
505
+ issues.append(
506
+ {
507
+ "type": "outdated_version",
508
+ "path": str(doc_path),
509
+ "message": f"Potentially outdated version reference: {version}",
510
+ }
511
+ )
512
+
513
+ return issues
514
+
515
+ def _generate_index_content(
516
+ self, api_docs: list[Path], guide_docs: list[Path], root_docs: list[Path]
517
+ ) -> str:
518
+ """Generate content for the documentation index."""
519
+ lines = [
520
+ "# Documentation Index\n\n",
521
+ "This is the complete documentation index for the project.\n\n",
522
+ ]
523
+
524
+ if api_docs:
525
+ lines.append("## API Documentation\n\n")
526
+ for doc in sorted(api_docs):
527
+ relative_path = doc.relative_to(self.docs_dir)
528
+ lines.append(f"- [{doc.stem}]({relative_path})\n")
529
+ lines.append("\n")
530
+
531
+ if guide_docs:
532
+ lines.append("## User Guides\n\n")
533
+ for doc in sorted(guide_docs):
534
+ relative_path = doc.relative_to(self.docs_dir)
535
+ lines.append(f"- [{doc.stem}]({relative_path})\n")
536
+ lines.append("\n")
537
+
538
+ if root_docs:
539
+ lines.append("## Additional Documentation\n\n")
540
+ for doc in sorted(root_docs):
541
+ lines.append(f"- [{doc.stem}]({doc.name})\n")
542
+ lines.append("\n")
543
+
544
+ return "".join(lines)
545
+
546
+ def _generate_protocol_documentation(self, protocols: dict[str, t.Any]) -> str:
547
+ """Generate focused protocol documentation."""
548
+ lines = ["# Protocol Reference\n\n"]
549
+ lines.append(
550
+ "This document describes all protocol interfaces used in the codebase.\n\n"
551
+ )
552
+
553
+ for protocol_name, protocol_info in sorted(protocols.items()):
554
+ lines.append(f"## {protocol_name}\n\n")
555
+
556
+ description = protocol_info.get("docstring", {}).get(
557
+ "description", "No description provided."
558
+ )
559
+ lines.append(f"{description}\n\n")
560
+
561
+ if protocol_info.get("runtime_checkable"):
562
+ lines.append("**Runtime Checkable:** Yes\n\n")
563
+
564
+ methods = protocol_info.get("methods", [])
565
+ if methods:
566
+ lines.append("### Required Methods\n\n")
567
+ for method in methods:
568
+ lines.append(f"#### `{method['name']}`\n\n")
569
+ method_desc = method.get("docstring", {}).get(
570
+ "description", "No description provided."
571
+ )
572
+ lines.append(f"{method_desc}\n\n")
573
+
574
+ # Add method signature
575
+ params = method.get("parameters", [])
576
+ param_strings = []
577
+ for param in params:
578
+ param_type = param.get("annotation", "Any")
579
+ param_strings.append(f"{param['name']}: {param_type}")
580
+
581
+ return_type = method.get("return_annotation", "Any")
582
+ signature = f"def {method['name']}({', '.join(param_strings)}) -> {return_type}"
583
+ lines.append(f"```python\n{signature}\n```\n\n")
584
+
585
+ lines.append("---\n\n")
586
+
587
+ return "".join(lines)
588
+
589
+ def _generate_service_documentation(self, services: dict[str, t.Any]) -> str:
590
+ """Generate focused service documentation."""
591
+ lines = ["# Service Reference\n\n"]
592
+ lines.append(
593
+ "This document describes all service implementations in the codebase.\n\n"
594
+ )
595
+
596
+ for service_name, service_info in sorted(services.items()):
597
+ service_section = self._generate_service_section(service_name, service_info)
598
+ lines.extend(service_section)
599
+
600
+ return "".join(lines)
601
+
602
+ def _generate_service_section(
603
+ self, service_name: str, service_info: dict[str, t.Any]
604
+ ) -> list[str]:
605
+ """Generate documentation section for a single service."""
606
+ lines: list[str] = []
607
+ lines.extend(
608
+ (
609
+ f"## {service_name}\n\n",
610
+ f"**Location:** `{service_info.get('path', 'Unknown')}`\n\n",
611
+ )
612
+ )
613
+
614
+ # Add protocols implemented
615
+ if service_info.get("protocols_implemented"):
616
+ protocol_lines = self._generate_protocols_implemented(
617
+ service_info["protocols_implemented"]
618
+ )
619
+ lines.extend(protocol_lines)
620
+
621
+ # Add class documentation
622
+ class_lines = self._generate_service_classes(service_info.get("classes", []))
623
+ lines.extend(class_lines)
624
+
625
+ return lines
626
+
627
+ def _generate_protocols_implemented(self, protocols: list[str]) -> list[str]:
628
+ """Generate protocols implemented section."""
629
+ lines = ["**Implements:**\n"]
630
+ for protocol in protocols:
631
+ lines.append(f"- {protocol}\n")
632
+ lines.append("\n")
633
+ return lines
634
+
635
+ def _generate_service_classes(self, classes: list[dict[str, t.Any]]) -> list[str]:
636
+ """Generate documentation for service classes."""
637
+ lines = []
638
+
639
+ for class_info in classes:
640
+ lines.append(f"### {class_info['name']}\n\n")
641
+ description = class_info.get("docstring", {}).get(
642
+ "description", "No description provided."
643
+ )
644
+ lines.append(f"{description}\n\n")
645
+
646
+ # Add public methods
647
+ public_method_lines = self._generate_public_methods(
648
+ class_info.get("methods", [])
649
+ )
650
+ lines.extend(public_method_lines)
651
+
652
+ return lines
653
+
654
+ def _generate_public_methods(self, methods: list[dict[str, t.Any]]) -> list[str]:
655
+ """Generate public methods documentation."""
656
+ public_methods = [m for m in methods if m.get("visibility") == "public"]
657
+
658
+ if not public_methods:
659
+ return []
660
+
661
+ lines = ["**Public Methods:**\n"]
662
+ for method in public_methods:
663
+ method_desc = method.get("docstring", {}).get("description", "")
664
+ lines.append(f"- `{method['name']}`: {method_desc}\n")
665
+ lines.append("\n")
666
+
667
+ return lines
668
+
669
+ def _generate_cli_documentation(self, commands: dict[str, t.Any]) -> str:
670
+ """Generate CLI reference documentation."""
671
+ lines = ["# CLI Reference\n\n"]
672
+ lines.append(
673
+ "This document describes all command-line options and usage patterns.\n\n"
674
+ )
675
+
676
+ for command_name, command_info in sorted(commands.items()):
677
+ lines.append(f"## {command_name}\n\n")
678
+
679
+ options = command_info.get("options", [])
680
+ if options:
681
+ lines.append("### Available Options\n\n")
682
+ for option in options:
683
+ lines.append(
684
+ f"- `--{option['name']}` ({option['type']}): {option.get('description', 'No description')}\n"
685
+ )
686
+ lines.append("\n")
687
+
688
+ return "".join(lines)
689
+
690
+ def _format_cross_references(self, cross_refs: dict[str, list[str]]) -> str:
691
+ """Format cross-references into markdown."""
692
+ lines = ["# Cross References\n\n"]
693
+ lines.append(
694
+ "This document shows where API components are used throughout the codebase.\n\n"
695
+ )
696
+
697
+ for name, references in sorted(cross_refs.items()):
698
+ if references:
699
+ lines.extend((f"## {name}\n\n", "**Referenced in:**\n"))
700
+ for ref in references:
701
+ lines.append(f"- {ref}\n")
702
+ lines.append("\n")
703
+
704
+ return "".join(lines)