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,319 @@
1
+ """Unified DateTime Parser for Roadmap CLI.
2
+
3
+ This module provides a single source of truth for all datetime parsing operations
4
+ across the roadmap CLI, eliminating duplication and ensuring consistent behavior.
5
+ """
6
+
7
+ import re
8
+ from datetime import UTC, datetime
9
+ from typing import Any
10
+
11
+ from structlog import get_logger
12
+
13
+ # Import timezone utilities
14
+ from .utils.timezone_utils import (
15
+ ensure_timezone_aware,
16
+ get_timezone_manager,
17
+ )
18
+
19
+ logger = get_logger()
20
+
21
+
22
+ class UnifiedDateTimeParser:
23
+ """Single source of truth for all datetime parsing in roadmap CLI."""
24
+
25
+ # Common datetime format patterns for parsing
26
+ DATETIME_FORMATS = [
27
+ "%Y-%m-%d %H:%M:%S",
28
+ "%Y-%m-%d %H:%M",
29
+ "%Y-%m-%d",
30
+ "%m/%d/%Y %H:%M:%S",
31
+ "%m/%d/%Y %H:%M",
32
+ "%m/%d/%Y",
33
+ "%d/%m/%Y %H:%M:%S",
34
+ "%d/%m/%Y %H:%M",
35
+ "%d/%m/%Y",
36
+ "%Y/%m/%d %H:%M:%S",
37
+ "%Y/%m/%d %H:%M",
38
+ "%Y/%m/%d",
39
+ ]
40
+
41
+ @classmethod
42
+ def _handle_datetime_object(
43
+ cls, value: datetime, assumed_timezone: str | None
44
+ ) -> datetime:
45
+ """Handle datetime object input (ensure timezone awareness).
46
+
47
+ Args:
48
+ value: Datetime object
49
+ assumed_timezone: Timezone to assume for naive datetimes
50
+
51
+ Returns:
52
+ Timezone-aware datetime in UTC
53
+ """
54
+ return ensure_timezone_aware(value, assumed_timezone or "UTC")
55
+
56
+ @classmethod
57
+ def _normalize_string_value(cls, value: str) -> str | None:
58
+ """Normalize string input for parsing.
59
+
60
+ Args:
61
+ value: String value to normalize
62
+
63
+ Returns:
64
+ Normalized string or None if empty
65
+ """
66
+ if not isinstance(value, str):
67
+ value = str(value)
68
+ value = value.strip()
69
+ return value if value else None
70
+
71
+ @classmethod
72
+ def _route_to_specialized_parser(
73
+ cls, value: str, source_type: str, assumed_timezone: str | None
74
+ ) -> datetime | None:
75
+ """Route value to appropriate specialized parser based on type and format.
76
+
77
+ Args:
78
+ value: String value to parse
79
+ source_type: Hint for parsing behavior
80
+ assumed_timezone: Timezone to assume for naive datetimes
81
+
82
+ Returns:
83
+ Parsed datetime or None
84
+ """
85
+ if source_type == "github" or cls._is_github_format(value):
86
+ return cls.parse_github_timestamp(value)
87
+ elif source_type == "iso" or cls._is_iso_format(value):
88
+ return cls.parse_iso_datetime(value, assumed_timezone)
89
+ elif source_type == "file":
90
+ return cls.parse_file_datetime(value, assumed_timezone)
91
+ else:
92
+ return cls.parse_user_datetime(value, assumed_timezone)
93
+
94
+ @classmethod
95
+ def parse_any_datetime(
96
+ cls, value: Any, source_type: str = "user", assumed_timezone: str | None = None
97
+ ) -> datetime | None:
98
+ """Universal datetime parser for all roadmap CLI needs.
99
+
100
+ This is the primary entry point for datetime parsing. It handles:
101
+ - String datetime values in various formats
102
+ - Existing datetime objects (ensures timezone awareness)
103
+ - None values (returns None)
104
+ - GitHub API timestamps (Z suffix)
105
+ - File frontmatter datetimes
106
+ - User input in multiple formats
107
+
108
+ Args:
109
+ value: Any datetime-like value (string, datetime, None)
110
+ source_type: Hint for parsing behavior ("user", "github", "file", "iso")
111
+ assumed_timezone: Timezone to assume for naive datetimes
112
+
113
+ Returns:
114
+ Timezone-aware datetime in UTC, or None if value is None/invalid
115
+ """
116
+ if value is None:
117
+ return None
118
+
119
+ if isinstance(value, datetime):
120
+ return cls._handle_datetime_object(value, assumed_timezone)
121
+
122
+ # Normalize string value
123
+ normalized = cls._normalize_string_value(value)
124
+ if not normalized:
125
+ return None
126
+
127
+ # Route to specialized parser
128
+ return cls._route_to_specialized_parser(
129
+ normalized, source_type, assumed_timezone
130
+ )
131
+
132
+ @classmethod
133
+ def parse_github_timestamp(cls, github_timestamp: str) -> datetime:
134
+ """Specialized GitHub API timestamp parsing.
135
+
136
+ Handles GitHub's ISO format timestamps which typically end with 'Z' (UTC).
137
+ Also handles malformed test timestamps with mixed timezone formats.
138
+
139
+ Args:
140
+ github_timestamp: GitHub API timestamp string
141
+
142
+ Returns:
143
+ Timezone-aware datetime in UTC
144
+
145
+ Raises:
146
+ ValueError: If timestamp cannot be parsed
147
+ """
148
+ if not github_timestamp:
149
+ return datetime.min.replace(tzinfo=UTC)
150
+
151
+ # Handle malformed timestamps from tests (e.g., "2025-01-01T00:00:00+00:00Z")
152
+ if github_timestamp.endswith("Z") and "+00:00" in github_timestamp:
153
+ # Remove the trailing Z if there's already timezone info
154
+ github_timestamp = github_timestamp[:-1]
155
+ elif github_timestamp.endswith("Z"):
156
+ # Standard GitHub API format: replace Z with +00:00
157
+ github_timestamp = github_timestamp.replace("Z", "+00:00")
158
+
159
+ try:
160
+ # Parse the timestamp and ensure it's in UTC
161
+ dt = datetime.fromisoformat(github_timestamp)
162
+ return ensure_timezone_aware(dt, "UTC")
163
+ except ValueError as e:
164
+ raise ValueError(
165
+ f"Invalid GitHub timestamp format: {github_timestamp}"
166
+ ) from e
167
+
168
+ @classmethod
169
+ def parse_file_datetime(
170
+ cls, value: str, assumed_timezone: str | None = None
171
+ ) -> datetime | None:
172
+ """Parse datetime from markdown frontmatter or file content.
173
+
174
+ Args:
175
+ value: Datetime string from file
176
+ assumed_timezone: Timezone to assume for naive datetimes
177
+
178
+ Returns:
179
+ Timezone-aware datetime in UTC, or None if invalid
180
+ """
181
+ if not value or not isinstance(value, str):
182
+ return None
183
+
184
+ value = value.strip()
185
+ if not value:
186
+ return None
187
+
188
+ # Try ISO format first (most common in files)
189
+ if cls._is_iso_format(value):
190
+ return cls.parse_iso_datetime(value, assumed_timezone)
191
+
192
+ # Try other common formats
193
+ return cls._parse_with_formats(value, cls.DATETIME_FORMATS, assumed_timezone)
194
+
195
+ @classmethod
196
+ def parse_user_datetime(
197
+ cls, value: str, assumed_timezone: str | None = None
198
+ ) -> datetime | None:
199
+ """Parse datetime from user input with flexible format support.
200
+
201
+ Args:
202
+ value: User input datetime string
203
+ assumed_timezone: Timezone to assume for naive datetimes
204
+
205
+ Returns:
206
+ Timezone-aware datetime in UTC, or None if invalid
207
+ """
208
+ if not value or not isinstance(value, str):
209
+ return None
210
+
211
+ # Use the TimezoneManager for user input parsing
212
+ try:
213
+ timezone_manager = get_timezone_manager()
214
+ return timezone_manager.parse_user_input(value, assumed_timezone)
215
+ except Exception as e:
216
+ logger.debug("timezone_manager_parsing_failed", value=value, error=str(e))
217
+ # Fallback to manual parsing
218
+ return cls._parse_with_formats(
219
+ value, cls.DATETIME_FORMATS, assumed_timezone
220
+ )
221
+
222
+ @classmethod
223
+ def parse_iso_datetime(
224
+ cls, value: str, assumed_timezone: str | None = None
225
+ ) -> datetime | None:
226
+ """Parse ISO format datetime string.
227
+
228
+ Args:
229
+ value: ISO format datetime string
230
+ assumed_timezone: Timezone to assume for naive datetimes
231
+
232
+ Returns:
233
+ Timezone-aware datetime in UTC, or None if invalid
234
+ """
235
+ if not value:
236
+ return None
237
+
238
+ try:
239
+ # Handle Z suffix (UTC indicator)
240
+ if value.endswith("Z"):
241
+ value = value.replace("Z", "+00:00")
242
+
243
+ # Parse with fromisoformat
244
+ dt = datetime.fromisoformat(value)
245
+ return ensure_timezone_aware(dt, assumed_timezone or "UTC")
246
+
247
+ except ValueError as e:
248
+ logger.debug("iso_datetime_parse_failed", value=value, error=str(e))
249
+ return None
250
+
251
+ @classmethod
252
+ def _is_github_format(cls, value: str) -> bool:
253
+ """Check if string looks like a GitHub API timestamp."""
254
+ return value.endswith("Z") or (
255
+ "T" in value and (":" in value) and ("+" in value or "Z" in value)
256
+ )
257
+
258
+ @classmethod
259
+ def _is_iso_format(cls, value: str) -> bool:
260
+ """Check if string looks like ISO format."""
261
+ iso_pattern = r"^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}"
262
+ return bool(re.match(iso_pattern, value))
263
+
264
+ @classmethod
265
+ def _parse_with_formats(
266
+ cls, value: str, formats: list, assumed_timezone: str | None = None
267
+ ) -> datetime | None:
268
+ """Try parsing with multiple datetime formats.
269
+
270
+ Args:
271
+ value: Datetime string to parse
272
+ formats: List of strptime format strings to try
273
+ assumed_timezone: Timezone to assume for naive datetimes
274
+
275
+ Returns:
276
+ Timezone-aware datetime in UTC, or None if no format works
277
+ """
278
+ for fmt in formats:
279
+ try:
280
+ dt = datetime.strptime(value, fmt)
281
+ return ensure_timezone_aware(dt, assumed_timezone or "UTC")
282
+ except ValueError as e:
283
+ logger.debug(
284
+ "format_datetime_parse_failed",
285
+ value=value,
286
+ format=fmt,
287
+ error=str(e),
288
+ )
289
+ continue
290
+ return None
291
+
292
+
293
+ # Convenience functions for backward compatibility and ease of use
294
+ def parse_datetime(
295
+ value: Any, source_type: str = "user", assumed_timezone: str | None = None
296
+ ) -> datetime | None:
297
+ """Parse datetime from various input formats."""
298
+ return UnifiedDateTimeParser.parse_any_datetime(
299
+ value, source_type, assumed_timezone
300
+ )
301
+
302
+
303
+ def parse_github_datetime(github_timestamp: str) -> datetime:
304
+ """Parse GitHub timestamp format."""
305
+ return UnifiedDateTimeParser.parse_github_timestamp(github_timestamp)
306
+
307
+
308
+ def parse_file_datetime(
309
+ value: str, assumed_timezone: str | None = None
310
+ ) -> datetime | None:
311
+ """Parse datetime from file path format."""
312
+ return UnifiedDateTimeParser.parse_file_datetime(value, assumed_timezone)
313
+
314
+
315
+ def parse_user_datetime(
316
+ value: str, assumed_timezone: str | None = None
317
+ ) -> datetime | None:
318
+ """Parse user-input datetime string."""
319
+ return UnifiedDateTimeParser.parse_user_datetime(value, assumed_timezone)
@@ -0,0 +1,84 @@
1
+ """Error formatting utilities for CLI output.
2
+
3
+ Provides consistent error message formatting for both plain and rich output modes.
4
+ """
5
+
6
+ from roadmap.common.console import is_plain_mode
7
+ from roadmap.common.errors.exceptions import RoadmapException
8
+
9
+
10
+ def format_error_message(exc: RoadmapException | Exception) -> str:
11
+ """Format an exception for user-friendly CLI output.
12
+
13
+ For RoadmapException: Uses user_message with appropriate styling
14
+ For other exceptions: Uses generic fallback message
15
+
16
+ Args:
17
+ exc: Exception to format
18
+
19
+ Returns:
20
+ Formatted error message suitable for stderr output
21
+ """
22
+ plain = is_plain_mode()
23
+
24
+ if isinstance(exc, RoadmapException):
25
+ message = exc.user_message
26
+ else:
27
+ message = str(exc)
28
+
29
+ # Add prefix based on mode
30
+ if plain:
31
+ return f"[ERROR] {message}"
32
+ else:
33
+ return f"❌ {message}"
34
+
35
+
36
+ def format_warning_message(message: str) -> str:
37
+ """Format a warning message for CLI output.
38
+
39
+ Args:
40
+ message: Warning message text
41
+
42
+ Returns:
43
+ Formatted warning message
44
+ """
45
+ plain = is_plain_mode()
46
+
47
+ if plain:
48
+ return f"[WARN] {message}"
49
+ else:
50
+ return f"⚠️ {message}"
51
+
52
+
53
+ def format_info_message(message: str) -> str:
54
+ """Format an info message for CLI output.
55
+
56
+ Args:
57
+ message: Info message text
58
+
59
+ Returns:
60
+ Formatted info message
61
+ """
62
+ plain = is_plain_mode()
63
+
64
+ if plain:
65
+ return f"[INFO] {message}"
66
+ else:
67
+ return f"ℹ️ {message}"
68
+
69
+
70
+ def format_success_message(message: str) -> str:
71
+ """Format a success message for CLI output.
72
+
73
+ Args:
74
+ message: Success message text
75
+
76
+ Returns:
77
+ Formatted success message
78
+ """
79
+ plain = is_plain_mode()
80
+
81
+ if plain:
82
+ return f"[OK] {message}"
83
+ else:
84
+ return f"✅ {message}"
@@ -0,0 +1,143 @@
1
+ """Error handling and exception definitions for Roadmap.
2
+
3
+ This package provides organized error classes, categorized by concern:
4
+ - exceptions: High-level exceptions with domain and user messages (NEW)
5
+ - error_base: Core exception classes and enums
6
+ - error_file: File and I/O related errors
7
+ - error_validation: Data validation errors
8
+ - error_network: Network and GitHub API errors
9
+ - error_git: Git operation errors and configuration errors
10
+ - error_security: Security and parsing errors
11
+ - error_handler: Error handling utilities
12
+ - error_standards: Standardized error handling decorators and context managers (NEW)
13
+ """
14
+
15
+ # Legacy error hierarchy (backwards compatibility)
16
+ from roadmap.common.errors.error_base import (
17
+ ErrorCategory,
18
+ ErrorSeverity,
19
+ RoadmapError,
20
+ )
21
+ from roadmap.common.errors.error_file import (
22
+ DirectoryCreationError,
23
+ ExportError,
24
+ FileLockError,
25
+ FileOperationError,
26
+ FileReadError,
27
+ FileWriteError,
28
+ ImportError,
29
+ PersistenceError,
30
+ )
31
+ from roadmap.common.errors.error_git import ConfigurationError, GitOperationError
32
+ from roadmap.common.errors.error_handler import ErrorHandler, handle_errors
33
+ from roadmap.common.errors.error_network import (
34
+ AuthenticationError,
35
+ GitHubAPIError,
36
+ NetworkError,
37
+ )
38
+ from roadmap.common.errors.error_security import (
39
+ ParseError,
40
+ PathValidationError,
41
+ SecurityError,
42
+ )
43
+
44
+ # Standardized error handling decorators and utilities
45
+ from roadmap.common.errors.error_standards import (
46
+ ErrorContext,
47
+ OperationType,
48
+ RecoveryAction,
49
+ log_operation,
50
+ safe_operation,
51
+ with_error_handling,
52
+ )
53
+ from roadmap.common.errors.error_validation import (
54
+ IssueNotFoundError,
55
+ MilestoneNotFoundError,
56
+ StateError,
57
+ ValidationError,
58
+ )
59
+
60
+ # New exception hierarchy (recommended for future use)
61
+ from roadmap.common.errors.exceptions import (
62
+ AlreadyInitializedError,
63
+ CreateError,
64
+ DatabaseError,
65
+ DeleteError,
66
+ EntityNotFoundError,
67
+ GitConfigError,
68
+ GitError,
69
+ GitHubError,
70
+ InvalidPriorityError,
71
+ InvalidStatusError,
72
+ NoGitRepositoryError,
73
+ NotInitializedError,
74
+ OperationError,
75
+ ProjectNotFoundError,
76
+ RoadmapException,
77
+ UpdateError,
78
+ )
79
+ from roadmap.common.errors.exceptions import (
80
+ IssueNotFoundError as NewIssueNotFoundError,
81
+ )
82
+ from roadmap.common.errors.exceptions import (
83
+ MilestoneNotFoundError as NewMilestoneNotFoundError,
84
+ )
85
+ from roadmap.common.errors.exceptions import (
86
+ ValidationError as NewValidationError,
87
+ )
88
+
89
+ __all__ = [
90
+ # Legacy (backwards compatibility)
91
+ "ErrorSeverity",
92
+ "ErrorCategory",
93
+ "RoadmapError",
94
+ "FileOperationError",
95
+ "DirectoryCreationError",
96
+ "FileReadError",
97
+ "FileWriteError",
98
+ "ExportError",
99
+ "ImportError",
100
+ "PersistenceError",
101
+ "FileLockError",
102
+ "ValidationError",
103
+ "NetworkError",
104
+ "AuthenticationError",
105
+ "GitHubAPIError",
106
+ "GitOperationError",
107
+ "SecurityError",
108
+ "PathValidationError",
109
+ "ParseError",
110
+ "ErrorHandler",
111
+ "handle_errors",
112
+ "StateError",
113
+ "IssueNotFoundError",
114
+ "MilestoneNotFoundError",
115
+ "ConfigurationError",
116
+ # New exceptions (recommended)
117
+ "RoadmapException",
118
+ "NotInitializedError",
119
+ "AlreadyInitializedError",
120
+ "EntityNotFoundError",
121
+ "NewIssueNotFoundError",
122
+ "NewMilestoneNotFoundError",
123
+ "ProjectNotFoundError",
124
+ "NewValidationError",
125
+ "InvalidStatusError",
126
+ "InvalidPriorityError",
127
+ "OperationError",
128
+ "CreateError",
129
+ "UpdateError",
130
+ "DeleteError",
131
+ "DatabaseError",
132
+ "GitError",
133
+ "GitHubError",
134
+ "GitConfigError",
135
+ "NoGitRepositoryError",
136
+ # Standardized error handling decorators and utilities
137
+ "safe_operation",
138
+ "log_operation",
139
+ "with_error_handling",
140
+ "ErrorContext",
141
+ "OperationType",
142
+ "RecoveryAction",
143
+ ]
@@ -0,0 +1,73 @@
1
+ """Base error classes and enums for Roadmap."""
2
+
3
+ from enum import Enum
4
+ from typing import Any
5
+
6
+
7
+ class ErrorSeverity(Enum):
8
+ """Error severity levels for consistent classification."""
9
+
10
+ CRITICAL = "critical"
11
+ HIGH = "high"
12
+ MEDIUM = "medium"
13
+ LOW = "low"
14
+ WARNING = "warning"
15
+ INFO = "info"
16
+
17
+
18
+ class ErrorCategory(Enum):
19
+ """Error categories for better organization and handling."""
20
+
21
+ FILE_OPERATION = "file_operation"
22
+ VALIDATION = "validation"
23
+ NETWORK = "network"
24
+ GIT_OPERATION = "git_operation"
25
+ GITHUB_API = "github_api"
26
+ PARSING = "parsing"
27
+ CONFIGURATION = "configuration"
28
+ PERMISSION = "permission"
29
+ DEPENDENCY = "dependency"
30
+ USER_INPUT = "user_input"
31
+
32
+
33
+ class RoadmapError(Exception):
34
+ """Base exception for all roadmap-specific errors."""
35
+
36
+ def __init__(
37
+ self,
38
+ message: str,
39
+ severity: ErrorSeverity = ErrorSeverity.MEDIUM,
40
+ category: ErrorCategory = ErrorCategory.VALIDATION,
41
+ context: dict[str, Any] | None = None,
42
+ cause: Exception | None = None,
43
+ ):
44
+ """Initialize RoadmapError.
45
+
46
+ Args:
47
+ message: Error message.
48
+ severity: Error severity level.
49
+ category: Error category.
50
+ context: Additional context dictionary.
51
+ cause: Underlying exception that caused this error.
52
+ """
53
+ super().__init__(message)
54
+ self.message = message
55
+ self.severity = severity
56
+ self.category = category
57
+ self.context = context or {}
58
+ self.cause = cause
59
+
60
+ def __str__(self) -> str:
61
+ """Return string representation of error."""
62
+ return self.message
63
+
64
+ def get_context_info(self) -> str:
65
+ """Get formatted context information."""
66
+ if not self.context:
67
+ return ""
68
+
69
+ context_parts = []
70
+ for key, value in self.context.items():
71
+ context_parts.append(f"{key}: {value}")
72
+
73
+ return f" ({', '.join(context_parts)})"
@@ -0,0 +1,82 @@
1
+ """File and I/O related error classes."""
2
+
3
+ from pathlib import Path
4
+
5
+ from roadmap.common.errors.error_base import ErrorCategory, ErrorSeverity, RoadmapError
6
+
7
+
8
+ class FileOperationError(RoadmapError):
9
+ """Errors related to file operations."""
10
+
11
+ def __init__(
12
+ self,
13
+ message: str,
14
+ file_path: Path | None = None,
15
+ operation: str | None = None,
16
+ **kwargs,
17
+ ):
18
+ """Initialize FileOperationError.
19
+
20
+ Args:
21
+ message: Error message.
22
+ file_path: Path to the file involved in the error.
23
+ operation: Name of the file operation that failed.
24
+ **kwargs: Additional arguments passed to parent class.
25
+ """
26
+ context = kwargs.get("context", {})
27
+ if file_path:
28
+ context["file_path"] = str(file_path)
29
+ if operation:
30
+ context["operation"] = operation
31
+
32
+ super().__init__(
33
+ message,
34
+ severity=kwargs.get("severity", ErrorSeverity.HIGH),
35
+ category=ErrorCategory.FILE_OPERATION,
36
+ context=context,
37
+ cause=kwargs.get("cause"),
38
+ )
39
+ self.file_path = file_path
40
+ self.operation = operation
41
+
42
+
43
+ class PersistenceError(FileOperationError):
44
+ """Raised when database or file persistence operations fail."""
45
+
46
+ pass
47
+
48
+
49
+ class FileLockError(FileOperationError):
50
+ """Raised when file locking operations fail."""
51
+
52
+ pass
53
+
54
+
55
+ class DirectoryCreationError(FileOperationError):
56
+ """Raised when directory creation fails."""
57
+
58
+ pass
59
+
60
+
61
+ class FileReadError(FileOperationError):
62
+ """Raised when file reading fails."""
63
+
64
+ pass
65
+
66
+
67
+ class FileWriteError(FileOperationError):
68
+ """Raised when file writing fails."""
69
+
70
+ pass
71
+
72
+
73
+ class ExportError(FileOperationError):
74
+ """Raised when data export fails."""
75
+
76
+ pass
77
+
78
+
79
+ class ImportError(FileOperationError):
80
+ """Raised when data import fails."""
81
+
82
+ pass