specfact-cli 0.26.14__tar.gz → 0.26.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/PKG-INFO +1 -1
  2. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/pyproject.toml +8 -4
  3. specfact_cli-0.26.16/resources/prompts/specfact.backlog-daily.md +109 -0
  4. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.backlog-refine.md +26 -0
  5. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/__init__.py +1 -1
  6. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/__init__.py +1 -1
  7. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/ado.py +5 -0
  8. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/github.py +30 -0
  9. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/adapters/base.py +31 -0
  10. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/cli.py +1 -0
  11. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/backlog_commands.py +1012 -40
  12. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/common/logger_setup.py +11 -3
  13. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/runtime.py +11 -3
  14. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/.gitignore +0 -0
  15. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/LICENSE.md +0 -0
  16. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/README.md +0 -0
  17. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/mappings/node-async.yaml +0 -0
  18. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/mappings/python-async.yaml +0 -0
  19. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/mappings/speckit-default.yaml +0 -0
  20. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/shared/cli-enforcement.md +0 -0
  21. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.01-import.md +0 -0
  22. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.02-plan.md +0 -0
  23. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.03-review.md +0 -0
  24. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.04-sdd.md +0 -0
  25. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.05-enforce.md +0 -0
  26. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.06-sync.md +0 -0
  27. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.07-contracts.md +0 -0
  28. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.compare.md +0 -0
  29. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.sync-backlog.md +0 -0
  30. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.validate.md +0 -0
  31. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/schemas/deviation.schema.json +0 -0
  32. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/schemas/plan.schema.json +0 -0
  33. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/schemas/protocol.schema.json +0 -0
  34. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/defaults/defect_v1.yaml +0 -0
  35. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/defaults/enabler_v1.yaml +0 -0
  36. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/defaults/spike_v1.yaml +0 -0
  37. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/defaults/user_story_v1.yaml +0 -0
  38. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/field_mappings/ado_agile.yaml +0 -0
  39. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/field_mappings/ado_default.yaml +0 -0
  40. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/field_mappings/ado_kanban.yaml +0 -0
  41. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/field_mappings/ado_safe.yaml +0 -0
  42. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/field_mappings/ado_scrum.yaml +0 -0
  43. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/frameworks/safe/safe_feature_v1.yaml +0 -0
  44. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/frameworks/scrum/user_story_v1.yaml +0 -0
  45. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/personas/developer/developer_task_v1.yaml +0 -0
  46. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/personas/product-owner/user_story_v1.yaml +0 -0
  47. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/providers/ado/work_item_v1.yaml +0 -0
  48. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/github-action.yml.j2 +0 -0
  49. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/persona/architect.md.j2 +0 -0
  50. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/persona/developer.md.j2 +0 -0
  51. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/persona/product-owner.md.j2 +0 -0
  52. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/plan.bundle.yaml.j2 +0 -0
  53. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/pr-template.md.j2 +0 -0
  54. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/protocol.yaml.j2 +0 -0
  55. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/telemetry.yaml.example +0 -0
  56. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/__main__.py +0 -0
  57. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/__init__.py +0 -0
  58. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/backlog_base.py +0 -0
  59. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/base.py +0 -0
  60. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/openspec.py +0 -0
  61. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/openspec_parser.py +0 -0
  62. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/registry.py +0 -0
  63. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/speckit.py +0 -0
  64. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/__init__.py +0 -0
  65. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/analyze_agent.py +0 -0
  66. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/base.py +0 -0
  67. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/plan_agent.py +0 -0
  68. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/registry.py +0 -0
  69. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/sync_agent.py +0 -0
  70. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/__init__.py +0 -0
  71. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
  72. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
  73. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
  74. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
  75. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
  76. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
  77. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
  78. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
  79. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
  80. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/__init__.py +0 -0
  81. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
  82. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/adapters/local_yaml_adapter.py +0 -0
  83. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/ai_refiner.py +0 -0
  84. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/converter.py +0 -0
  85. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/filters.py +0 -0
  86. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/format_detector.py +0 -0
  87. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/formats/__init__.py +0 -0
  88. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/formats/base.py +0 -0
  89. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/formats/markdown_format.py +0 -0
  90. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/formats/structured_format.py +0 -0
  91. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
  92. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
  93. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/mappers/base.py +0 -0
  94. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
  95. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
  96. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/template_detector.py +0 -0
  97. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/__init__.py +0 -0
  98. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/analyze.py +0 -0
  99. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/auth.py +0 -0
  100. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/contract_cmd.py +0 -0
  101. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/drift.py +0 -0
  102. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/enforce.py +0 -0
  103. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/generate.py +0 -0
  104. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/import_cmd.py +0 -0
  105. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/init.py +0 -0
  106. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/migrate.py +0 -0
  107. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/plan.py +0 -0
  108. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/project_cmd.py +0 -0
  109. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/repro.py +0 -0
  110. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/sdd.py +0 -0
  111. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/spec.py +0 -0
  112. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/sync.py +0 -0
  113. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/update.py +0 -0
  114. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/validate.py +0 -0
  115. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/common/__init__.py +0 -0
  116. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/common/logging_utils.py +0 -0
  117. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/common/text_utils.py +0 -0
  118. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/common/utils.py +0 -0
  119. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/comparators/__init__.py +0 -0
  120. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/comparators/plan_comparator.py +0 -0
  121. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/contracts/__init__.py +0 -0
  122. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/contracts/crosshair_props.py +0 -0
  123. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
  124. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
  125. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/__init__.py +0 -0
  126. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/contract_generator.py +0 -0
  127. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/openapi_extractor.py +0 -0
  128. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/persona_exporter.py +0 -0
  129. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/plan_generator.py +0 -0
  130. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/protocol_generator.py +0 -0
  131. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/report_generator.py +0 -0
  132. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/task_generator.py +0 -0
  133. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/test_to_openapi.py +0 -0
  134. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/workflow_generator.py +0 -0
  135. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/importers/__init__.py +0 -0
  136. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/importers/speckit_converter.py +0 -0
  137. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/importers/speckit_scanner.py +0 -0
  138. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/integrations/__init__.py +0 -0
  139. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/integrations/specmatic.py +0 -0
  140. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/merge/__init__.py +0 -0
  141. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/merge/resolver.py +0 -0
  142. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/migrations/__init__.py +0 -0
  143. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/migrations/plan_migrator.py +0 -0
  144. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/__init__.py +0 -0
  145. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/backlog_item.py +0 -0
  146. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/bridge.py +0 -0
  147. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/capabilities.py +0 -0
  148. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/change.py +0 -0
  149. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/contract.py +0 -0
  150. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/deviation.py +0 -0
  151. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/dor_config.py +0 -0
  152. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/enforcement.py +0 -0
  153. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/persona_template.py +0 -0
  154. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/plan.py +0 -0
  155. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/project.py +0 -0
  156. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/protocol.py +0 -0
  157. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/quality.py +0 -0
  158. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/sdd.py +0 -0
  159. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/source_tracking.py +0 -0
  160. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/task.py +0 -0
  161. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/modes/__init__.py +0 -0
  162. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/modes/detector.py +0 -0
  163. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/modes/router.py +0 -0
  164. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/parsers/__init__.py +0 -0
  165. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/parsers/persona_importer.py +0 -0
  166. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/resources/semgrep/async.yml +0 -0
  167. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
  168. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
  169. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/__init__.py +0 -0
  170. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/bridge_probe.py +0 -0
  171. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/bridge_sync.py +0 -0
  172. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/bridge_watch.py +0 -0
  173. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/change_detector.py +0 -0
  174. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/code_to_spec.py +0 -0
  175. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/drift_detector.py +0 -0
  176. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/repository_sync.py +0 -0
  177. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/spec_to_code.py +0 -0
  178. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/spec_to_tests.py +0 -0
  179. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/watcher.py +0 -0
  180. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
  181. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/telemetry.py +0 -0
  182. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/__init__.py +0 -0
  183. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/bridge_templates.py +0 -0
  184. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
  185. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
  186. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
  187. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
  188. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
  189. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
  190. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
  191. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/registry.py +0 -0
  192. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/specification_templates.py +0 -0
  193. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/__init__.py +0 -0
  194. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
  195. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/auth_tokens.py +0 -0
  196. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/bundle_loader.py +0 -0
  197. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/code_change_detector.py +0 -0
  198. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/console.py +0 -0
  199. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/content_sanitizer.py +0 -0
  200. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/context_detection.py +0 -0
  201. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/enrichment_context.py +0 -0
  202. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/enrichment_parser.py +0 -0
  203. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/env_manager.py +0 -0
  204. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/feature_keys.py +0 -0
  205. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/git.py +0 -0
  206. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/github_annotations.py +0 -0
  207. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/ide_setup.py +0 -0
  208. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/incremental_check.py +0 -0
  209. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/metadata.py +0 -0
  210. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/optional_deps.py +0 -0
  211. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/performance.py +0 -0
  212. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/progress.py +0 -0
  213. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
  214. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/prompts.py +0 -0
  215. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/sdd_discovery.py +0 -0
  216. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/source_scanner.py +0 -0
  217. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/startup_checks.py +0 -0
  218. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/structure.py +0 -0
  219. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/structured_io.py +0 -0
  220. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/suggestions.py +0 -0
  221. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/terminal.py +0 -0
  222. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/yaml_utils.py +0 -0
  223. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/__init__.py +0 -0
  224. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/agile_validation.py +0 -0
  225. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
  226. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/cli_first_validator.py +0 -0
  227. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/contract_validator.py +0 -0
  228. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/fsm.py +0 -0
  229. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/repro_checker.py +0 -0
  230. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/schema.py +0 -0
  231. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
  232. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
  233. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
  234. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
  235. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/dependency_installer.py +0 -0
  236. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
  237. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
  238. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
  239. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
  240. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
  241. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
  242. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
  243. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
  244. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/models.py +0 -0
  245. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/orchestrator.py +0 -0
  246. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
  247. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
  248. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/versioning/__init__.py +0 -0
  249. {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/versioning/analyzer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specfact-cli
3
- Version: 0.26.14
3
+ Version: 0.26.16
4
4
  Summary: Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions.
5
5
  Project-URL: Homepage, https://github.com/nold-ai/specfact-cli
6
6
  Project-URL: Repository, https://github.com/nold-ai/specfact-cli.git
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "specfact-cli"
7
- version = "0.26.14"
7
+ version = "0.26.16"
8
8
  description = "Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -272,9 +272,9 @@ TOKENIZERS_PARALLELISM = "false" # Good practice if using HuggingFace tokenizers
272
272
 
273
273
  [tool.hatch.envs.hatch-test.scripts]
274
274
  # Adapted from template, adjust JUnit path if necessary
275
- run = "pytest --timeout=5 --junitxml=logs/tests/junit/test-results.xml {args}" # Removed --auto-capture-workflow if not used
276
- run-cov = "coverage run -m pytest --timeout=5 --junitxml=logs/tests/junit/test-results.xml {args}"
277
- cov = "coverage run -m pytest --timeout=5 --junitxml=logs/tests/junit/test-results.xml {args}"
275
+ run = "pytest --timeout=30 --junitxml=logs/tests/junit/test-results.xml {args}" # 30s for code analysis/semgrep/graph tests under xdist
276
+ run-cov = "coverage run -m pytest --timeout=30 --junitxml=logs/tests/junit/test-results.xml {args}"
277
+ cov = "coverage run -m pytest --timeout=30 --junitxml=logs/tests/junit/test-results.xml {args}"
278
278
  cov-combine = "coverage combine --quiet"
279
279
  xml = "coverage xml -o logs/tests/coverage/coverage.xml"
280
280
  run-html = "coverage html --data-file=logs/tests/coverage/.coverage -d logs/tests/coverage/html"
@@ -334,6 +334,10 @@ output = "logs/tests/coverage/coverage.xml"
334
334
  mode = "strict"
335
335
  default_fixture_loop_scope = "function"
336
336
 
337
+ [tool.pytest-timeout]
338
+ timeout = 30
339
+ method = "thread"
340
+
337
341
  [tool.hatch.build]
338
342
  dev-mode-dirs = ["src","tools"]
339
343
 
@@ -0,0 +1,109 @@
1
+ ---
2
+ description: "Daily standup and sprint review with story-by-story walkthrough"
3
+ ---
4
+
5
+ # SpecFact Daily Standup Command
6
+
7
+ ## User Input
8
+
9
+ ```text
10
+ $ARGUMENTS
11
+ ```
12
+
13
+ You **MUST** consider the user input before proceeding (if not empty).
14
+
15
+ ## Purpose
16
+
17
+ Run a daily standup view and optional interactive walkthrough of backlog items (GitHub Issues, Azure DevOps work items) with the DevOps team: list items in scope, review story-by-story, highlight current focus, surface issues or open questions, and allow adding discussion notes as annotation comments on the issue.
18
+
19
+ **When to use:** Daily standup, sprint review, quick status sync with the team.
20
+
21
+ **Quick:** `/specfact.daily` or `/specfact.backlog-daily` with optional adapter and filters. From a clone, org/repo or org/project are auto-detected from git remote.
22
+
23
+ ## Parameters
24
+
25
+ ### Required
26
+
27
+ - `ADAPTER` - Backlog adapter name (github, ado, etc.)
28
+
29
+ ### Adapter Configuration (same as backlog-refine)
30
+
31
+ **GitHub:** `--repo-owner`, `--repo-name`, `--github-token` (optional).
32
+ **Azure DevOps:** `--ado-org`, `--ado-project`, `--ado-team` (optional), `--ado-base-url`, `--ado-token` (optional).
33
+
34
+ When run from a **clone**, org/repo or org/project are inferred from `git remote get-url origin`; no need to pass them unless overriding.
35
+
36
+ ### Filters
37
+
38
+ - `--state STATE` - Filter by state (e.g. open, Active)
39
+ - `--assignee USERNAME` or `--assignee me` - Filter by assignee
40
+ - `--sprint SPRINT` / `--iteration PATH` - Filter by sprint/iteration (e.g. `current`)
41
+ - `--limit N` - Max items (default 20)
42
+ - `--blockers-first` - Sort items with blockers first
43
+ - `--show-unassigned` / `--unassigned-only` - Include or show only unassigned items
44
+
45
+ ### Daily-Specific Options
46
+
47
+ - `--interactive` - Step-by-step review: select items with arrow keys, view full detail (refine-like) and **existing comments** on each issue
48
+ - `--copilot-export PATH` - Write summarized progress per story to a file for Copilot slash-command use
49
+ - `--summarize` - Output a prompt (instruction + filter context + standup data) to **stdout** for Copilot or slash command to generate a standup summary
50
+ - `--summarize-to PATH` - Write the same summarize prompt to a **file**
51
+ - `--suggest-next` - In interactive mode, show suggested next item by value score
52
+ - `--post` with `--yesterday`, `--today`, `--blockers` - Post a standup comment to the first item's issue (when adapter supports comments)
53
+
54
+ ## Workflow
55
+
56
+ ### Step 1: Run Daily Standup
57
+
58
+ Execute the CLI with adapter and optional filters:
59
+
60
+ ```bash
61
+ specfact backlog daily $ADAPTER [--state open] [--sprint current] [--assignee me] [--limit 20]
62
+ ```
63
+
64
+ Or use the slash command with arguments: `/specfact.backlog-daily --adapter ado --sprint current`
65
+
66
+ **What you see:** A standup table (assigned items) and a "Pending / open for commitment" table (unassigned items in scope). Each row shows ID, title, status, last updated, and optional yesterday/today/blockers from the item body.
67
+
68
+ ### Step 2: Interactive Story-by-Story Review (with DevOps team)
69
+
70
+ When the user runs **`--interactive`** (or the slash command drives an interactive flow):
71
+
72
+ 1. **For each story** (one at a time):
73
+ - **Present** the item: ID, title, status, assignees, last updated, description, acceptance criteria, standup fields (yesterday/today/blockers), and **existing comments** annotated to that issue (when the adapter supports fetching comments).
74
+ - **Highlight current focus**: What is the team member working on? What is the next intended step?
75
+ - **Surface issues or open questions**: Blockers, ambiguities, dependencies, or decisions needed.
76
+ - **Allow discussion notes**: If the team agrees, suggest or add a **comment** on the issue (e.g. "Standup YYYY-MM-DD: …" or "Discussion: …") so the discussion is captured as an annotation. Only add comments when the user explicitly approves (e.g. "add that as a comment").
77
+ - **Move to next** only when the team is done with this story (e.g. "next", "done").
78
+
79
+ 2. **Rules**:
80
+ - Do not update the backlog item body or title unless the user asks for a refinement (use `specfact backlog refine` for that).
81
+ - Comments are for **discussion notes** and standup updates; keep them short and actionable.
82
+ - If the adapter does not support comments, report that clearly and skip adding comments.
83
+
84
+ 3. **Navigation**: After each story, offer "Next story", "Previous story", "Back to list", "Exit" (or equivalent) so the team can move through the list without re-running the command.
85
+
86
+ ### Step 3: Generate Standup Summary (optional)
87
+
88
+ When the user has run `specfact backlog daily ... --summarize` or `--summarize-to PATH`, the output is a **prompt** containing:
89
+
90
+ - A short instruction: generate a concise daily standup summary from the following data.
91
+ - Filter context (adapter, state, sprint, assignee, limit).
92
+ - Per-item data (same as `--copilot-export`: ID, title, status, assignees, last updated, progress, blockers).
93
+
94
+ **Use this output** by pasting it into Copilot or invoking the slash command `specfact.daily` with this context, so the AI can produce a short narrative summary (e.g. "Today's standup: 3 in progress, 1 blocked, 2 pending commitment …").
95
+
96
+ ## Comments on Issues
97
+
98
+ - **Interactive detail view** shows **existing comments** on each issue (GitHub issue comments, ADO work item discussion) when the adapter supports it. Use them to understand prior discussion and avoid repeating questions.
99
+ - **Adding comments**: When the team agrees to record a discussion note or standup update, add it as a comment on the issue (via `--post` for standup lines, or by guiding the user to run the CLI/post manually). Do not invent comments; only suggest or add when the user approves.
100
+
101
+ ## CLI Enforcement
102
+
103
+ - Execute `specfact backlog daily` (or equivalent) first; use its output as context.
104
+ - Use `--interactive` for story-by-story walkthrough; use `--summarize` or `--summarize-to` when a standup summary prompt is needed.
105
+ - Use `--copilot-export` when you need a file of item summaries for reference during standup.
106
+
107
+ ## Context
108
+
109
+ {ARGS}
@@ -69,6 +69,8 @@ Refine backlog items from DevOps tools (GitHub Issues, Azure DevOps, etc.) into
69
69
  - Ambiguous name-only matches will prompt for explicit iteration path
70
70
  - `--release RELEASE` - Filter by release identifier (case-insensitive)
71
71
  - `--limit N` - Maximum number of items to process in this refinement session (caps batch size)
72
+ - `--ignore-refined` / `--no-ignore-refined` - When set (default), exclude already-refined items so `--limit` applies to items that need refinement. Use `--no-ignore-refined` to process the first N items in order.
73
+ - `--id ISSUE_ID` - Refine only this backlog item (issue or work item ID). Other items are ignored.
72
74
  - `--persona PERSONA` - Filter templates by persona (product-owner, architect, developer)
73
75
  - `--framework FRAMEWORK` - Filter templates by framework (agile, scrum, safe, kanban)
74
76
 
@@ -162,6 +164,30 @@ specfact backlog refine $ADAPTER \
162
164
  - Use `:quit` or `:abort` to cancel the entire session gracefully
163
165
  - Session cancellation shows summary and exits without error
164
166
 
167
+ ### Interactive refinement (Copilot mode)
168
+
169
+ When refining backlog items in Copilot mode (e.g. after export to tmp or during a refinement session), follow this **per-story loop** so the PO and stakeholders can review and approve before any update:
170
+
171
+ 1. **For each story** (one at a time):
172
+ - **Present** the refined story in a clear, readable format:
173
+ - Use headings for Title, Body, Acceptance Criteria, Metrics.
174
+ - Use tables or panels for structured data so it is easy to scan.
175
+ - **Assess specification level** so the DevOps team knows if the story is ready, under-specified, or over-specified:
176
+ - **Under-specified**: Missing acceptance criteria, vague scope, unclear "so that" or user value. List evidence (e.g. "No AC", "Scope could mean X or Y"). Suggest what to add.
177
+ - **Over-specified**: Too much implementation detail, too many sub-steps for one story, or solution prescribed instead of outcome. List evidence and suggest what to trim or split.
178
+ - **Fit for scope and intent**: Clear persona, capability, benefit, and testable AC; appropriate size. State briefly why it is ready (and, if DoR is in use, that DoR is satisfied).
179
+ - **List ambiguities** or open questions (e.g. unclear scope, missing acceptance criteria, conflicting assumptions).
180
+ - **Ask** the PO and other stakeholders for clarification: "Please review the refined story above. Do you want any changes? Any ambiguities to resolve? Should this story be split?"
181
+ - **If the user provides feedback**: Re-refine the story incorporating the feedback, then repeat from "Present" for this story.
182
+ - **Only when the user explicitly approves** (e.g. "looks good", "approved", "no changes"): Mark this story as done and move to the **next** story.
183
+ - **Do not update** the backlog item (or write to the refined file as final) until the user has approved this story.
184
+
185
+ 2. **Formatting**:
186
+ - Use clear headings, bullet lists, and optional tables/panels so refinement sessions are easy to follow and enjoyable.
187
+ - Keep each story’s block self-contained so stakeholders can focus on one item at a time.
188
+
189
+ 3. **Rule**: The backlog item (or exported block) must only be updated/finalized **after** the user has approved the refined content for that story. Then proceed to the next story with the same process.
190
+
165
191
  ### Step 3: Present Results
166
192
 
167
193
  Display refinement results:
@@ -3,4 +3,4 @@ SpecFact CLI - Spec→Contract→Sentinel tool for contract-driven development.
3
3
  """
4
4
 
5
5
  # Package version: keep in sync with pyproject.toml, setup.py, src/specfact_cli/__init__.py
6
- __version__ = "0.26.14"
6
+ __version__ = "0.26.16"
@@ -9,6 +9,6 @@ This package provides command-line tools for:
9
9
  - Validating reproducibility
10
10
  """
11
11
 
12
- __version__ = "0.26.14"
12
+ __version__ = "0.26.16"
13
13
 
14
14
  __all__ = ["__version__"]
@@ -3107,6 +3107,11 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
3107
3107
 
3108
3108
  return filtered_items
3109
3109
 
3110
+ @beartype
3111
+ def supports_add_comment(self) -> bool:
3112
+ """Whether this adapter can add comments (requires token, org, project)."""
3113
+ return bool(self.api_token and self.org and self.project)
3114
+
3110
3115
  @beartype
3111
3116
  def add_comment(self, item: BacklogItem, comment: str) -> bool:
3112
3117
  """
@@ -2644,6 +2644,11 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
2644
2644
  lambda result, item: result.id == item.id and result.provider == item.provider,
2645
2645
  "Updated item must preserve id and provider",
2646
2646
  )
2647
+ @beartype
2648
+ def supports_add_comment(self) -> bool:
2649
+ """Whether this adapter can add comments (requires token and repo)."""
2650
+ return bool(self.api_token and self.repo_owner and self.repo_name)
2651
+
2647
2652
  @beartype
2648
2653
  def add_comment(self, item: BacklogItem, comment: str) -> bool:
2649
2654
  """
@@ -2681,6 +2686,31 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
2681
2686
  except Exception:
2682
2687
  return False
2683
2688
 
2689
+ @beartype
2690
+ def get_comments(self, item: BacklogItem) -> list[str]:
2691
+ """
2692
+ Fetch comments for a GitHub issue.
2693
+
2694
+ Args:
2695
+ item: BacklogItem to fetch comments for
2696
+
2697
+ Returns:
2698
+ List of comment body strings, or empty list on error
2699
+ """
2700
+ if not self.repo_owner or not self.repo_name:
2701
+ return []
2702
+ issue_number: int | None = None
2703
+ if item.id.isdigit():
2704
+ issue_number = int(item.id)
2705
+ elif item.url:
2706
+ match = re.search(r"/issues/(\d+)", item.url)
2707
+ if match:
2708
+ issue_number = int(match.group(1))
2709
+ if not issue_number:
2710
+ return []
2711
+ raw = self._get_issue_comments(self.repo_owner, self.repo_name, issue_number)
2712
+ return [str(c.get("body", "")).strip() for c in raw if isinstance(c, dict)]
2713
+
2684
2714
  def update_backlog_item(self, item: BacklogItem, update_fields: list[str] | None = None) -> BacklogItem:
2685
2715
  """
2686
2716
  Update a GitHub issue.
@@ -147,6 +147,20 @@ class BacklogAdapter(ABC):
147
147
  """
148
148
  return None
149
149
 
150
+ @beartype
151
+ @ensure(lambda result: isinstance(result, bool), "Must return boolean")
152
+ def supports_add_comment(self) -> bool:
153
+ """
154
+ Whether this adapter supports adding comments to backlog items.
155
+
156
+ Returns:
157
+ True if add_comment will attempt to post, False otherwise
158
+
159
+ Note:
160
+ Default is False. Override in adapters that support issue comments.
161
+ """
162
+ return False
163
+
150
164
  @beartype
151
165
  def add_comment(self, item: BacklogItem, comment: str) -> bool:
152
166
  """
@@ -164,3 +178,20 @@ class BacklogAdapter(ABC):
164
178
  can use the default False implementation.
165
179
  """
166
180
  return False
181
+
182
+ @beartype
183
+ def get_comments(self, item: BacklogItem) -> list[str]:
184
+ """
185
+ Fetch comments for a backlog item (optional).
186
+
187
+ Args:
188
+ item: BacklogItem to fetch comments for
189
+
190
+ Returns:
191
+ List of comment body strings, or empty list if not supported or on error
192
+
193
+ Note:
194
+ This is an optional method. Adapters that don't support fetching comments
195
+ can use the default empty list implementation.
196
+ """
197
+ return []
@@ -454,6 +454,7 @@ def cli_main() -> None:
454
454
  console.print() # Empty line after banner
455
455
  elif not is_help_or_version and not is_test_mode:
456
456
  # Show simple version line like other CLIs (skip for help/version commands and in test mode)
457
+ # Printed before startup checks so users see output immediately (important with slow checks e.g. xagt)
457
458
  print_version_line()
458
459
 
459
460
  # Run startup checks (template validation and version check)