roadmap-cli 0.1.1__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 (521) hide show
  1. roadmap/__init__.py +27 -0
  2. roadmap/adapters/__init__.py +1 -0
  3. roadmap/adapters/base_paginated_adapter.py +117 -0
  4. roadmap/adapters/cli/__init__.py +249 -0
  5. roadmap/adapters/cli/analysis/__init__.py +5 -0
  6. roadmap/adapters/cli/analysis/commands.py +370 -0
  7. roadmap/adapters/cli/analysis/presenter.py +125 -0
  8. roadmap/adapters/cli/archive_operations.py +86 -0
  9. roadmap/adapters/cli/cli_command_helpers.py +109 -0
  10. roadmap/adapters/cli/cli_confirmations.py +74 -0
  11. roadmap/adapters/cli/cli_error_handlers.py +146 -0
  12. roadmap/adapters/cli/cli_validators.py +39 -0
  13. roadmap/adapters/cli/commands/sync_status.py +308 -0
  14. roadmap/adapters/cli/comment/__init__.py +5 -0
  15. roadmap/adapters/cli/comment/commands.py +106 -0
  16. roadmap/adapters/cli/config/__init__.py +5 -0
  17. roadmap/adapters/cli/config/commands.py +198 -0
  18. roadmap/adapters/cli/console_exports.py +10 -0
  19. roadmap/adapters/cli/core.py +26 -0
  20. roadmap/adapters/cli/crud/__init__.py +47 -0
  21. roadmap/adapters/cli/crud/base_archive.py +208 -0
  22. roadmap/adapters/cli/crud/base_create.py +154 -0
  23. roadmap/adapters/cli/crud/base_delete.py +155 -0
  24. roadmap/adapters/cli/crud/base_restore.py +283 -0
  25. roadmap/adapters/cli/crud/base_update.py +193 -0
  26. roadmap/adapters/cli/crud/crud_helpers.py +206 -0
  27. roadmap/adapters/cli/crud/crud_utils.py +152 -0
  28. roadmap/adapters/cli/crud/entity_builders.py +374 -0
  29. roadmap/adapters/cli/data/__init__.py +8 -0
  30. roadmap/adapters/cli/data/commands.py +149 -0
  31. roadmap/adapters/cli/decorators.py +208 -0
  32. roadmap/adapters/cli/dtos/__init__.py +155 -0
  33. roadmap/adapters/cli/exception_handler.py +105 -0
  34. roadmap/adapters/cli/git/__init__.py +8 -0
  35. roadmap/adapters/cli/git/commands.py +475 -0
  36. roadmap/adapters/cli/git/handlers/__init__.py +1 -0
  37. roadmap/adapters/cli/git/handlers/git_authentication_handler.py +124 -0
  38. roadmap/adapters/cli/git/handlers/git_branch_handler.py +238 -0
  39. roadmap/adapters/cli/git/handlers/git_connectivity_handler.py +122 -0
  40. roadmap/adapters/cli/git/handlers/git_hooks_handler.py +105 -0
  41. roadmap/adapters/cli/git/hooks_config.py +327 -0
  42. roadmap/adapters/cli/git/status_display.py +158 -0
  43. roadmap/adapters/cli/health/__init__.py +8 -0
  44. roadmap/adapters/cli/health/db_integrity.py +204 -0
  45. roadmap/adapters/cli/health/enhancer.py +227 -0
  46. roadmap/adapters/cli/health/fixer.py +295 -0
  47. roadmap/adapters/cli/health/fixers/__init__.py +10 -0
  48. roadmap/adapters/cli/health/fixers/corrupted_comments_fixer.py +231 -0
  49. roadmap/adapters/cli/health/fixers/data_integrity_fixer.py +137 -0
  50. roadmap/adapters/cli/health/fixers/duplicate_issues_fixer.py +138 -0
  51. roadmap/adapters/cli/health/fixers/folder_structure_fixer.py +114 -0
  52. roadmap/adapters/cli/health/fixers/label_normalization_fixer.py +162 -0
  53. roadmap/adapters/cli/health/fixers/milestone_name_normalization_fixer.py +181 -0
  54. roadmap/adapters/cli/health/fixers/milestone_naming_compliance_fixer.py +244 -0
  55. roadmap/adapters/cli/health/fixers/milestone_parse_error_fixer.py +162 -0
  56. roadmap/adapters/cli/health/fixers/milestone_validation_fixer.py +211 -0
  57. roadmap/adapters/cli/health/fixers/old_backups_fixer.py +135 -0
  58. roadmap/adapters/cli/health/fixers/orphaned_issues_fixer.py +252 -0
  59. roadmap/adapters/cli/health/formatter.py +250 -0
  60. roadmap/adapters/cli/health/formatters.py +427 -0
  61. roadmap/adapters/cli/health/scan.py +293 -0
  62. roadmap/adapters/cli/init/__init__.py +5 -0
  63. roadmap/adapters/cli/init/commands.py +587 -0
  64. roadmap/adapters/cli/init.py +9 -0
  65. roadmap/adapters/cli/issues/__init__.py +70 -0
  66. roadmap/adapters/cli/issues/archive.py +137 -0
  67. roadmap/adapters/cli/issues/archive_class.py +253 -0
  68. roadmap/adapters/cli/issues/block.py +39 -0
  69. roadmap/adapters/cli/issues/close.py +216 -0
  70. roadmap/adapters/cli/issues/comment.py +178 -0
  71. roadmap/adapters/cli/issues/create.py +162 -0
  72. roadmap/adapters/cli/issues/delete.py +31 -0
  73. roadmap/adapters/cli/issues/deps.py +161 -0
  74. roadmap/adapters/cli/issues/issue_status_helpers.py +111 -0
  75. roadmap/adapters/cli/issues/link.py +308 -0
  76. roadmap/adapters/cli/issues/list.py +402 -0
  77. roadmap/adapters/cli/issues/lookup.py +96 -0
  78. roadmap/adapters/cli/issues/progress.py +102 -0
  79. roadmap/adapters/cli/issues/restore.py +96 -0
  80. roadmap/adapters/cli/issues/restore_class.py +57 -0
  81. roadmap/adapters/cli/issues/start.py +165 -0
  82. roadmap/adapters/cli/issues/sync_status.py +374 -0
  83. roadmap/adapters/cli/issues/unblock.py +43 -0
  84. roadmap/adapters/cli/issues/unlink.py +104 -0
  85. roadmap/adapters/cli/issues/update.py +120 -0
  86. roadmap/adapters/cli/issues/view.py +36 -0
  87. roadmap/adapters/cli/layout.py +220 -0
  88. roadmap/adapters/cli/mappers.py +200 -0
  89. roadmap/adapters/cli/milestones/__init__.py +52 -0
  90. roadmap/adapters/cli/milestones/archive.py +125 -0
  91. roadmap/adapters/cli/milestones/archive_class.py +236 -0
  92. roadmap/adapters/cli/milestones/assign.py +62 -0
  93. roadmap/adapters/cli/milestones/close.py +177 -0
  94. roadmap/adapters/cli/milestones/create.py +131 -0
  95. roadmap/adapters/cli/milestones/delete.py +27 -0
  96. roadmap/adapters/cli/milestones/kanban.py +123 -0
  97. roadmap/adapters/cli/milestones/list.py +87 -0
  98. roadmap/adapters/cli/milestones/recalculate.py +79 -0
  99. roadmap/adapters/cli/milestones/restore.py +87 -0
  100. roadmap/adapters/cli/milestones/restore_class.py +99 -0
  101. roadmap/adapters/cli/milestones/update.py +61 -0
  102. roadmap/adapters/cli/milestones/view.py +142 -0
  103. roadmap/adapters/cli/output_manager.py +319 -0
  104. roadmap/adapters/cli/presentation/base_presenter.py +121 -0
  105. roadmap/adapters/cli/presentation/cleanup_presenter.py +235 -0
  106. roadmap/adapters/cli/presentation/core_initialization_presenter.py +277 -0
  107. roadmap/adapters/cli/presentation/crud_presenter.py +134 -0
  108. roadmap/adapters/cli/presentation/daily_summary_presenter.py +266 -0
  109. roadmap/adapters/cli/presentation/issue_presenter.py +258 -0
  110. roadmap/adapters/cli/presentation/milestone_list_presenter.py +135 -0
  111. roadmap/adapters/cli/presentation/milestone_presenter.py +297 -0
  112. roadmap/adapters/cli/presentation/project_presenter.py +233 -0
  113. roadmap/adapters/cli/presentation/project_status_presenter.py +186 -0
  114. roadmap/adapters/cli/presentation/table_builders.py +95 -0
  115. roadmap/adapters/cli/projects/__init__.py +42 -0
  116. roadmap/adapters/cli/projects/archive.py +127 -0
  117. roadmap/adapters/cli/projects/archive_class.py +96 -0
  118. roadmap/adapters/cli/projects/close.py +94 -0
  119. roadmap/adapters/cli/projects/create.py +50 -0
  120. roadmap/adapters/cli/projects/delete.py +27 -0
  121. roadmap/adapters/cli/projects/list.py +227 -0
  122. roadmap/adapters/cli/projects/restore.py +87 -0
  123. roadmap/adapters/cli/projects/restore_class.py +56 -0
  124. roadmap/adapters/cli/projects/update.py +57 -0
  125. roadmap/adapters/cli/projects/view.py +157 -0
  126. roadmap/adapters/cli/services/__init__.py +1 -0
  127. roadmap/adapters/cli/services/daily_summary_service.py +313 -0
  128. roadmap/adapters/cli/services/export_manager.py +268 -0
  129. roadmap/adapters/cli/services/milestone_list_service.py +266 -0
  130. roadmap/adapters/cli/services/project_initialization_service.py +29 -0
  131. roadmap/adapters/cli/services/project_status_service.py +462 -0
  132. roadmap/adapters/cli/services/sync_service.py +62 -0
  133. roadmap/adapters/cli/status.py +408 -0
  134. roadmap/adapters/cli/styling.py +21 -0
  135. roadmap/adapters/cli/sync.py +1117 -0
  136. roadmap/adapters/cli/sync_context.py +432 -0
  137. roadmap/adapters/cli/sync_handlers/__init__.py +77 -0
  138. roadmap/adapters/cli/sync_handlers/apply_ops.py +522 -0
  139. roadmap/adapters/cli/sync_handlers/baseline_ops.py +366 -0
  140. roadmap/adapters/cli/sync_handlers/conflict_ops.py +161 -0
  141. roadmap/adapters/cli/sync_handlers/dry_run_display.py +237 -0
  142. roadmap/adapters/cli/sync_handlers/interactive_resolver.py +396 -0
  143. roadmap/adapters/cli/sync_handlers/progress_tracker.py +128 -0
  144. roadmap/adapters/cli/sync_metrics_command.py +190 -0
  145. roadmap/adapters/cli/sync_presenter.py +58 -0
  146. roadmap/adapters/cli/sync_validation.py +295 -0
  147. roadmap/adapters/cli/today.py +52 -0
  148. roadmap/adapters/cli/utils/click_options.py +38 -0
  149. roadmap/adapters/git/__init__.py +1 -0
  150. roadmap/adapters/git/git.py +208 -0
  151. roadmap/adapters/git/git_branch_manager.py +400 -0
  152. roadmap/adapters/git/git_command_executor.py +56 -0
  153. roadmap/adapters/git/git_commit_analyzer.py +334 -0
  154. roadmap/adapters/git/git_hooks.py +22 -0
  155. roadmap/adapters/git/git_hooks_manager.py +455 -0
  156. roadmap/adapters/git/git_repository_info.py +65 -0
  157. roadmap/adapters/git/hook_installer.py +106 -0
  158. roadmap/adapters/git/hook_registry.py +97 -0
  159. roadmap/adapters/git/hook_script_generator.py +58 -0
  160. roadmap/adapters/git/sync_monitor.py +409 -0
  161. roadmap/adapters/git/workflow_automation.py +286 -0
  162. roadmap/adapters/github/__init__.py +1 -0
  163. roadmap/adapters/github/github.py +360 -0
  164. roadmap/adapters/github/handlers/__init__.py +17 -0
  165. roadmap/adapters/github/handlers/base.py +337 -0
  166. roadmap/adapters/github/handlers/collaborators.py +165 -0
  167. roadmap/adapters/github/handlers/comments.py +118 -0
  168. roadmap/adapters/github/handlers/issues.py +150 -0
  169. roadmap/adapters/github/handlers/labels.py +164 -0
  170. roadmap/adapters/github/handlers/milestones.py +104 -0
  171. roadmap/adapters/persistence/__init__.py +35 -0
  172. roadmap/adapters/persistence/conflict_resolver.py +190 -0
  173. roadmap/adapters/persistence/database_manager.py +492 -0
  174. roadmap/adapters/persistence/entity_sync_coordinators.py +672 -0
  175. roadmap/adapters/persistence/file_locking.py +348 -0
  176. roadmap/adapters/persistence/file_parser.py +92 -0
  177. roadmap/adapters/persistence/file_synchronizer.py +107 -0
  178. roadmap/adapters/persistence/focused_managers.py +140 -0
  179. roadmap/adapters/persistence/git_history.py +330 -0
  180. roadmap/adapters/persistence/parser/__init__.py +20 -0
  181. roadmap/adapters/persistence/parser/frontmatter.py +152 -0
  182. roadmap/adapters/persistence/parser/issue.py +245 -0
  183. roadmap/adapters/persistence/parser/milestone.py +146 -0
  184. roadmap/adapters/persistence/parser/project.py +106 -0
  185. roadmap/adapters/persistence/persistence.py +288 -0
  186. roadmap/adapters/persistence/repositories/__init__.py +15 -0
  187. roadmap/adapters/persistence/repositories/issue_repository.py +223 -0
  188. roadmap/adapters/persistence/repositories/milestone_repository.py +140 -0
  189. roadmap/adapters/persistence/repositories/project_repository.py +168 -0
  190. roadmap/adapters/persistence/repositories/remote_link_repository.py +355 -0
  191. roadmap/adapters/persistence/repositories/sync_state_repository.py +66 -0
  192. roadmap/adapters/persistence/storage/__init__.py +36 -0
  193. roadmap/adapters/persistence/storage/conflicts.py +101 -0
  194. roadmap/adapters/persistence/storage/connection_manager.py +79 -0
  195. roadmap/adapters/persistence/storage/issue_storage.py +89 -0
  196. roadmap/adapters/persistence/storage/milestone_storage.py +80 -0
  197. roadmap/adapters/persistence/storage/project_storage.py +102 -0
  198. roadmap/adapters/persistence/storage/queries.py +227 -0
  199. roadmap/adapters/persistence/storage/state_manager.py +652 -0
  200. roadmap/adapters/persistence/storage/sync_state_storage.py +207 -0
  201. roadmap/adapters/persistence/sync_metrics_repository.py +342 -0
  202. roadmap/adapters/persistence/sync_orchestrator.py +293 -0
  203. roadmap/adapters/persistence/sync_state_tracker.py +86 -0
  204. roadmap/adapters/persistence/yaml_repositories.py +711 -0
  205. roadmap/adapters/sync/__init__.py +21 -0
  206. roadmap/adapters/sync/backend_factory.py +108 -0
  207. roadmap/adapters/sync/backends/__init__.py +15 -0
  208. roadmap/adapters/sync/backends/converters.py +209 -0
  209. roadmap/adapters/sync/backends/github_backend_helpers.py +380 -0
  210. roadmap/adapters/sync/backends/github_client.py +99 -0
  211. roadmap/adapters/sync/backends/github_sync_backend.py +792 -0
  212. roadmap/adapters/sync/backends/github_sync_ops.py +908 -0
  213. roadmap/adapters/sync/backends/services/__init__.py +1 -0
  214. roadmap/adapters/sync/backends/services/github_authentication_service.py +105 -0
  215. roadmap/adapters/sync/backends/services/github_issue_delete_service.py +423 -0
  216. roadmap/adapters/sync/backends/services/github_issue_dependency_service.py +63 -0
  217. roadmap/adapters/sync/backends/services/github_issue_fetch_service.py +158 -0
  218. roadmap/adapters/sync/backends/services/github_label_sync_service.py +126 -0
  219. roadmap/adapters/sync/backends/services/github_local_issue_sync_service.py +229 -0
  220. roadmap/adapters/sync/backends/services/github_milestone_fetch_service.py +204 -0
  221. roadmap/adapters/sync/backends/vanilla_git_sync_backend.py +198 -0
  222. roadmap/adapters/sync/services/__init__.py +11 -0
  223. roadmap/adapters/sync/services/baseline_state_handler.py +83 -0
  224. roadmap/adapters/sync/services/conflict_converter.py +85 -0
  225. roadmap/adapters/sync/services/issue_persistence_service.py +263 -0
  226. roadmap/adapters/sync/services/issue_state_service.py +243 -0
  227. roadmap/adapters/sync/services/local_change_filter.py +129 -0
  228. roadmap/adapters/sync/services/pull_result_processor.py +71 -0
  229. roadmap/adapters/sync/services/remote_issue_creation_service.py +112 -0
  230. roadmap/adapters/sync/services/sync_analysis_service.py +250 -0
  231. roadmap/adapters/sync/services/sync_authentication_service.py +57 -0
  232. roadmap/adapters/sync/services/sync_data_fetch_service.py +212 -0
  233. roadmap/adapters/sync/services/sync_linking_service.py +329 -0
  234. roadmap/adapters/sync/services/sync_report_service.py +62 -0
  235. roadmap/adapters/sync/services/sync_state_update_service.py +51 -0
  236. roadmap/adapters/sync/sync_cache_orchestrator.py +454 -0
  237. roadmap/adapters/sync/sync_merge_engine.py +416 -0
  238. roadmap/adapters/sync/sync_merge_orchestrator.py +1313 -0
  239. roadmap/adapters/sync/sync_retrieval_orchestrator.py +810 -0
  240. roadmap/application/services/__init__.py +1 -0
  241. roadmap/application/services/deduplicate_service.py +517 -0
  242. roadmap/application/use_cases/__init__.py +1 -0
  243. roadmap/common/__init__.py +308 -0
  244. roadmap/common/cache.py +209 -0
  245. roadmap/common/cli_errors.py +147 -0
  246. roadmap/common/configuration/__init__.py +33 -0
  247. roadmap/common/configuration/config_loader.py +264 -0
  248. roadmap/common/configuration/config_manager.py +164 -0
  249. roadmap/common/configuration/config_schema.py +145 -0
  250. roadmap/common/configuration/github/__init__.py +9 -0
  251. roadmap/common/configuration/github/config_manager.py +154 -0
  252. roadmap/common/configuration/github/token_resolver.py +84 -0
  253. roadmap/common/console.py +184 -0
  254. roadmap/common/constants.py +134 -0
  255. roadmap/common/datetime_parser.py +319 -0
  256. roadmap/common/error_formatter.py +84 -0
  257. roadmap/common/errors/__init__.py +143 -0
  258. roadmap/common/errors/error_base.py +73 -0
  259. roadmap/common/errors/error_file.py +82 -0
  260. roadmap/common/errors/error_git.py +67 -0
  261. roadmap/common/errors/error_handler.py +166 -0
  262. roadmap/common/errors/error_network.py +90 -0
  263. roadmap/common/errors/error_security.py +78 -0
  264. roadmap/common/errors/error_standards.py +561 -0
  265. roadmap/common/errors/error_validation.py +111 -0
  266. roadmap/common/errors/exceptions.py +432 -0
  267. roadmap/common/formatters/__init__.py +29 -0
  268. roadmap/common/formatters/base_table_formatter.py +96 -0
  269. roadmap/common/formatters/export/__init__.py +7 -0
  270. roadmap/common/formatters/export/issue_exporter.py +97 -0
  271. roadmap/common/formatters/helpers.py +28 -0
  272. roadmap/common/formatters/kanban/__init__.py +9 -0
  273. roadmap/common/formatters/kanban/layout.py +48 -0
  274. roadmap/common/formatters/kanban/organizer.py +81 -0
  275. roadmap/common/formatters/output/__init__.py +15 -0
  276. roadmap/common/formatters/tables/__init__.py +11 -0
  277. roadmap/common/formatters/tables/column_factory.py +312 -0
  278. roadmap/common/formatters/tables/issue_table.py +276 -0
  279. roadmap/common/formatters/tables/milestone_table.py +247 -0
  280. roadmap/common/formatters/tables/project_table.py +195 -0
  281. roadmap/common/formatters/text/__init__.py +57 -0
  282. roadmap/common/formatters/text/basic.py +217 -0
  283. roadmap/common/formatters/text/display.py +42 -0
  284. roadmap/common/formatters/text/duration.py +36 -0
  285. roadmap/common/formatters/text/operations.py +325 -0
  286. roadmap/common/formatters/text/status_badges.py +57 -0
  287. roadmap/common/initialization/github/__init__.py +11 -0
  288. roadmap/common/initialization/github/setup_service.py +238 -0
  289. roadmap/common/initialization/github/setup_validator.py +78 -0
  290. roadmap/common/logging/__init__.py +113 -0
  291. roadmap/common/logging/audit_logging.py +5 -0
  292. roadmap/common/logging/correlation.py +45 -0
  293. roadmap/common/logging/decorators.py +267 -0
  294. roadmap/common/logging/error_logging.py +217 -0
  295. roadmap/common/logging/formatters.py +124 -0
  296. roadmap/common/logging/loggers.py +68 -0
  297. roadmap/common/logging/performance_tracking.py +267 -0
  298. roadmap/common/logging/utils.py +335 -0
  299. roadmap/common/models/__init__.py +44 -0
  300. roadmap/common/models/cli_models.py +118 -0
  301. roadmap/common/models/config_models.py +199 -0
  302. roadmap/common/models/output_models.py +381 -0
  303. roadmap/common/observability/__init__.py +28 -0
  304. roadmap/common/observability/instrumentation.py +103 -0
  305. roadmap/common/observability/observability.py +76 -0
  306. roadmap/common/observability/otel_init.py +109 -0
  307. roadmap/common/output_formatter.py +393 -0
  308. roadmap/common/progress.py +379 -0
  309. roadmap/common/result.py +396 -0
  310. roadmap/common/security/__init__.py +48 -0
  311. roadmap/common/security/exceptions.py +13 -0
  312. roadmap/common/security/export_cleanup.py +79 -0
  313. roadmap/common/security/file_operations.py +104 -0
  314. roadmap/common/security/filename_sanitization.py +54 -0
  315. roadmap/common/security/logging.py +27 -0
  316. roadmap/common/security/path_validation.py +137 -0
  317. roadmap/common/security/temp_files.py +41 -0
  318. roadmap/common/services/__init__.py +65 -0
  319. roadmap/common/services/decorators.py +183 -0
  320. roadmap/common/services/logging_utils.py +208 -0
  321. roadmap/common/services/metrics.py +161 -0
  322. roadmap/common/services/performance.py +219 -0
  323. roadmap/common/services/profiling.py +288 -0
  324. roadmap/common/services/retry.py +288 -0
  325. roadmap/common/status_style_manager.py +114 -0
  326. roadmap/common/union_find.py +88 -0
  327. roadmap/common/update_constants.py +13 -0
  328. roadmap/common/utils/__init__.py +65 -0
  329. roadmap/common/utils/cli_helpers.py +381 -0
  330. roadmap/common/utils/file_utils.py +440 -0
  331. roadmap/common/utils/path_utils.py +38 -0
  332. roadmap/common/utils/status_utils.py +130 -0
  333. roadmap/common/utils/timezone_utils.py +480 -0
  334. roadmap/common/validation/__init__.py +37 -0
  335. roadmap/common/validation/field_validator.py +104 -0
  336. roadmap/common/validation/result.py +37 -0
  337. roadmap/common/validation/roadmap_validator.py +310 -0
  338. roadmap/common/validation/schema_validator.py +36 -0
  339. roadmap/common/validation/validators.py +50 -0
  340. roadmap/core/__init__.py +1 -0
  341. roadmap/core/domain/__init__.py +30 -0
  342. roadmap/core/domain/comment.py +24 -0
  343. roadmap/core/domain/health.py +15 -0
  344. roadmap/core/domain/issue.py +274 -0
  345. roadmap/core/domain/milestone.py +173 -0
  346. roadmap/core/domain/ports/__init__.py +1 -0
  347. roadmap/core/domain/ports/baseline_repository.py +24 -0
  348. roadmap/core/domain/ports/issue_repository.py +34 -0
  349. roadmap/core/domain/ports/remote_backend_port.py +31 -0
  350. roadmap/core/domain/project.py +130 -0
  351. roadmap/core/interfaces/__init__.py +109 -0
  352. roadmap/core/interfaces/assignee_validator.py +40 -0
  353. roadmap/core/interfaces/backend_factory.py +175 -0
  354. roadmap/core/interfaces/github.py +102 -0
  355. roadmap/core/interfaces/parsers.py +140 -0
  356. roadmap/core/interfaces/persistence.py +45 -0
  357. roadmap/core/interfaces/repositories.py +174 -0
  358. roadmap/core/interfaces/state_managers.py +111 -0
  359. roadmap/core/interfaces/state_storage.py +64 -0
  360. roadmap/core/interfaces/sync_backend.py +275 -0
  361. roadmap/core/interfaces/sync_services.py +119 -0
  362. roadmap/core/interfaces/sync_validators.py +180 -0
  363. roadmap/core/models/__init__.py +31 -0
  364. roadmap/core/models/sync_models.py +162 -0
  365. roadmap/core/models.py +115 -0
  366. roadmap/core/observability/__init__.py +17 -0
  367. roadmap/core/observability/sync_metrics.py +699 -0
  368. roadmap/core/repositories.py +200 -0
  369. roadmap/core/services/__init__.py +313 -0
  370. roadmap/core/services/baseline/__init__.py +1 -0
  371. roadmap/core/services/baseline/baseline_builder_progress.py +274 -0
  372. roadmap/core/services/baseline/baseline_retriever.py +63 -0
  373. roadmap/core/services/baseline/baseline_selector.py +248 -0
  374. roadmap/core/services/baseline/baseline_state_retriever.py +284 -0
  375. roadmap/core/services/baseline/optimized_baseline_builder.py +425 -0
  376. roadmap/core/services/comment/__init__.py +1 -0
  377. roadmap/core/services/comment/comment_service.py +277 -0
  378. roadmap/core/services/git/__init__.py +1 -0
  379. roadmap/core/services/git/git_hook_auto_sync_service.py +403 -0
  380. roadmap/core/services/github/__init__.py +1 -0
  381. roadmap/core/services/github/github_change_detector.py +162 -0
  382. roadmap/core/services/github/github_config_validator.py +148 -0
  383. roadmap/core/services/github/github_conflict_detector.py +179 -0
  384. roadmap/core/services/github/github_entity_classifier.py +51 -0
  385. roadmap/core/services/github/github_integration_service.py +439 -0
  386. roadmap/core/services/github/github_issue_client.py +346 -0
  387. roadmap/core/services/health/__init__.py +1 -0
  388. roadmap/core/services/health/backup_cleanup_service.py +202 -0
  389. roadmap/core/services/health/data_integrity_validator_service.py +90 -0
  390. roadmap/core/services/health/entity_health_scanner.py +460 -0
  391. roadmap/core/services/health/file_repair_service.py +193 -0
  392. roadmap/core/services/health/health_check_service.py +166 -0
  393. roadmap/core/services/health/health_models.py +80 -0
  394. roadmap/core/services/health/infrastructure_validator_service.py +328 -0
  395. roadmap/core/services/health/issue_health_scanner.py +263 -0
  396. roadmap/core/services/helpers/__init__.py +18 -0
  397. roadmap/core/services/helpers/status_change_helpers.py +88 -0
  398. roadmap/core/services/initialization/__init__.py +19 -0
  399. roadmap/core/services/initialization/utils.py +104 -0
  400. roadmap/core/services/initialization/validator.py +78 -0
  401. roadmap/core/services/initialization/workflow.py +182 -0
  402. roadmap/core/services/initialization_service.py +111 -0
  403. roadmap/core/services/issue/__init__.py +1 -0
  404. roadmap/core/services/issue/assignee_validation_service.py +312 -0
  405. roadmap/core/services/issue/issue_creation_service.py +309 -0
  406. roadmap/core/services/issue/issue_filter_service.py +302 -0
  407. roadmap/core/services/issue/issue_matching_service.py +127 -0
  408. roadmap/core/services/issue/issue_service.py +765 -0
  409. roadmap/core/services/issue/issue_update_service.py +144 -0
  410. roadmap/core/services/issue/start_issue_service.py +174 -0
  411. roadmap/core/services/issue_helpers/__init__.py +18 -0
  412. roadmap/core/services/issue_helpers/issue_filters.py +296 -0
  413. roadmap/core/services/milestone_service.py +438 -0
  414. roadmap/core/services/project/__init__.py +1 -0
  415. roadmap/core/services/project/project_service.py +434 -0
  416. roadmap/core/services/project/project_status_service.py +125 -0
  417. roadmap/core/services/project_init/__init__.py +22 -0
  418. roadmap/core/services/project_init/context_detection.py +146 -0
  419. roadmap/core/services/project_init/creation.py +76 -0
  420. roadmap/core/services/project_init/detection.py +51 -0
  421. roadmap/core/services/project_init/template.py +228 -0
  422. roadmap/core/services/status_change_service.py +88 -0
  423. roadmap/core/services/sync/__init__.py +1 -0
  424. roadmap/core/services/sync/batch_processor.py +290 -0
  425. roadmap/core/services/sync/conflict_resolver.py +154 -0
  426. roadmap/core/services/sync/dependency_resolver.py +367 -0
  427. roadmap/core/services/sync/duplicate_detector.py +771 -0
  428. roadmap/core/services/sync/duplicate_resolver.py +315 -0
  429. roadmap/core/services/sync/error_classification.py +470 -0
  430. roadmap/core/services/sync/performance.py +263 -0
  431. roadmap/core/services/sync/sync_change_computer.py +211 -0
  432. roadmap/core/services/sync/sync_checkpoint.py +348 -0
  433. roadmap/core/services/sync/sync_conflict_detector.py +147 -0
  434. roadmap/core/services/sync/sync_conflict_resolver.py +448 -0
  435. roadmap/core/services/sync/sync_errors.py +383 -0
  436. roadmap/core/services/sync/sync_key_normalizer.py +222 -0
  437. roadmap/core/services/sync/sync_metadata_service.py +361 -0
  438. roadmap/core/services/sync/sync_plan.py +171 -0
  439. roadmap/core/services/sync/sync_plan_executor.py +447 -0
  440. roadmap/core/services/sync/sync_report.py +296 -0
  441. roadmap/core/services/sync/sync_state.py +173 -0
  442. roadmap/core/services/sync/sync_state_comparator.py +690 -0
  443. roadmap/core/services/sync/sync_state_manager.py +431 -0
  444. roadmap/core/services/sync/sync_state_normalizer.py +98 -0
  445. roadmap/core/services/sync/sync_three_way.py +78 -0
  446. roadmap/core/services/sync/three_way_merger.py +178 -0
  447. roadmap/core/services/utils/__init__.py +1 -0
  448. roadmap/core/services/utils/configuration_service.py +113 -0
  449. roadmap/core/services/utils/critical_path_calculator.py +418 -0
  450. roadmap/core/services/utils/dependency_analyzer.py +360 -0
  451. roadmap/core/services/utils/field_conflict_detector.py +126 -0
  452. roadmap/core/services/utils/remote_fetcher.py +202 -0
  453. roadmap/core/services/utils/remote_state_normalizer.py +110 -0
  454. roadmap/core/services/utils/retry_policy.py +51 -0
  455. roadmap/core/services/validator_base.py +130 -0
  456. roadmap/core/services/validators/__init__.py +28 -0
  457. roadmap/core/services/validators/_utils.py +20 -0
  458. roadmap/core/services/validators/archivable_issues_validator.py +71 -0
  459. roadmap/core/services/validators/archivable_milestones_validator.py +69 -0
  460. roadmap/core/services/validators/backup_validator.py +89 -0
  461. roadmap/core/services/validators/data_integrity_validator.py +84 -0
  462. roadmap/core/services/validators/duplicate_issues_validator.py +75 -0
  463. roadmap/core/services/validators/duplicate_milestones_validator.py +141 -0
  464. roadmap/core/services/validators/folder_structure_validator.py +165 -0
  465. roadmap/core/services/validators/health_status_utils.py +28 -0
  466. roadmap/core/services/validators/milestone_naming_validator.py +146 -0
  467. roadmap/core/services/validators/missing_headlines_validator.py +97 -0
  468. roadmap/core/services/validators/orphaned_issues_validator.py +142 -0
  469. roadmap/core/services/validators/orphaned_milestones_validator.py +85 -0
  470. roadmap/core/utils/git_remote_parser.py +83 -0
  471. roadmap/core/utils/github_urls.py +66 -0
  472. roadmap/domain/validation.py +30 -0
  473. roadmap/infrastructure/__init__.py +55 -0
  474. roadmap/infrastructure/coordination/__init__.py +8 -0
  475. roadmap/infrastructure/coordination/coordinator_params.py +82 -0
  476. roadmap/infrastructure/coordination/core.py +446 -0
  477. roadmap/infrastructure/coordination/git_coordinator.py +160 -0
  478. roadmap/infrastructure/coordination/initialization.py +348 -0
  479. roadmap/infrastructure/coordination/issue_coordinator.py +154 -0
  480. roadmap/infrastructure/coordination/issue_operations.py +456 -0
  481. roadmap/infrastructure/coordination/milestone_coordinator.py +135 -0
  482. roadmap/infrastructure/coordination/milestone_operations.py +201 -0
  483. roadmap/infrastructure/coordination/project_coordinator.py +113 -0
  484. roadmap/infrastructure/coordination/project_operations.py +144 -0
  485. roadmap/infrastructure/coordination/team_coordinator.py +107 -0
  486. roadmap/infrastructure/coordination/user_operations.py +150 -0
  487. roadmap/infrastructure/coordination/validation_coordinator.py +249 -0
  488. roadmap/infrastructure/coordination_gateway.py +152 -0
  489. roadmap/infrastructure/git/__init__.py +6 -0
  490. roadmap/infrastructure/git/git_integration_ops.py +234 -0
  491. roadmap/infrastructure/git_gateway.py +35 -0
  492. roadmap/infrastructure/github_gateway.py +52 -0
  493. roadmap/infrastructure/maintenance/__init__.py +5 -0
  494. roadmap/infrastructure/maintenance/cleanup.py +483 -0
  495. roadmap/infrastructure/observability/__init__.py +7 -0
  496. roadmap/infrastructure/observability/health.py +196 -0
  497. roadmap/infrastructure/observability/health_formatter.py +73 -0
  498. roadmap/infrastructure/observability/specialized_health_checkers.py +188 -0
  499. roadmap/infrastructure/persistence_gateway.py +164 -0
  500. roadmap/infrastructure/security/__init__.py +1 -0
  501. roadmap/infrastructure/security/credentials.py +489 -0
  502. roadmap/infrastructure/sync_gateway.py +94 -0
  503. roadmap/infrastructure/validation/__init__.py +7 -0
  504. roadmap/infrastructure/validation/file_enumeration.py +219 -0
  505. roadmap/infrastructure/validation/github_assignee_validator.py +47 -0
  506. roadmap/infrastructure/validation/github_validator.py +101 -0
  507. roadmap/infrastructure/validation/milestone_consistency_validator.py +96 -0
  508. roadmap/infrastructure/validation/vanilla_assignee_validator.py +37 -0
  509. roadmap/infrastructure/validation_gateway.py +96 -0
  510. roadmap/presentation/formatters/sync_metrics_formatter.py +355 -0
  511. roadmap/settings.py +345 -0
  512. roadmap/templates/github_workflows/ci-cd-roadmap.yml +241 -0
  513. roadmap/templates/github_workflows/issue-lifecycle.yml +236 -0
  514. roadmap/templates/github_workflows/roadmap-integration.yml +137 -0
  515. roadmap/templates/github_workflows/roadmap-starter.yml +59 -0
  516. roadmap/version.py +381 -0
  517. roadmap_cli-0.1.1.dist-info/METADATA +448 -0
  518. roadmap_cli-0.1.1.dist-info/RECORD +521 -0
  519. roadmap_cli-0.1.1.dist-info/WHEEL +4 -0
  520. roadmap_cli-0.1.1.dist-info/entry_points.txt +2 -0
  521. roadmap_cli-0.1.1.dist-info/licenses/LICENSE.md +21 -0
