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,109 @@
1
+ """Protocol definitions for dependency injection and service abstraction."""
2
+
3
+ from typing import Protocol
4
+
5
+ from .assignee_validator import AssigneeValidator # type: ignore[assignment]
6
+ from .backend_factory import SyncBackendFactoryInterface, SyncBackendInterface
7
+ from .github import GitHubBackendInterface
8
+ from .parsers import (
9
+ FrontmatterParserInterface,
10
+ IssueParserInterface,
11
+ MilestoneParserInterface,
12
+ ProjectParserInterface,
13
+ )
14
+ from .persistence import (
15
+ FileNotFound,
16
+ GitHistoryError,
17
+ PersistenceInterface,
18
+ )
19
+ from .repositories import (
20
+ IssueRepository,
21
+ MilestoneRepository,
22
+ ProjectRepository,
23
+ )
24
+ from .state_managers import (
25
+ IssueStateManager,
26
+ MilestoneStateManager,
27
+ ProjectStateManager,
28
+ QueryStateManager,
29
+ SyncStateManager,
30
+ )
31
+ from .state_storage import SyncStateStorageInterface
32
+ from .sync_backend import (
33
+ SyncConflict,
34
+ SyncReport,
35
+ )
36
+ from .sync_services import SyncCacheServiceInterface, SyncLinkingServiceInterface
37
+
38
+ __all__ = [
39
+ "CredentialProvider",
40
+ "AssigneeValidator",
41
+ "ProjectStateManager",
42
+ "MilestoneStateManager",
43
+ "IssueStateManager",
44
+ "SyncStateManager",
45
+ "QueryStateManager",
46
+ "SyncBackendInterface",
47
+ "SyncBackendFactoryInterface",
48
+ "SyncConflict",
49
+ "SyncReport",
50
+ "PersistenceInterface",
51
+ "IssueParserInterface",
52
+ "FrontmatterParserInterface",
53
+ "MilestoneParserInterface",
54
+ "ProjectParserInterface",
55
+ "GitHubBackendInterface",
56
+ "SyncStateStorageInterface",
57
+ "SyncLinkingServiceInterface",
58
+ "SyncCacheServiceInterface",
59
+ "IssueRepository",
60
+ "MilestoneRepository",
61
+ "ProjectRepository",
62
+ "FileNotFound",
63
+ "GitHistoryError",
64
+ ]
65
+
66
+
67
+ class CredentialProvider(Protocol):
68
+ """Abstract interface for credential management.
69
+
70
+ Defines the contract that any credential provider must implement.
71
+ Allows services to work with different credential backends without
72
+ depending on concrete implementations.
73
+ """
74
+
75
+ def get_token(self) -> str | None:
76
+ """Retrieve a stored token.
77
+
78
+ Returns:
79
+ Token string if found, None otherwise
80
+ """
81
+ ...
82
+
83
+ def store_token(self, token: str, repo_info: dict[str, str] | None = None) -> bool: # noqa: F841
84
+ """Store a token securely.
85
+
86
+ Args:
87
+ token: Token to store
88
+ repo_info: Optional repository information (owner, repo)
89
+
90
+ Returns:
91
+ True if stored successfully, False otherwise
92
+ """
93
+ ...
94
+
95
+ def delete_token(self) -> bool:
96
+ """Delete a stored token.
97
+
98
+ Returns:
99
+ True if deleted successfully, False otherwise
100
+ """
101
+ ...
102
+
103
+ def is_available(self) -> bool:
104
+ """Check if the credential provider is available on this system.
105
+
106
+ Returns:
107
+ True if available, False otherwise
108
+ """
109
+ ...
@@ -0,0 +1,40 @@
1
+ """Assignee validator interface.
2
+
3
+ Defines the contract for assignee validation implementations that can be
4
+ swapped based on the configured sync backend.
5
+ """
6
+
7
+ from typing import Protocol
8
+
9
+
10
+ class AssigneeValidator(Protocol):
11
+ """Protocol for assignee validation.
12
+
13
+ Implementations validate assignees according to their backend's rules.
14
+ For example, GitHub validator checks against repository collaborators,
15
+ while a no-op validator always accepts any assignee.
16
+ """
17
+
18
+ def validate(self, assignee: str) -> tuple[bool, str]:
19
+ """Validate an assignee.
20
+
21
+ Args:
22
+ assignee: Username to validate
23
+
24
+ Returns:
25
+ Tuple of (is_valid, error_message)
26
+ - (True, "") if valid
27
+ - (False, error_message) if invalid
28
+ """
29
+ ...
30
+
31
+ def get_canonical_assignee(self, assignee: str) -> str:
32
+ """Get the canonical form of an assignee name.
33
+
34
+ Args:
35
+ assignee: Input assignee name
36
+
37
+ Returns:
38
+ Canonical assignee name (may be same as input if no mapping exists)
39
+ """
40
+ ...
@@ -0,0 +1,175 @@
1
+ """Backend factory interface for creating sync backends.
2
+
3
+ Defines contract for backend instantiation without importing adapter implementations.
4
+ Allows dynamic backend selection without layer violations.
5
+
6
+ Updated to use Result<T, SyncError> pattern for explicit error handling.
7
+ """
8
+
9
+ from abc import ABC, abstractmethod
10
+ from typing import TYPE_CHECKING, Any
11
+
12
+ if TYPE_CHECKING:
13
+ from roadmap.common.result import Result
14
+ from roadmap.core.services.sync.sync_errors import SyncError
15
+
16
+ from .sync_backend import SyncReport
17
+
18
+
19
+ class SyncBackendFactoryInterface(ABC):
20
+ """Contract for creating sync backends."""
21
+
22
+ @abstractmethod
23
+ def create_backend(
24
+ self,
25
+ backend_type: str, # noqa: F841
26
+ config: dict[str, Any], # noqa: F841
27
+ ) -> "SyncBackendInterface":
28
+ """Create a sync backend instance.
29
+
30
+ Args:
31
+ backend_type: Type of backend to create (e.g., 'github', 'gitlab')
32
+ config: Configuration dictionary for the backend
33
+
34
+ Returns:
35
+ SyncBackendInterface implementation
36
+
37
+ Raises:
38
+ ValueError: If backend_type is not supported
39
+ """
40
+ pass
41
+
42
+ @abstractmethod
43
+ def list_supported_backends(self) -> list[str]:
44
+ """List all supported backend types.
45
+
46
+ Returns:
47
+ List of backend type identifiers
48
+ """
49
+ pass
50
+
51
+ @abstractmethod
52
+ def get_default_backend(self) -> str:
53
+ """Get the default backend type.
54
+
55
+ Returns:
56
+ Backend type identifier
57
+ """
58
+ pass
59
+
60
+
61
+ class SyncBackendInterface(ABC):
62
+ """Contract for sync backend implementations.
63
+
64
+ Updated to use Result<T, SyncError> for explicit error handling.
65
+ """
66
+
67
+ @abstractmethod
68
+ def authenticate(self) -> "Result[bool, SyncError]":
69
+ """Authenticate with the backend service.
70
+
71
+ Returns:
72
+ Ok(True) if authentication successful
73
+ Err(SyncError) with error details
74
+ """
75
+ pass
76
+
77
+ @abstractmethod
78
+ def get_backend_name(self) -> str:
79
+ """Get the backend name.
80
+
81
+ Returns:
82
+ Backend identifier string
83
+ """
84
+ pass
85
+
86
+ @abstractmethod
87
+ def get_issues(self) -> "Result[dict[str, Any], SyncError]":
88
+ """Get issues from backend.
89
+
90
+ Returns:
91
+ Ok(dict) of issues on success
92
+ Err(SyncError) with error details
93
+ """
94
+ pass
95
+
96
+ @abstractmethod
97
+ def push_issues(self, issues: dict[str, Any]) -> "Result[SyncReport, SyncError]": # noqa: F841
98
+ """Push issues to backend.
99
+
100
+ Args:
101
+ issues: Dictionary of issues to push
102
+
103
+ Returns:
104
+ Ok(SyncReport) with results on success
105
+ Err(SyncError) with fatal error details
106
+ """
107
+ pass
108
+
109
+ @abstractmethod
110
+ def push_issue(self, local_issue: Any) -> "Result[bool, SyncError]": # noqa: F841
111
+ """Push a single issue to backend.
112
+
113
+ Delegates to push_issues by default but can be overridden.
114
+
115
+ Args:
116
+ local_issue: Issue object to push
117
+
118
+ Returns:
119
+ Ok(True) if successful
120
+ Err(SyncError) with error details
121
+ """
122
+ pass
123
+
124
+ @abstractmethod
125
+ def pull_issues(self, issue_ids: list[str]) -> "Result[SyncReport, SyncError]":
126
+ """Pull issues from backend.
127
+
128
+ Args:
129
+ issue_ids: List of issue IDs to pull
130
+
131
+ Returns:
132
+ Ok(SyncReport) with results on success
133
+ Err(SyncError) with fatal error details
134
+ """
135
+ pass
136
+
137
+ @abstractmethod
138
+ def pull_issue(self, issue_id: str) -> "Result[bool, SyncError]":
139
+ """Pull a single issue from backend.
140
+
141
+ Delegates to pull_issues by default but can be overridden.
142
+
143
+ Args:
144
+ issue_id: Issue ID to pull
145
+
146
+ Returns:
147
+ Ok(True) if successful
148
+ Err(SyncError) with error details
149
+ """
150
+ pass
151
+
152
+ @abstractmethod
153
+ def get_conflict_resolution_options(self, conflict: Any) -> list[str]: # noqa: F841
154
+ """Get conflict resolution options.
155
+
156
+ Args:
157
+ conflict: Conflict object
158
+
159
+ Returns:
160
+ List of resolution options
161
+ """
162
+ pass
163
+
164
+ @abstractmethod
165
+ def resolve_conflict(self, conflict: Any, resolution: str) -> bool: # noqa: F841
166
+ """Resolve a conflict.
167
+
168
+ Args:
169
+ conflict: Conflict object
170
+ resolution: Resolution option selected
171
+
172
+ Returns:
173
+ True if resolved successfully
174
+ """
175
+ pass
@@ -0,0 +1,102 @@
1
+ """GitHub backend interface for core services.
2
+
3
+ Defines contract for GitHub operations without importing adapter implementations.
4
+ Allows core services to work with GitHub without layer violations.
5
+ """
6
+
7
+ from abc import ABC, abstractmethod
8
+ from typing import Any
9
+
10
+ from roadmap.core.domain import Issue
11
+
12
+
13
+ class GitHubBackendInterface(ABC):
14
+ """Contract for GitHub backend operations."""
15
+
16
+ @abstractmethod
17
+ def authenticate(self) -> bool:
18
+ """Authenticate with GitHub.
19
+
20
+ Returns:
21
+ True if authentication successful, False otherwise
22
+ """
23
+ pass
24
+
25
+ @abstractmethod
26
+ def get_issues(self) -> dict[str, Any]:
27
+ """Get all issues from GitHub repository.
28
+
29
+ Returns:
30
+ Dictionary mapping issue IDs to issue data
31
+ """
32
+ pass
33
+
34
+ @abstractmethod
35
+ def get_issue(self, issue_id: str) -> Any:
36
+ """Get a specific issue from GitHub.
37
+
38
+ Args:
39
+ issue_id: The GitHub issue ID
40
+
41
+ Returns:
42
+ Issue data or None if not found
43
+ """
44
+ pass
45
+
46
+ @abstractmethod
47
+ def create_issue(self, issue: Issue) -> str:
48
+ """Create an issue on GitHub.
49
+
50
+ Args:
51
+ issue: Issue domain object to create
52
+
53
+ Returns:
54
+ GitHub issue ID of created issue
55
+ """
56
+ pass
57
+
58
+ @abstractmethod
59
+ def update_issue(self, issue_id: str, issue: Issue) -> bool:
60
+ """Update an issue on GitHub.
61
+
62
+ Args:
63
+ issue_id: GitHub issue ID
64
+ issue: Updated issue data
65
+
66
+ Returns:
67
+ True if successful, False otherwise
68
+ """
69
+ pass
70
+
71
+ @abstractmethod
72
+ def close_issue(self, issue_id: str) -> bool:
73
+ """Close an issue on GitHub.
74
+
75
+ Args:
76
+ issue_id: GitHub issue ID
77
+
78
+ Returns:
79
+ True if successful, False otherwise
80
+ """
81
+ pass
82
+
83
+ @abstractmethod
84
+ def list_repositories(self) -> list[str]:
85
+ """List accessible repositories.
86
+
87
+ Returns:
88
+ List of repository identifiers
89
+ """
90
+ pass
91
+
92
+ @abstractmethod
93
+ def validate_credentials(self, token: str) -> bool:
94
+ """Validate GitHub API credentials.
95
+
96
+ Args:
97
+ token: GitHub API token
98
+
99
+ Returns:
100
+ True if credentials are valid
101
+ """
102
+ pass
@@ -0,0 +1,140 @@
1
+ """Parser interfaces for domain object deserialization.
2
+
3
+ These interfaces define contracts for parsing files and content into domain objects.
4
+ Implementations should be in the infrastructure/adapters layer.
5
+ """
6
+
7
+ from abc import ABC, abstractmethod
8
+ from pathlib import Path
9
+ from typing import TYPE_CHECKING, Any
10
+
11
+ if TYPE_CHECKING:
12
+ from roadmap.core.domain import Issue, Milestone, Project
13
+
14
+
15
+ class IssueParserInterface(ABC):
16
+ """Contract for parsing issue markdown files."""
17
+
18
+ @abstractmethod
19
+ def parse_issue_file(self, file_path: Path) -> "Issue":
20
+ """Parse an issue markdown file and return an Issue domain object.
21
+
22
+ Args:
23
+ file_path: Path to issue markdown file
24
+
25
+ Returns:
26
+ Issue domain object
27
+
28
+ Raises:
29
+ FileNotFoundError: If file doesn't exist
30
+ ValueError: If file cannot be parsed
31
+ """
32
+ pass
33
+
34
+ @abstractmethod
35
+ def parse_issue_content(self, content: str) -> dict[str, Any]:
36
+ """Parse issue content string and return frontmatter as dict.
37
+
38
+ Args:
39
+ content: File content as string
40
+
41
+ Returns:
42
+ Parsed frontmatter as dictionary
43
+ """
44
+ pass
45
+
46
+
47
+ class MilestoneParserInterface(ABC):
48
+ """Contract for parsing milestone markdown files."""
49
+
50
+ @abstractmethod
51
+ def parse_milestone_file(self, file_path: Path) -> "Milestone":
52
+ """Parse a milestone markdown file and return a Milestone domain object.
53
+
54
+ Args:
55
+ file_path: Path to milestone markdown file
56
+
57
+ Returns:
58
+ Milestone domain object
59
+
60
+ Raises:
61
+ FileNotFoundError: If file doesn't exist
62
+ ValueError: If file cannot be parsed
63
+ """
64
+ pass
65
+
66
+ @abstractmethod
67
+ def parse_milestone_content(self, content: str) -> dict[str, Any]:
68
+ """Parse milestone content string and return frontmatter as dict.
69
+
70
+ Args:
71
+ content: File content as string
72
+
73
+ Returns:
74
+ Parsed frontmatter as dictionary
75
+ """
76
+ pass
77
+
78
+
79
+ class ProjectParserInterface(ABC):
80
+ """Contract for parsing project markdown files."""
81
+
82
+ @abstractmethod
83
+ def parse_project_file(self, file_path: Path) -> "Project":
84
+ """Parse a project markdown file and return a Project domain object.
85
+
86
+ Args:
87
+ file_path: Path to project markdown file
88
+
89
+ Returns:
90
+ Project domain object
91
+
92
+ Raises:
93
+ FileNotFoundError: If file doesn't exist
94
+ ValueError: If file cannot be parsed
95
+ """
96
+ pass
97
+
98
+ @abstractmethod
99
+ def parse_project_content(self, content: str) -> dict[str, Any]:
100
+ """Parse project content string and return frontmatter as dict.
101
+
102
+ Args:
103
+ content: File content as string
104
+
105
+ Returns:
106
+ Parsed frontmatter as dictionary
107
+ """
108
+ pass
109
+
110
+
111
+ class FrontmatterParserInterface(ABC):
112
+ """Contract for parsing YAML frontmatter from markdown files."""
113
+
114
+ @abstractmethod
115
+ def parse_file(self, file_path: Path) -> tuple[dict[str, Any], str]:
116
+ """Parse a markdown file and extract frontmatter and content.
117
+
118
+ Args:
119
+ file_path: Path to markdown file
120
+
121
+ Returns:
122
+ Tuple of (frontmatter dict, content string)
123
+
124
+ Raises:
125
+ FileNotFoundError: If file doesn't exist
126
+ ValueError: If file cannot be parsed
127
+ """
128
+ pass
129
+
130
+ @abstractmethod
131
+ def parse_content(self, content: str) -> tuple[dict[str, Any], str]:
132
+ """Parse markdown content and extract frontmatter and text.
133
+
134
+ Args:
135
+ content: File content as string
136
+
137
+ Returns:
138
+ Tuple of (frontmatter dict, content string)
139
+ """
140
+ pass
@@ -0,0 +1,45 @@
1
+ """Persistence interface for core services.
2
+
3
+ Defines contract for file persistence and git history operations.
4
+ """
5
+
6
+ from abc import ABC, abstractmethod
7
+ from datetime import datetime
8
+
9
+
10
+ class FileNotFound(Exception):
11
+ """Raised when a file is not found in history."""
12
+
13
+ pass
14
+
15
+
16
+ class GitHistoryError(Exception):
17
+ """Raised when git history operations fail."""
18
+
19
+ pass
20
+
21
+
22
+ class PersistenceInterface(ABC):
23
+ """Interface for file persistence operations."""
24
+
25
+ @abstractmethod
26
+ def get_file_at_timestamp(self, file_path: str, timestamp: datetime) -> str:
27
+ """Get file content at a specific git timestamp.
28
+
29
+ Args:
30
+ file_path: Path to file relative to repo root
31
+ timestamp: Datetime to retrieve file at
32
+
33
+ Returns:
34
+ File content as string
35
+
36
+ Raises:
37
+ FileNotFound: If file doesn't exist at timestamp
38
+ GitHistoryError: If git operation fails
39
+ """
40
+ pass
41
+
42
+ @abstractmethod
43
+ def list_files_in_directory(self, directory: str) -> list[str]:
44
+ """List all files in a directory at HEAD."""
45
+ pass