gitflow-analytics 3.7.0__tar.gz → 3.7.5__tar.gz

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 (252) hide show
  1. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/PKG-INFO +1 -1
  2. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/_version.py +1 -1
  3. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/cli.py +244 -105
  4. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/config/repository.py +9 -1
  5. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/config/schema.py +48 -1
  6. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/identity_llm/analysis_pass.py +7 -2
  7. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics.egg-info/PKG-INFO +1 -1
  8. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics.egg-info/SOURCES.txt +0 -39
  9. gitflow_analytics-3.7.0/docs/CLEANUP_SUMMARY.md +0 -184
  10. gitflow_analytics-3.7.0/docs/PROJECT_CLEANUP_REPORT.md +0 -233
  11. gitflow_analytics-3.7.0/docs/STORY_POINTS_CONFIG_SUMMARY.md +0 -107
  12. gitflow_analytics-3.7.0/docs/_archive/analysis-files/ewtn-critical-security-report.md +0 -180
  13. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_engineer_20250915_085239_236.md +0 -100
  14. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_engineer_20250915_114233_697.md +0 -78
  15. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_engineer_20250915_115330_511.md +0 -80
  16. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_engineer_20250915_120516_669.md +0 -78
  17. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_engineer_20250915_124906_951.md +0 -87
  18. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_engineer_20250915_175540_671.md +0 -78
  19. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_engineer_20250915_214023_300.md +0 -95
  20. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_engineer_20250916_130622_510.md +0 -76
  21. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_ops_20250915_123323_419.md +0 -94
  22. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_ops_20250915_134446_128.md +0 -96
  23. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_ops_20250915_184656_725.md +0 -93
  24. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_research_20250915_091233_023.md +0 -77
  25. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_research_20250915_100404_339.md +0 -77
  26. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/agent_research_20250915_110606_413.md +0 -86
  27. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/system_prompt_20250915_084833_641.md +0 -2289
  28. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/system_prompt_20250915_090830_660.md +0 -2303
  29. gitflow_analytics-3.7.0/docs/_archive/old-logs/prompts/system_prompt_20250916_130545_822.md +0 -2289
  30. gitflow_analytics-3.7.0/docs/_archive/old-reports/output/database_qualitative_report_20250630_20250824.md +0 -47
  31. gitflow_analytics-3.7.0/docs/_archive/old-reports/output/narrative_report_20250630_20250824.md +0 -142
  32. gitflow_analytics-3.7.0/docs/_archive/old-reports/reports-24week/database_qualitative_report_20250303_20250817.md +0 -55
  33. gitflow_analytics-3.7.0/docs/_archive/old-reports/reports-24week/narrative_report_20250303_20250817.md +0 -157
  34. gitflow_analytics-3.7.0/docs/_archive/old-reports/test-ewtn-reports/narrative_report_20250810.md +0 -70
  35. gitflow_analytics-3.7.0/docs/_archive/old-reports/test-reports/database_qualitative_report_20250908_20250914.md +0 -53
  36. gitflow_analytics-3.7.0/docs/_archive/old-reports/test-reports/narrative_report_20250908_20250914.md +0 -182
  37. gitflow_analytics-3.7.0/docs/_archive/old-reports/test-weekly-reports/database_qualitative_report_20250623_20250817.md +0 -67
  38. gitflow_analytics-3.7.0/docs/_archive/old-reports/test-weekly-reports/narrative_report_20250623_20250817.md +0 -169
  39. gitflow_analytics-3.7.0/docs/_archive/temp-files/FIX_SUMMARY.md +0 -147
  40. gitflow_analytics-3.7.0/docs/guides/LLM_CLASSIFICATION_GUIDE.md +0 -164
  41. gitflow_analytics-3.7.0/src/gitflow_analytics/security/reports/__init__.py +0 -5
  42. gitflow_analytics-3.7.0/src/gitflow_analytics/security/reports/security_report.py +0 -358
  43. gitflow_analytics-3.7.0/tests/debug_bulk_exists.py +0 -62
  44. gitflow_analytics-3.7.0/tests/debug_commit_story_points.py +0 -145
  45. gitflow_analytics-3.7.0/tests/debug_database_storage.py +0 -228
  46. gitflow_analytics-3.7.0/tests/debug_jira_enrichment.py +0 -110
  47. gitflow_analytics-3.7.0/tests/debug_story_points.py +0 -121
  48. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/CHANGELOG.md +0 -0
  49. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/CLAUDE.md +0 -0
  50. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/LICENSE +0 -0
  51. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/MANIFEST.in +0 -0
  52. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/README.md +0 -0
  53. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/README.md +0 -0
  54. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/REFACTOR.md +0 -0
  55. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/SECURITY.md +0 -0
  56. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/STRUCTURE.md +0 -0
  57. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/_archive/temp-files/PROGRESS_TRACKING_FIXES.md +0 -0
  58. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/_archive/temp-files/SYNTAX_ERROR_FIX.md +0 -0
  59. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/architecture/README.md +0 -0
  60. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/architecture/branch-analysis-optimization.md +0 -0
  61. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/architecture/caching-strategy.md +0 -0
  62. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/architecture/llm-classifier-refactoring.md +0 -0
  63. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/architecture/ml-pipeline.md +0 -0
  64. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/configuration/configuration.md +0 -0
  65. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/deployment/README.md +0 -0
  66. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/design/README.md +0 -0
  67. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/design/circuit-breaker-implementation.md +0 -0
  68. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/design/commit-classification-design.md +0 -0
  69. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/design/git_pm_correlation_design.md +0 -0
  70. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/design/platform-agnostic-pm-framework.md +0 -0
  71. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/design/qualitative_data_extraction.md +0 -0
  72. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/developer/README.md +0 -0
  73. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/developer/contributing.md +0 -0
  74. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/developer/development-setup.md +0 -0
  75. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/developer/training-guide.md +0 -0
  76. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/examples/README.md +0 -0
  77. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/getting-started/README.md +0 -0
  78. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/getting-started/first-analysis.md +0 -0
  79. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/getting-started/installation.md +0 -0
  80. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/getting-started/quickstart.md +0 -0
  81. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/guides/README.md +0 -0
  82. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/guides/chatgpt-setup.md +0 -0
  83. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/guides/identity-resolution-enhanced.md +0 -0
  84. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/guides/interactive-launcher.md +0 -0
  85. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/guides/managing-aliases.md +0 -0
  86. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/guides/ml-categorization.md +0 -0
  87. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/guides/troubleshooting.md +0 -0
  88. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/quick-reference/launcher-and-identity.md +0 -0
  89. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/reference/README.md +0 -0
  90. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/reference/cache-system.md +0 -0
  91. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/reference/cli-commands.md +0 -0
  92. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/reference/configuration-schema.md +0 -0
  93. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/docs/reference/json-export-schema.md +0 -0
  94. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/pyproject.toml +0 -0
  95. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/setup.cfg +0 -0
  96. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/__init__.py +0 -0
  97. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/classification/__init__.py +0 -0
  98. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/classification/batch_classifier.py +0 -0
  99. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/classification/classifier.py +0 -0
  100. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/classification/feature_extractor.py +0 -0
  101. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/classification/linguist_analyzer.py +0 -0
  102. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/classification/model.py +0 -0
  103. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/cli_wizards/__init__.py +0 -0
  104. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/cli_wizards/install_wizard.py +0 -0
  105. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/cli_wizards/run_launcher.py +0 -0
  106. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/config/__init__.py +0 -0
  107. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/config/aliases.py +0 -0
  108. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/config/errors.py +0 -0
  109. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/config/loader.py +0 -0
  110. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/config/profiles.py +0 -0
  111. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/config/validator.py +0 -0
  112. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/config.py +0 -0
  113. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/constants.py +0 -0
  114. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/__init__.py +0 -0
  115. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/analyzer.py +0 -0
  116. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/branch_mapper.py +0 -0
  117. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/cache.py +0 -0
  118. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/data_fetcher.py +0 -0
  119. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/git_auth.py +0 -0
  120. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/git_timeout_wrapper.py +0 -0
  121. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/identity.py +0 -0
  122. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/metrics_storage.py +0 -0
  123. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/progress.py +0 -0
  124. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/schema_version.py +0 -0
  125. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/core/subprocess_git.py +0 -0
  126. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/extractors/__init__.py +0 -0
  127. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/extractors/base.py +0 -0
  128. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/extractors/ml_tickets.py +0 -0
  129. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/extractors/story_points.py +0 -0
  130. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/extractors/tickets.py +0 -0
  131. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/identity_llm/__init__.py +0 -0
  132. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/identity_llm/analyzer.py +0 -0
  133. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/identity_llm/models.py +0 -0
  134. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/integrations/__init__.py +0 -0
  135. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/integrations/github_integration.py +0 -0
  136. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/integrations/jira_integration.py +0 -0
  137. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/integrations/orchestrator.py +0 -0
  138. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/metrics/__init__.py +0 -0
  139. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/metrics/activity_scoring.py +0 -0
  140. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/metrics/branch_health.py +0 -0
  141. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/metrics/dora.py +0 -0
  142. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/models/__init__.py +0 -0
  143. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/models/database.py +0 -0
  144. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/pm_framework/__init__.py +0 -0
  145. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/pm_framework/adapters/__init__.py +0 -0
  146. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/pm_framework/adapters/jira_adapter.py +0 -0
  147. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/pm_framework/base.py +0 -0
  148. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/pm_framework/models.py +0 -0
  149. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/pm_framework/orchestrator.py +0 -0
  150. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/pm_framework/registry.py +0 -0
  151. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/__init__.py +0 -0
  152. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/chatgpt_analyzer.py +0 -0
  153. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/__init__.py +0 -0
  154. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/change_type.py +0 -0
  155. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/domain_classifier.py +0 -0
  156. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/intent_analyzer.py +0 -0
  157. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/llm/__init__.py +0 -0
  158. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/llm/base.py +0 -0
  159. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/llm/batch_processor.py +0 -0
  160. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/llm/cache.py +0 -0
  161. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/llm/cost_tracker.py +0 -0
  162. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/llm/openai_client.py +0 -0
  163. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/llm/prompts.py +0 -0
  164. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/llm/response_parser.py +0 -0
  165. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/llm_commit_classifier.py +0 -0
  166. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/classifiers/risk_analyzer.py +0 -0
  167. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/core/__init__.py +0 -0
  168. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/core/llm_fallback.py +0 -0
  169. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/core/nlp_engine.py +0 -0
  170. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/core/pattern_cache.py +0 -0
  171. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/core/processor.py +0 -0
  172. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/enhanced_analyzer.py +0 -0
  173. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/example_enhanced_usage.py +0 -0
  174. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/models/__init__.py +0 -0
  175. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/models/schemas.py +0 -0
  176. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/utils/__init__.py +0 -0
  177. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/utils/batch_processor.py +0 -0
  178. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/utils/cost_tracker.py +0 -0
  179. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/utils/metrics.py +0 -0
  180. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/qualitative/utils/text_processing.py +0 -0
  181. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/__init__.py +0 -0
  182. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/analytics_writer.py +0 -0
  183. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/base.py +0 -0
  184. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/branch_health_writer.py +0 -0
  185. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/classification_writer.py +0 -0
  186. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/cli_integration.py +0 -0
  187. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/csv_writer.py +0 -0
  188. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/data_models.py +0 -0
  189. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/database_report_generator.py +0 -0
  190. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/example_usage.py +0 -0
  191. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/factory.py +0 -0
  192. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/formatters.py +0 -0
  193. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/html_generator.py +0 -0
  194. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/interfaces.py +0 -0
  195. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/json_exporter.py +0 -0
  196. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/narrative_writer.py +0 -0
  197. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/story_point_correlation.py +0 -0
  198. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/reports/weekly_trends_writer.py +0 -0
  199. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/security/__init__.py +0 -0
  200. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/security/config.py +0 -0
  201. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/security/extractors/__init__.py +0 -0
  202. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/security/extractors/dependency_checker.py +0 -0
  203. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/security/extractors/secret_detector.py +0 -0
  204. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/security/extractors/vulnerability_scanner.py +0 -0
  205. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/security/llm_analyzer.py +0 -0
  206. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/security/security_analyzer.py +0 -0
  207. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/training/__init__.py +0 -0
  208. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/training/model_loader.py +0 -0
  209. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/training/pipeline.py +0 -0
  210. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/ui/__init__.py +0 -0
  211. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/ui/progress_display.py +0 -0
  212. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics/verify_activity.py +0 -0
  213. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics.egg-info/dependency_links.txt +0 -0
  214. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics.egg-info/entry_points.txt +0 -0
  215. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics.egg-info/requires.txt +0 -0
  216. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/src/gitflow_analytics.egg-info/top_level.txt +0 -0
  217. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/__init__.py +0 -0
  218. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/conftest.py +0 -0
  219. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/core/__init__.py +0 -0
  220. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/core/test_analyzer.py +0 -0
  221. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/core/test_cache.py +0 -0
  222. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/core/test_data_fetcher.py +0 -0
  223. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/core/test_identity.py +0 -0
  224. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/core/test_progress.py +0 -0
  225. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/extractors/__init__.py +0 -0
  226. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/integrations/__init__.py +0 -0
  227. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/metrics/__init__.py +0 -0
  228. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/models/__init__.py +0 -0
  229. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/qualitative/__init__.py +0 -0
  230. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/qualitative/test_basic_integration.py +0 -0
  231. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/reports/__init__.py +0 -0
  232. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_atomic_caching.py +0 -0
  233. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_classification_system.py +0 -0
  234. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_cli.py +0 -0
  235. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_config.py +0 -0
  236. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_config_extends.py +0 -0
  237. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_config_profiles.py +0 -0
  238. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_config_story_points.py +0 -0
  239. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_jira_connection.py +0 -0
  240. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_llm_commit_classification.py +0 -0
  241. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_march_2025_comparison.py +0 -0
  242. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_metrics.py +0 -0
  243. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_ml_accuracy.py +0 -0
  244. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_ml_components.py +0 -0
  245. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_ml_comprehensive.py +0 -0
  246. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_ml_integration.py +0 -0
  247. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_pm_env_resolution.py +0 -0
  248. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_report_abstraction.py +0 -0
  249. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_reports.py +0 -0
  250. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_story_points_analysis.py +0 -0
  251. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_training_pipeline.py +0 -0
  252. {gitflow_analytics-3.7.0 → gitflow_analytics-3.7.5}/tests/test_two_step_process.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitflow-analytics