@@ -0,0 +1,150 @@
1
+ """User and Team Operations Module - Handles user management and validation.
2
+
3
+ This module encapsulates user and team management responsibilities extracted from RoadmapCore,
4
+ including team member retrieval, user validation, and assignee management.
5
+
6
+ Responsibilities:
7
+ - Team member retrieval and caching
8
+ - Current user management
9
+ - Assignee validation and normalization
10
+ - Issue assignment queries by user
11
+ """
12
+
13
+ from roadmap.core.domain import Issue
14
+ from roadmap.core.interfaces.assignee_validator import AssigneeValidator
15
+ from roadmap.core.services import GitHubIntegrationService, IssueService
16
+
17
+
18
+ class UserOperations:
19
+ """Manager for user and team-related operations."""
20
+
21
+ def __init__(
22
+ self,
23
+ github_service: GitHubIntegrationService,
24
+ issue_service: IssueService,
25
+ assignee_validator: AssigneeValidator | None = None,
26
+ ):
27
+ """Initialize user operations manager.
28
+
29
+ Args:
30
+ github_service: The GitHubIntegrationService instance
31
+ issue_service: The IssueService instance
32
+ assignee_validator: Validator for assignees (injected based on backend).
33
+ If None, uses vanilla validator for backwards compatibility.
34
+ """
35
+ self.github_service = github_service
36
+ self.issue_service = issue_service
37
+
38
+ # Use injected validator, or fall back to vanilla validator
39
+ if assignee_validator is None:
40
+ from roadmap.infrastructure.validation.vanilla_assignee_validator import (
41
+ VanillaAssigneeValidator,
42
+ )
43
+
44
+ assignee_validator = VanillaAssigneeValidator()
45
+
46
+ self.assignee_validator = assignee_validator
47
+
48
+ def get_team_members(self) -> list[str]:
49
+ """Get team members from GitHub repository.
50
+
51
+ Returns:
52
+ List of usernames if GitHub is configured, empty list otherwise
53
+ """
54
+ return self.github_service.get_team_members()
55
+
56
+ def get_current_user(self) -> str | None:
57
+ """Get the current user from config.
58
+
59
+ Returns:
60
+ Current user's name from config if set, None otherwise
61
+ """
62
+ return self.github_service.get_current_user()
63
+
64
+ def get_assigned_issues(self, assignee: str) -> list[Issue]:
65
+ """Get all issues assigned to a specific user.
66
+
67
+ Args:
68
+ assignee: The username to get issues for
69
+
70
+ Returns:
71
+ List of Issue objects assigned to the user
72
+ """
73
+ return self.issue_service.list_issues(assignee=assignee)
74
+
75
+ def get_my_issues(self) -> list[Issue]:
76
+ """Get all issues assigned to the current user.
77
+
78
+ Returns:
79
+ List of Issue objects assigned to current user, or empty list if not set
80
+ """
81
+ current_user = self.get_current_user()
82
+ if not current_user:
83
+ return []
84
+ return self.get_assigned_issues(current_user)
85
+
86
+ def get_all_assigned_issues(self) -> dict[str, list[Issue]]:
87
+ """Get all issues grouped by assignee.
88
+
89
+ Returns:
90
+ Dictionary mapping assignee usernames to their assigned issues
91
+ """
92
+ all_issues = self.issue_service.list_issues()
93
+ assigned_issues: dict[str, list[Issue]] = {}
94
+
95
+ for issue in all_issues:
96
+ if issue.assignee:
97
+ if issue.assignee not in assigned_issues:
98
+ assigned_issues[issue.assignee] = []
99
+ assigned_issues[issue.assignee].append(issue)
100
+
101
+ return assigned_issues
102
+
103
+ def get_cached_team_members(self) -> list[str]:
104
+ """Get team members with caching (5 minute cache).
105
+
106
+ Returns:
107
+ List of cached team member usernames
108
+ """
109
+ return self.github_service.get_cached_team_members()
110
+
111
+ def validate_assignee(self, assignee: str) -> tuple[bool, str]:
112
+ """Validate an assignee using the configured validator.
113
+
114
+ The validator is backend-specific:
115
+ - GitHub backend: validates against repository collaborators
116
+ - Git backend: accepts any assignee (no-op validator)
117
+
118
+ Args:
119
+ assignee: Username to validate
120
+
121
+ Returns:
122
+ Tuple of (is_valid, error_message)
123
+ - (True, "") if valid
124
+ - (False, error_message) if invalid
125
+ """
126
+ return self.assignee_validator.validate(assignee)
127
+
128
+ def legacy_validate_assignee(self, assignee: str) -> tuple[bool, str]:
129
+ """Legacy validation fallback for when validation strategy fails.
130
+
131
+ Args:
132
+ assignee: Username to validate
133
+
134
+ Returns:
135
+ Tuple of (is_valid, error_message)
136
+ """
137
+ return self.github_service._legacy_validate_assignee(assignee)
138
+
139
+ def get_canonical_assignee(self, assignee: str) -> str:
140
+ """Get the canonical form of an assignee name.
141
+
142
+ This method should be called after validate_assignee to get the canonical form.
143
+
144
+ Args:
145
+ assignee: Input assignee name
146
+
147
+ Returns:
148
+ Canonical assignee name (may be same as input if no mapping exists)
149
+ """
150
+ return self.assignee_validator.get_canonical_assignee(assignee)
@@ -0,0 +1,249 @@
1
+ """Validation Coordinator - Coordinates validation operations.
2
+
3
+ Extracted from RoadmapCore to reduce god object complexity.
4
+ Provides a focused API for validation concerns.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from pathlib import Path
10
+ from typing import TYPE_CHECKING
11
+
12
+ from roadmap.common.errors.error_standards import OperationType, safe_operation
13
+ from roadmap.common.logging import get_logger
14
+ from roadmap.core.services import GitHubIntegrationService
15
+
16
+ if TYPE_CHECKING:
17
+ from roadmap.infrastructure.coordination.core import RoadmapCore
18
+
19
+ logger = get_logger(__name__)
20
+
21
+
22
+ class ValidationCoordinator:
23
+ """Coordinates all validation operations."""
24
+
25
+ def __init__(
26
+ self, github_service: GitHubIntegrationService, core: RoadmapCore | None = None
27
+ ):
28
+ """Initialize coordinator with GitHub service.
29
+
30
+ Args:
31
+ github_service: GitHubIntegrationService instance
32
+ core: RoadmapCore instance for initialization checks
33
+ """
34
+ self._github_service = github_service
35
+ self._core = core
36
+
37
+ @safe_operation(OperationType.READ, "Configuration")
38
+ def get_github_config(self) -> tuple[str | None, str | None, str | None]:
39
+ """Get GitHub configuration from config file and credentials.
40
+
41
+ Returns:
42
+ Tuple of (token, owner, repo) or (None, None, None) if not configured
43
+ """
44
+ logger.info("getting_github_config")
45
+ return self._github_service.get_github_config()
46
+
47
+ @safe_operation(OperationType.READ, "RemoteLinks")
48
+ def collect_remote_link_validation_data(
49
+ self,
50
+ issues_dir: Path,
51
+ backend_name: str = "github",
52
+ ) -> dict:
53
+ """Collect YAML and database remote link data for validation.
54
+
55
+ Args:
56
+ issues_dir: Directory containing issue markdown files
57
+ backend_name: Backend name to validate
58
+
59
+ Returns:
60
+ Dict with issue_files, total_files, yaml_remote_ids, unparseable_files, db_links
61
+ """
62
+ if not self._core:
63
+ raise ValueError("ValidationCoordinator requires RoadmapCore")
64
+
65
+ issue_files = sorted(issues_dir.glob("**/*.md")) if issues_dir.exists() else []
66
+ yaml_remote_ids: dict[str, dict[str, str | int]] = {}
67
+ unparseable_files: list[tuple[str, str]] = []
68
+
69
+ if issue_files:
70
+ from roadmap.adapters.persistence.parser.issue import IssueParser
71
+
72
+ for file_path in issue_files:
73
+ try:
74
+ issue = IssueParser.parse_issue_file(file_path)
75
+ if issue.remote_ids:
76
+ yaml_remote_ids[issue.id] = issue.remote_ids
77
+ except Exception as e:
78
+ logger.warning(
79
+ "failed_to_parse_issue_file",
80
+ file_path=str(file_path),
81
+ error=str(e),
82
+ )
83
+ unparseable_files.append((str(file_path), str(e)))
84
+
85
+ db_links = self._core.db.remote_links.get_all_links_for_backend(backend_name)
86
+
87
+ return {
88
+ "issue_files": issue_files,
89
+ "total_files": len(issue_files),
90
+ "yaml_remote_ids": yaml_remote_ids,
91
+ "unparseable_files": unparseable_files,
92
+ "db_links": db_links,
93
+ }
94
+
95
+ @safe_operation(OperationType.READ, "RemoteLinks")
96
+ def build_remote_link_report(
97
+ self,
98
+ yaml_remote_ids: dict[str, dict[str, str | int]],
99
+ db_links: dict[str, str | int],
100
+ ) -> dict:
101
+ """Build a report of remote link discrepancies and duplicates.
102
+
103
+ Args:
104
+ yaml_remote_ids: Mapping of issue_id -> backend_name -> remote_id
105
+ db_links: Mapping of issue_uuid -> remote_id
106
+
107
+ Returns:
108
+ Dict with validation summary fields
109
+ """
110
+ yaml_issue_uuids = set(yaml_remote_ids.keys())
111
+ db_issue_uuids = set(db_links.keys())
112
+
113
+ missing_in_db = [
114
+ uuid for uuid in yaml_issue_uuids if uuid not in db_issue_uuids
115
+ ]
116
+ extra_in_db = [uuid for uuid in db_issue_uuids if uuid not in yaml_issue_uuids]
117
+
118
+ duplicate_remote_ids: dict[str, list[str]] = {}
119
+ remote_id_map: dict[str, list[str]] = {}
120
+ for issue_uuid, remote_id in db_links.items():
121
+ remote_id_key = str(remote_id)
122
+ remote_id_map.setdefault(remote_id_key, []).append(issue_uuid)
123
+
124
+ for remote_id, issue_uuids in remote_id_map.items():
125
+ if len(issue_uuids) > 1:
126
+ duplicate_remote_ids[remote_id] = issue_uuids
127
+
128
+ return {
129
+ "files_with_remote_ids": len(yaml_remote_ids),
130
+ "database_links": len(db_links),
131
+ "missing_in_db": missing_in_db,
132
+ "extra_in_db": extra_in_db,
133
+ "duplicate_remote_ids": duplicate_remote_ids,
134
+ }
135
+
136
+ @safe_operation(OperationType.UPDATE, "RemoteLinks")
137
+ def apply_remote_link_fixes(
138
+ self,
139
+ yaml_remote_ids: dict[str, dict[str, str | int]],
140
+ report: dict,
141
+ backend_name: str = "github",
142
+ prune_extra: bool = False,
143
+ dedupe: bool = False,
144
+ dry_run: bool = False,
145
+ ) -> dict:
146
+ """Apply fixes for missing, extra, and duplicate remote links.
147
+
148
+ Args:
149
+ yaml_remote_ids: Mapping of issue_id -> backend_name -> remote_id
150
+ report: Validation report dict
151
+ backend_name: Backend name to fix
152
+ prune_extra: Remove links missing from YAML
153
+ dedupe: Remove duplicate remote_id links
154
+ dry_run: If True, do not apply changes
155
+
156
+ Returns:
157
+ Dict with counts for fixed, removed, and deduped links
158
+ """
159
+ if not self._core:
160
+ raise ValueError("ValidationCoordinator requires RoadmapCore")
161
+
162
+ fixed_count = self._fix_missing_links(
163
+ report.get("missing_in_db", []), yaml_remote_ids, dry_run
164
+ )
165
+ removed_count = (
166
+ self._prune_extra_links(
167
+ report.get("extra_in_db", []), backend_name, dry_run
168
+ )
169
+ if prune_extra
170
+ else 0
171
+ )
172
+ deduped_count = (
173
+ self._dedupe_links(
174
+ report.get("duplicate_remote_ids", {}),
175
+ set(yaml_remote_ids.keys()),
176
+ backend_name,
177
+ dry_run,
178
+ )
179
+ if dedupe
180
+ else 0
181
+ )
182
+ return {
183
+ "fixed_count": fixed_count,
184
+ "removed_count": removed_count,
185
+ "deduped_count": deduped_count,
186
+ }
187
+
188
+ def _fix_missing_links(
189
+ self, missing_ids: list, yaml_remote_ids: dict, dry_run: bool
190
+ ) -> int:
191
+ core = self._core
192
+ if core is None:
193
+ raise ValueError("ValidationCoordinator requires RoadmapCore")
194
+
195
+ fixed = 0
196
+ for issue_uuid in missing_ids:
197
+ remote_ids = yaml_remote_ids.get(issue_uuid)
198
+ if not remote_ids:
199
+ continue
200
+ if dry_run:
201
+ fixed += 1
202
+ continue
203
+ for backend_key, remote_id in remote_ids.items():
204
+ core.db.remote_links.link_issue(issue_uuid, backend_key, remote_id)
205
+ fixed += 1
206
+ return fixed
207
+
208
+ def _prune_extra_links(
209
+ self, extra_ids: list, backend_name: str, dry_run: bool
210
+ ) -> int:
211
+ core = self._core
212
+ if core is None:
213
+ raise ValueError("ValidationCoordinator requires RoadmapCore")
214
+
215
+ removed = 0
216
+ for issue_uuid in extra_ids:
217
+ if dry_run:
218
+ removed += 1
219
+ continue
220
+ if core.db.remote_links.unlink_issue(issue_uuid, backend_name):
221
+ removed += 1
222
+ return removed
223
+
224
+ def _dedupe_links(
225
+ self,
226
+ duplicates: dict,
227
+ yaml_issue_uuids: set,
228
+ backend_name: str,
229
+ dry_run: bool,
230
+ ) -> int:
231
+ core = self._core
232
+ if core is None:
233
+ raise ValueError("ValidationCoordinator requires RoadmapCore")
234
+
235
+ deduped = 0
236
+ for issue_uuids in duplicates.values():
237
+ keep_uuid = next(
238
+ (uuid for uuid in issue_uuids if uuid in yaml_issue_uuids),
239
+ issue_uuids[0],
240
+ )
241
+ for issue_uuid in issue_uuids:
242
+ if issue_uuid == keep_uuid:
243
+ continue
244
+ if dry_run:
245
+ deduped += 1
246
+ continue
247
+ if core.db.remote_links.unlink_issue(issue_uuid, backend_name):
248
+ deduped += 1
249
+ return deduped
@@ -0,0 +1,152 @@
1
+ """Gateway to coordination infrastructure adapter access for core services.
2
+
3
+ This module mediates all core service access to infrastructure coordination
4
+ implementations, ensuring proper layer separation between Core and Infrastructure.
5
+
6
+ All imports from roadmap.adapters accessed via coordination are localized here.
7
+ Core services use this gateway instead of importing coordination modules directly
8
+ or accessing adapters through coordination.
9
+ """
10
+
11
+ from pathlib import Path
12
+ from typing import Any
13
+
14
+
15
+ class CoordinationGateway:
16
+ """Gateway for infrastructure coordination operations.
17
+
18
+ Provides a centralized interface for core services to access coordination
19
+ functionality that internally uses adapters (git, persistence, etc.)
20
+ without direct adapter imports in core.
21
+ """
22
+
23
+ @staticmethod
24
+ def get_git_integration(repo_path: Path | None = None, config: Any = None) -> Any:
25
+ """Get GitIntegration adapter for git operations.
26
+
27
+ Args:
28
+ repo_path: Path to git repository
29
+ config: Configuration object
30
+
31
+ Returns:
32
+ GitIntegration instance from adapters
33
+ """
34
+ from roadmap.adapters.git.git import GitIntegration
35
+
36
+ return GitIntegration(repo_path=repo_path, config=config)
37
+
38
+ @staticmethod
39
+ def get_state_manager(db_path: Path | str | None = None) -> Any:
40
+ """Get StateManager for database operations.
41
+
42
+ Args:
43
+ db_path: Path to database file (optional)
44
+
45
+ Returns:
46
+ StateManager instance from adapters
47
+ """
48
+ from roadmap.adapters.persistence.storage import StateManager
49
+
50
+ if db_path:
51
+ return StateManager(db_path)
52
+ return StateManager()
53
+
54
+ @staticmethod
55
+ def get_yaml_issue_repository(
56
+ db: Any | None = None, issues_dir: Path | None = None
57
+ ) -> Any:
58
+ """Get YAML repository for issue persistence.
59
+
60
+ Args:
61
+ db: Database instance
62
+ issues_dir: Path to issues directory
63
+
64
+ Returns:
65
+ YAMLIssueRepository instance from adapters
66
+ """
67
+ from roadmap.adapters.persistence.yaml_repositories import (
68
+ YAMLIssueRepository,
69
+ )
70
+
71
+ # Both parameters are required
72
+ if db is None or issues_dir is None:
73
+ raise ValueError("Both 'db' and 'issues_dir' are required parameters")
74
+ return YAMLIssueRepository(db, issues_dir)
75
+
76
+ @staticmethod
77
+ def get_git_sync_monitor(
78
+ repo_path: Path | None = None, state_manager: Any = None
79
+ ) -> Any:
80
+ """Get GitSyncMonitor for git sync tracking.
81
+
82
+ Args:
83
+ repo_path: Path to git repository
84
+ state_manager: State manager instance
85
+
86
+ Returns:
87
+ GitSyncMonitor instance from adapters
88
+ """
89
+ from roadmap.adapters.git.sync_monitor import GitSyncMonitor
90
+
91
+ return GitSyncMonitor(repo_path=repo_path, state_manager=state_manager)
92
+
93
+ @staticmethod
94
+ def get_git_hook_manager(core: Any) -> Any:
95
+ """Get GitHookManager for git hook operations.
96
+
97
+ Args:
98
+ core: RoadmapCore instance (required)
99
+
100
+ Returns:
101
+ GitHookManager instance from adapters
102
+ """
103
+ from roadmap.adapters.git.git_hooks import GitHookManager
104
+
105
+ return GitHookManager(core)
106
+
107
+ @staticmethod
108
+ def parse_issue(file_path: Any) -> Any:
109
+ """Parse issue from file.
110
+
111
+ Args:
112
+ file_path: Path to issue file
113
+
114
+ Returns:
115
+ Parsed Issue object
116
+ """
117
+ from roadmap.adapters.persistence.parser import IssueParser
118
+
119
+ return IssueParser.parse_issue_file(file_path)
120
+
121
+ @staticmethod
122
+ def parse_milestone(file_path: Any) -> Any:
123
+ """Parse milestone from file.
124
+
125
+ Args:
126
+ file_path: Path to milestone file
127
+
128
+ Returns:
129
+ Parsed Milestone object
130
+ """
131
+ from roadmap.adapters.persistence.parser import MilestoneParser
132
+
133
+ return MilestoneParser.parse_milestone_file(file_path)
134
+
135
+ @staticmethod
136
+ def get_yaml_repositories_manager() -> Any:
137
+ """Get combined repositories manager for multi-repo operations.
138
+
139
+ Returns:
140
+ Dictionary of repository classes available
141
+ """
142
+ from roadmap.adapters.persistence.yaml_repositories import (
143
+ YAMLIssueRepository,
144
+ YAMLMilestoneRepository,
145
+ YAMLProjectRepository,
146
+ )
147
+
148
+ return {
149
+ "issue": YAMLIssueRepository,
150
+ "milestone": YAMLMilestoneRepository,
151
+ "project": YAMLProjectRepository,
152
+ }
@@ -0,0 +1,6 @@
1
+ """Git integration layer - Coordinates git operations and branch linking.
2
+
3
+ This module handles:
4
+ - Git coordinator: Orchestrates git operations
5
+ - Git integration ops: Concrete git operation implementations
6
+ """