3
- Version: 3.7.0
3
+ Version: 3.7.5
4
4
  Summary: Analyze Git repositories for developer productivity insights
5
5
  Author-email: Bob Matyas <bobmatnyc@gmail.com>
6
6
  License: MIT
@@ -1,4 +1,4 @@
1
1
  """Version information for gitflow-analytics."""
2
2
 
3
- __version__ = "3.7.0"
3
+ __version__ = "3.7.5"
4
4
  __version_info__ = tuple(int(x) for x in __version__.split("."))
@@ -944,7 +944,7 @@ def analyze(
944
944
  data_fetcher = GitDataFetcher(
945
945
  cache=cache,
946
946
  branch_mapping_rules=cfg.analysis.branch_mapping_rules,
947
- allowed_ticket_platforms=cfg.analysis.ticket_platforms,
947
+ allowed_ticket_platforms=cfg.get_effective_ticket_platforms(),
948
948
  exclude_paths=cfg.analysis.exclude_paths,
949
949
  )
950
950
 
@@ -1135,9 +1135,7 @@ def analyze(
1135
1135
  analyzer = GitAnalyzer(
1136
1136
  cache,
1137
1137
  branch_mapping_rules=cfg.analysis.branch_mapping_rules,
1138
- allowed_ticket_platforms=getattr(
1139
- cfg.analysis, "ticket_platforms", ["jira", "github", "clickup", "linear"]
1140
- ),
1138
+ allowed_ticket_platforms=cfg.get_effective_ticket_platforms(),
1141
1139
  exclude_paths=cfg.analysis.exclude_paths,
1142
1140
  story_point_patterns=cfg.analysis.story_point_patterns,
1143
1141
  ml_categorization_config=ml_config,
@@ -1164,9 +1162,28 @@ def analyze(
1164
1162
  # Use a 'repos' directory in the config directory for cloned repositories
1165
1163
  config_dir = Path(config).parent if config else Path.cwd()
1166
1164
  repos_dir = config_dir / "repos"
1167
- discovered_repos = cfg.discover_organization_repositories(clone_base_path=repos_dir)
1165
+
1166
+ # Progress callback for repository discovery
1167
+ def discovery_progress(repo_name, count):
1168
+ if display and display._live:
1169
+ display.update_progress_task(
1170
+ "main",
1171
+ description=f"🔍 Discovering: {repo_name} ({count} repos checked)",
1172
+ completed=15 + min(count % 5, 4), # Show some movement
1173
+ )
1174
+ else:
1175
+ # Simple inline progress - just show count
1176
+ click.echo(f"\r 📦 Checking repositories... {count}", nl=False)
1177
+
1178
+ discovered_repos = cfg.discover_organization_repositories(
1179
+ clone_base_path=repos_dir, progress_callback=discovery_progress
1180
+ )
1168
1181
  repositories_to_analyze = discovered_repos
1169
1182
 
1183
+ # Clear the progress line
1184
+ if not (display and display._live):
1185
+ click.echo("\r" + " " * 60 + "\r", nl=False) # Clear line
1186
+
1170
1187
  if display and display._live:
1171
1188
  # We're in full-screen mode, update progress and initialize repo list
1172
1189
  display.update_progress_task(
@@ -1703,14 +1720,14 @@ def analyze(
1703
1720
  "📊 No commits or batches found for date range - proceeding with data fetch"
1704
1721
  )
1705
1722
 
1706
- # PROCEED WITH EMERGENCY FETCH if validation didn't pass
1723
+ # PROCEED WITH INITIAL FETCH if validation didn't pass
1707
1724
  if not validation_passed:
1708
1725
  if display:
1709
1726
  display.print_status(
1710
- "Data validation failed - running emergency data fetch", "warning"
1727
+ "Data validation failed - running initial data fetch", "warning"
1711
1728
  )
1712
1729
  else:
1713
- click.echo("⚠️ Data validation failed - running emergency data fetch")
1730
+ click.echo("⚠️ Data validation failed - running initial data fetch")
1714
1731
 
1715
1732
  # Force data fetch for all repositories since we have no batches
1716
1733
  repos_needing_analysis = repositories_to_analyze
@@ -1719,12 +1736,12 @@ def analyze(
1719
1736
  if repos_needing_analysis:
1720
1737
  if display:
1721
1738
  display.print_status(
1722
- f"Emergency fetch: Fetching data for {len(repos_needing_analysis)} repositories...",
1739
+ f"Initial fetch: Fetching data for {len(repos_needing_analysis)} repositories...",
1723
1740
  "info",
1724
1741
  )
1725
1742
  else:
1726
1743
  click.echo(
1727
- f"🚨 Emergency fetch: Fetching data for {len(repos_needing_analysis)} repositories..."
1744
+ f"🚨 Initial fetch: Fetching data for {len(repos_needing_analysis)} repositories..."
1728
1745
  )
1729
1746
  click.echo(
1730
1747
  " 📋 Reason: Need to ensure commits and batches exist for classification"
@@ -1760,89 +1777,163 @@ def analyze(
1760
1777
  # Check if repo exists, clone if needed (critical for organization mode)
1761
1778
  if not repo_path.exists():
1762
1779
  if repo_config.github_repo and cfg.github.organization:
1763
- if display:
1764
- display.print_status(
1765
- f" 📥 Cloning {repo_config.github_repo} from GitHub...",
1766
- "info",
1767
- )
1768
- else:
1769
- click.echo(f" 📥 Cloning {repo_config.github_repo} from GitHub...")
1770
- try:
1771
- # Ensure parent directory exists
1772
- repo_path.parent.mkdir(parents=True, exist_ok=True)
1773
-
1774
- # Build clone URL with authentication
1775
- clone_url = f"https://github.com/{repo_config.github_repo}.git"
1776
- if cfg.github.token:
1777
- clone_url = f"https://{cfg.github.token}@github.com/{repo_config.github_repo}.git"
1778
-
1779
- # Clone using subprocess for better control
1780
- env = os.environ.copy()
1781
- env["GIT_TERMINAL_PROMPT"] = "0"
1782
- env["GIT_ASKPASS"] = ""
1783
- env["GCM_INTERACTIVE"] = "never"
1784
-
1785
- cmd = ["git", "clone", "--config", "credential.helper="]
1786
- if repo_config.branch:
1787
- cmd.extend(["-b", repo_config.branch])
1788
- cmd.extend([clone_url, str(repo_path)])
1789
-
1790
- result = subprocess.run(
1791
- cmd,
1792
- env=env,
1793
- capture_output=True,
1794
- text=True,
1795
- timeout=30,
1796
- )
1780
+ # Retry logic for cloning
1781
+ max_retries = 2
1782
+ retry_count = 0
1783
+ clone_success = False
1784
+
1785
+ while retry_count <= max_retries and not clone_success:
1786
+ if retry_count > 0:
1787
+ if display:
1788
+ display.print_status(
1789
+ f" 🔄 Retry {retry_count}/{max_retries}: {repo_config.github_repo}",
1790
+ "warning",
1791
+ )
1792
+ else:
1793
+ click.echo(
1794
+ f" 🔄 Retry {retry_count}/{max_retries}: {repo_config.github_repo}"
1795
+ )
1796
+ else:
1797
+ if display:
1798
+ display.print_status(
1799
+ f" 📥 Cloning {repo_config.github_repo} from GitHub...",
1800
+ "info",
1801
+ )
1802
+ else:
1803
+ click.echo(
1804
+ f" 📥 Cloning {repo_config.github_repo} from GitHub..."
1805
+ )
1806
+
1807
+ try:
1808
+ # Ensure parent directory exists
1809
+ repo_path.parent.mkdir(parents=True, exist_ok=True)
1810
+
1811
+ # Build clone URL with authentication
1812
+ clone_url = (
1813
+ f"https://github.com/{repo_config.github_repo}.git"
1814
+ )
1815
+ if cfg.github.token:
1816
+ clone_url = f"https://{cfg.github.token}@github.com/{repo_config.github_repo}.git"
1817
+
1818
+ # Clone using subprocess for better control
1819
+ env = os.environ.copy()
1820
+ env["GIT_TERMINAL_PROMPT"] = "0"
1821
+ env["GIT_ASKPASS"] = ""
1822
+ env["GCM_INTERACTIVE"] = "never"
1823
+ env["GIT_PROGRESS"] = "1" # Force progress output
1824
+
1825
+ cmd = [
1826
+ "git",
1827
+ "clone",
1828
+ "--progress",
1829
+ "--config",
1830
+ "credential.helper=",
1831
+ ]
1832
+ if repo_config.branch:
1833
+ cmd.extend(["-b", repo_config.branch])
1834
+ cmd.extend([clone_url, str(repo_path)])
1835
+
1836
+ # Track start time for timeout reporting
1837
+ import time
1838
+
1839
+ start_time = time.time()
1840
+ timeout_seconds = 300 # 5 minutes for large repos
1841
+
1842
+ # Run without capturing stderr to show git progress
1843
+ result = subprocess.run(
1844
+ cmd,
1845
+ env=env,
1846
+ stdout=subprocess.PIPE,
1847
+ stderr=None, # Let stderr (progress) flow to terminal
1848
+ text=True,
1849
+ timeout=timeout_seconds,
1850
+ )
1797
1851
 
1798
- if result.returncode != 0:
1799
- error_msg = result.stderr or result.stdout
1800
- if any(
1801
- x in error_msg.lower()
1802
- for x in ["authentication", "permission denied", "401", "403"]
1803
- ):
1852
+ elapsed = time.time() - start_time
1853
+
1854
+ if result.returncode != 0:
1855
+ error_msg = "Clone failed"
1856
+ if any(
1857
+ x in error_msg.lower()
1858
+ for x in [
1859
+ "authentication",
1860
+ "permission denied",
1861
+ "401",
1862
+ "403",
1863
+ ]
1864
+ ):
1865
+ if display:
1866
+ display.print_status(
1867
+ f" ❌ Authentication failed for {repo_config.github_repo}",
1868
+ "error",
1869
+ )
1870
+ else:
1871
+ click.echo(
1872
+ f" ❌ Authentication failed for {repo_config.github_repo}"
1873
+ )
1874
+ break # Don't retry auth failures
1875
+ else:
1876
+ raise subprocess.CalledProcessError(
1877
+ result.returncode,
1878
+ cmd,
1879
+ result.stdout,
1880
+ result.stderr,
1881
+ )
1882
+ else:
1883
+ clone_success = True
1804
1884
  if display:
1805
1885
  display.print_status(
1806
- f" Authentication failed for {repo_config.github_repo}",
1807
- "error",
1886
+ f" Cloned {repo_config.github_repo} ({elapsed:.1f}s)",
1887
+ "success",
1808
1888
  )
1809
1889
  else:
1810
1890
  click.echo(
1811
- f" Authentication failed for {repo_config.github_repo}"
1891
+ f" Cloned {repo_config.github_repo} ({elapsed:.1f}s)"
1812
1892
  )
1813
- continue
1893
+
1894
+ except subprocess.TimeoutExpired:
1895
+ retry_count += 1
1896
+ if display:
1897
+ display.print_status(
1898
+ f" ⏱️ Clone timeout after {timeout_seconds}s: {repo_config.github_repo}",
1899
+ "error",
1900
+ )
1814
1901
  else:
1815
- raise subprocess.CalledProcessError(
1816
- result.returncode, cmd, result.stdout, result.stderr
1902
+ click.echo(
1903
+ f" ⏱️ Clone timeout after {timeout_seconds}s: {repo_config.github_repo}"
1817
1904
  )
1905
+ # Clean up partial clone
1906
+ if repo_path.exists():
1907
+ import shutil
1818
1908
 
1819
- if display:
1820
- display.print_status(
1821
- f" ✅ Cloned {repo_config.github_repo}", "success"
1822
- )
1823
- else:
1824
- click.echo(f" ✅ Cloned {repo_config.github_repo}")
1909
+ shutil.rmtree(repo_path, ignore_errors=True)
1910
+ if retry_count > max_retries:
1911
+ if display:
1912
+ display.print_status(
1913
+ f" ❌ Skipping {repo_config.github_repo} after {max_retries} timeouts",
1914
+ "error",
1915
+ )
1916
+ else:
1917
+ click.echo(
1918
+ f" ❌ Skipping {repo_config.github_repo} after {max_retries} timeouts"
1919
+ )
1920
+ break
1921
+ continue # Try again
1922
+
1923
+ except Exception as e:
1924
+ retry_count += 1
1925
+ if display:
1926
+ display.print_status(
1927
+ f" ❌ Clone error: {e}", "error"
1928
+ )
1929
+ else:
1930
+ click.echo(f" ❌ Clone error: {e}")
1931
+ if retry_count > max_retries:
1932
+ break
1933
+ continue # Try again
1825
1934
 
1826
- except subprocess.TimeoutExpired:
1827
- if display:
1828
- display.print_status(
1829
- f" ❌ Clone timeout for {repo_config.github_repo}",
1830
- "error",
1831
- )
1832
- else:
1833
- click.echo(f" ❌ Clone timeout for {repo_config.github_repo}")
1834
- continue
1835
- except Exception as e:
1836
- if display:
1837
- display.print_status(
1838
- f" ❌ Failed to clone {repo_config.github_repo}: {e}",
1839
- "error",
1840
- )
1841
- else:
1842
- click.echo(
1843
- f" ❌ Failed to clone {repo_config.github_repo}: {e}"
1844
- )
1845
- continue
1935
+ if not clone_success:
1936
+ continue # Skip this repo and move to next
1846
1937
  else:
1847
1938
  # No github_repo configured, can't clone
1848
1939
  if display:
@@ -1928,15 +2019,15 @@ def analyze(
1928
2019
 
1929
2020
  if display:
1930
2021
  display.print_status(
1931
- f"Emergency fetch complete: {total_commits} commits, {total_tickets} tickets",
2022
+ f"Initial fetch complete: {total_commits} commits, {total_tickets} tickets",
1932
2023
  "success",
1933
2024
  )
1934
2025
  else:
1935
2026
  click.echo(
1936
- f"🚨 Emergency fetch complete: {total_commits} commits, {total_tickets} tickets"
2027
+ f"🚨 Initial fetch complete: {total_commits} commits, {total_tickets} tickets"
1937
2028
  )
1938
2029
 
1939
- # RE-VALIDATE after emergency fetch
2030
+ # RE-VALIDATE after initial fetch
1940
2031
  with cache.get_session() as session:
1941
2032
  final_commits = (
1942
2033
  session.query(CachedCommit)
@@ -1961,7 +2052,7 @@ def analyze(
1961
2052
  )
1962
2053
 
1963
2054
  if final_commits == 0:
1964
- error_msg = "❌ CRITICAL: Emergency fetch completed but still 0 commits stored in database"
2055
+ error_msg = "❌ CRITICAL: Initial fetch completed but still 0 commits stored in database"
1965
2056
  if display:
1966
2057
  display.print_status(error_msg, "error")
1967
2058
  else:
@@ -1969,7 +2060,9 @@ def analyze(
1969
2060
  click.echo(
1970
2061
  f" 📅 Date range: {start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}"
1971
2062
  )
1972
- click.echo(f" 📊 Emergency stats: {total_commits} commits reported")
2063
+ click.echo(
2064
+ f" 📊 Initial fetch stats: {total_commits} commits reported"
2065
+ )
1973
2066
  click.echo(
1974
2067
  f" 🗃️ Database result: {final_commits} commits, {final_batches} batches"
1975
2068
  )
@@ -1983,7 +2076,7 @@ def analyze(
1983
2076
  " - Repository has no commits in the specified time range"
1984
2077
  )
1985
2078
  raise click.ClickException(
1986
- "Emergency fetch failed validation - no data available for classification"
2079
+ "Initial fetch failed validation - no data available for classification"
1987
2080
  )
1988
2081
 
1989
2082
  if display:
@@ -2342,25 +2435,33 @@ def analyze(
2342
2435
  env["GIT_TERMINAL_PROMPT"] = "0"
2343
2436
  env["GIT_ASKPASS"] = ""
2344
2437
  env["GCM_INTERACTIVE"] = "never"
2438
+ env["GIT_PROGRESS"] = "1" # Force progress output
2345
2439
 
2346
2440
  # Build git clone command
2347
- cmd = ["git", "clone", "--config", "credential.helper="]
2441
+ cmd = [
2442
+ "git",
2443
+ "clone",
2444
+ "--progress",
2445
+ "--config",
2446
+ "credential.helper=",
2447
+ ]
2348
2448
  if repo_config.branch:
2349
2449
  cmd.extend(["-b", repo_config.branch])
2350
2450
  cmd.extend([clone_url, str(repo_config.path)])
2351
2451
 
2352
- # Run with timeout to prevent hanging
2452
+ # Run with timeout to prevent hanging, let progress show on stderr
2353
2453
  result = subprocess.run(
2354
2454
  cmd,
2355
2455
  env=env,
2356
- capture_output=True,
2456
+ stdout=subprocess.PIPE,
2457
+ stderr=None, # Let stderr (progress) flow to terminal
2357
2458
  text=True,
2358
- timeout=30, # 30 second timeout
2459
+ timeout=120, # Increase timeout for large repos
2359
2460
  )
2360
2461
 
2361
2462
  if result.returncode != 0:
2362
2463
  raise git.GitCommandError(
2363
- cmd, result.returncode, stderr=result.stderr
2464
+ cmd, result.returncode, stderr="Clone failed"
2364
2465
  )
2365
2466
  except subprocess.TimeoutExpired:
2366
2467
  if display:
@@ -2409,13 +2510,19 @@ def analyze(
2409
2510
  cmd = [
2410
2511
  "git",
2411
2512
  "clone",
2513
+ "--progress",
2412
2514
  "--config",
2413
2515
  "credential.helper=",
2414
2516
  clone_url,
2415
2517
  str(repo_config.path),
2416
2518
  ]
2417
2519
  result = subprocess.run(
2418
- cmd, env=env, capture_output=True, text=True, timeout=30
2520
+ cmd,
2521
+ env=env,
2522
+ stdout=subprocess.PIPE,
2523
+ stderr=None,
2524
+ text=True,
2525
+ timeout=120,
2419
2526
  )
2420
2527
  if result.returncode != 0:
2421
2528
  raise git.GitCommandError(
@@ -4192,9 +4299,7 @@ def fetch(
4192
4299
  data_fetcher = GitDataFetcher(
4193
4300
  cache=cache,
4194
4301
  branch_mapping_rules=getattr(cfg.analysis, "branch_mapping_rules", {}),
4195
- allowed_ticket_platforms=getattr(
4196
- cfg.analysis, "ticket_platforms", ["jira", "github", "clickup", "linear"]
4197
- ),
4302
+ allowed_ticket_platforms=cfg.get_effective_ticket_platforms(),
4198
4303
  exclude_paths=getattr(cfg.analysis, "exclude_paths", None),
4199
4304
  )
4200
4305
 
@@ -4217,9 +4322,23 @@ def fetch(
4217
4322
  # Use a 'repos' directory in the config directory for cloned repositories
4218
4323
  config_dir = Path(config).parent if config else Path.cwd()
4219
4324
  repos_dir = config_dir / "repos"
4220
- discovered_repos = cfg.discover_organization_repositories(clone_base_path=repos_dir)
4325
+
4326
+ # Progress callback for repository discovery
4327
+ def discovery_progress(repo_name, count):
4328
+ if display:
4329
+ display.print_status(f" 📦 Checking: {repo_name} ({count})", "info")
4330
+ else:
4331
+ click.echo(f"\r 📦 Checking repositories... {count}", nl=False)
4332
+
4333
+ discovered_repos = cfg.discover_organization_repositories(
4334
+ clone_base_path=repos_dir, progress_callback=discovery_progress
4335
+ )
4221
4336
  repositories_to_fetch = discovered_repos
4222
4337
 
4338
+ # Clear the progress line
4339
+ if not display:
4340
+ click.echo("\r" + " " * 60 + "\r", nl=False) # Clear line
4341
+
4223
4342
  if display:
4224
4343
  display.print_status(
4225
4344
  f"Found {len(discovered_repos)} repositories in organization", "success"
@@ -4400,6 +4519,8 @@ def cache_stats(config: Path) -> None:
4400
4519
  - Decide when to clear cache
4401
4520
  - Troubleshoot slow analyses
4402
4521
  """
4522
+ from .core.cache import GitAnalysisCache
4523
+
4403
4524
  try:
4404
4525
  cfg = ConfigLoader.load(config)
4405
4526
  cache = GitAnalysisCache(cfg.cache.directory)
@@ -4454,6 +4575,8 @@ def merge_identity(config: Path, dev1: str, dev2: str) -> None:
4454
4575
  - Refreshes cached statistics
4455
4576
  - Updates identity mappings
4456
4577
  """
4578
+ from .core.identity import DeveloperIdentityResolver
4579
+
4457
4580
  try:
4458
4581
  cfg = ConfigLoader.load(config)
4459
4582
  identity_resolver = DeveloperIdentityResolver(cfg.cache.directory / "identities.db")
@@ -4719,6 +4842,7 @@ def discover_storypoint_fields(config: Path) -> None:
4719
4842
  return
4720
4843
 
4721
4844
  # Initialize PM integration (currently JIRA)
4845
+ from .core.cache import GitAnalysisCache
4722
4846
  from .integrations.jira_integration import JIRAIntegration
4723
4847
 
4724
4848
  # Create minimal cache for integration
@@ -4802,6 +4926,9 @@ def identities(config: Path, weeks: int, apply: bool) -> None:
4802
4926
  Mappings are saved to 'analysis.identity.manual_mappings'
4803
4927
  Bot exclusions go to 'analysis.exclude.authors'
4804
4928
  """
4929
+ from .core.analyzer import GitAnalyzer
4930
+ from .core.cache import GitAnalysisCache
4931
+
4805
4932
  try:
4806
4933
  cfg = ConfigLoader.load(config)
4807
4934
  cache = GitAnalysisCache(cfg.cache.directory)
@@ -4862,9 +4989,7 @@ def identities(config: Path, weeks: int, apply: bool) -> None:
4862
4989
  analyzer = GitAnalyzer(
4863
4990
  cache,
4864
4991
  branch_mapping_rules=cfg.analysis.branch_mapping_rules,
4865
- allowed_ticket_platforms=getattr(
4866
- cfg.analysis, "ticket_platforms", ["jira", "github", "clickup", "linear"]
4867
- ),
4992
+ allowed_ticket_platforms=cfg.get_effective_ticket_platforms(),
4868
4993
  exclude_paths=cfg.analysis.exclude_paths,
4869
4994
  story_point_patterns=cfg.analysis.story_point_patterns,
4870
4995
  ml_categorization_config=ml_config,
@@ -5032,6 +5157,8 @@ def aliases_command(
5032
5157
  """
5033
5158
  try:
5034
5159
  from .config.aliases import AliasesManager, DeveloperAlias
5160
+ from .core.analyzer import GitAnalyzer
5161
+ from .core.cache import GitAnalysisCache
5035
5162
  from .identity_llm.analyzer import LLMIdentityAnalyzer
5036
5163
 
5037
5164
  # Load configuration
@@ -5099,9 +5226,7 @@ def aliases_command(
5099
5226
  analyzer = GitAnalyzer(
5100
5227
  cache,
5101
5228
  branch_mapping_rules=cfg.analysis.branch_mapping_rules,
5102
- allowed_ticket_platforms=getattr(
5103
- cfg.analysis, "ticket_platforms", ["jira", "github", "clickup", "linear"]
5104
- ),
5229
+ allowed_ticket_platforms=cfg.get_effective_ticket_platforms(),
5105
5230
  exclude_paths=cfg.analysis.exclude_paths,
5106
5231
  story_point_patterns=cfg.analysis.story_point_patterns,
5107
5232
  ml_categorization_config=ml_config,
@@ -5335,6 +5460,8 @@ def list_developers(config: Path) -> None:
5335
5460
  - Finding developer email addresses
5336
5461
  - Checking contribution statistics
5337
5462
  """
5463
+ from .core.identity import DeveloperIdentityResolver
5464
+
5338
5465
  try:
5339
5466
  cfg = ConfigLoader.load(config)
5340
5467
  identity_resolver = DeveloperIdentityResolver(cfg.cache.directory / "identities.db")
@@ -5468,6 +5595,8 @@ def train(
5468
5595
  - scikit-learn and pandas dependencies
5469
5596
  - ~100MB disk space for model storage
5470
5597
  """
5598
+ from .core.cache import GitAnalysisCache
5599
+ from .integrations.orchestrator import IntegrationOrchestrator
5471
5600
 
5472
5601
  # Configure logging
5473
5602
  if log.upper() != "NONE":
@@ -5551,8 +5680,18 @@ def train(
5551
5680
  try:
5552
5681
  config_dir = Path(config).parent if config else Path.cwd()
5553
5682
  repos_dir = config_dir / "repos"
5554
- discovered_repos = cfg.discover_organization_repositories(clone_base_path=repos_dir)
5683
+
5684
+ # Progress callback for repository discovery
5685
+ def discovery_progress(repo_name, count):
5686
+ click.echo(f"\r 📦 Checking repositories... {count}", nl=False)
5687
+
5688
+ discovered_repos = cfg.discover_organization_repositories(
5689
+ clone_base_path=repos_dir, progress_callback=discovery_progress
5690
+ )
5555
5691
  repositories_to_analyze = discovered_repos
5692
+
5693
+ # Clear the progress line and show result
5694
+ click.echo("\r" + " " * 60 + "\r", nl=False)
5556
5695
  click.echo(f"✅ Found {len(discovered_repos)} repositories in organization")
5557
5696
  except Exception as e:
5558
5697
  click.echo(f"❌ Failed to discover repositories: {e}")
@@ -20,12 +20,13 @@ class RepositoryManager:
20
20
  self.github_config = github_config
21
21
 
22
22
  def discover_organization_repositories(
23
- self, clone_base_path: Optional[Path] = None
23
+ self, clone_base_path: Optional[Path] = None, progress_callback=None
24
24
  ) -> list[RepositoryConfig]:
25
25
  """Discover repositories from GitHub organization.
26
26
 
27
27
  Args:
28
28
  clone_base_path: Base directory where repos should be cloned/found.
29
+ progress_callback: Optional callback function(repo_name, count) for progress updates.
29
30
 
30
31
  Returns:
31
32
  List of discovered repository configurations.
@@ -42,7 +43,14 @@ class RepositoryManager:
42
43
  if clone_base_path is None:
43
44
  raise ValueError("No base path available for repository cloning")
44
45
 
46
+ repo_count = 0
45
47
  for repo in org.get_repos():
48
+ repo_count += 1
49
+
50
+ # Call progress callback if provided
51
+ if progress_callback:
52
+ progress_callback(repo.name, repo_count)
53
+
46
54
  # Skip archived repositories
47
55
  if repo.archived:
48
56
  continue