specfact-cli 0.27.0__tar.gz → 0.28.0__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 (348) hide show
  1. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/.gitignore +4 -0
  2. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/PKG-INFO +14 -1
  3. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/README.md +13 -0
  4. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/pyproject.toml +6 -3
  5. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/__init__.py +1 -1
  6. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/__init__.py +1 -1
  7. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/analyzers/graph_analyzer.py +6 -6
  8. specfact_cli-0.28.0/src/specfact_cli/commands/analyze.py +6 -0
  9. specfact_cli-0.28.0/src/specfact_cli/commands/auth.py +6 -0
  10. specfact_cli-0.28.0/src/specfact_cli/commands/backlog_commands.py +6 -0
  11. specfact_cli-0.28.0/src/specfact_cli/commands/contract_cmd.py +6 -0
  12. specfact_cli-0.28.0/src/specfact_cli/commands/drift.py +6 -0
  13. specfact_cli-0.28.0/src/specfact_cli/commands/enforce.py +6 -0
  14. specfact_cli-0.28.0/src/specfact_cli/commands/generate.py +6 -0
  15. specfact_cli-0.28.0/src/specfact_cli/commands/import_cmd.py +6 -0
  16. specfact_cli-0.28.0/src/specfact_cli/commands/init.py +6 -0
  17. specfact_cli-0.28.0/src/specfact_cli/commands/migrate.py +6 -0
  18. specfact_cli-0.28.0/src/specfact_cli/commands/plan.py +6 -0
  19. specfact_cli-0.28.0/src/specfact_cli/commands/project_cmd.py +6 -0
  20. specfact_cli-0.28.0/src/specfact_cli/commands/repro.py +6 -0
  21. specfact_cli-0.28.0/src/specfact_cli/commands/sdd.py +6 -0
  22. specfact_cli-0.28.0/src/specfact_cli/commands/spec.py +6 -0
  23. specfact_cli-0.28.0/src/specfact_cli/commands/sync.py +6 -0
  24. specfact_cli-0.28.0/src/specfact_cli/commands/update.py +6 -0
  25. specfact_cli-0.28.0/src/specfact_cli/commands/validate.py +6 -0
  26. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/generators/persona_exporter.py +1 -1
  27. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/merge/resolver.py +1 -1
  28. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/plan.py +4 -1
  29. specfact_cli-0.28.0/src/specfact_cli/modules/analyze/src/__init__.py +1 -0
  30. specfact_cli-0.28.0/src/specfact_cli/modules/analyze/src/app.py +6 -0
  31. specfact_cli-0.28.0/src/specfact_cli/modules/auth/src/__init__.py +1 -0
  32. specfact_cli-0.28.0/src/specfact_cli/modules/auth/src/app.py +6 -0
  33. specfact_cli-0.28.0/src/specfact_cli/modules/backlog/src/__init__.py +1 -0
  34. specfact_cli-0.28.0/src/specfact_cli/modules/backlog/src/app.py +6 -0
  35. specfact_cli-0.27.0/src/specfact_cli/commands/backlog_commands.py → specfact_cli-0.28.0/src/specfact_cli/modules/backlog/src/commands.py +4 -2
  36. specfact_cli-0.28.0/src/specfact_cli/modules/contract/src/__init__.py +1 -0
  37. specfact_cli-0.28.0/src/specfact_cli/modules/contract/src/app.py +6 -0
  38. specfact_cli-0.27.0/src/specfact_cli/commands/contract_cmd.py → specfact_cli-0.28.0/src/specfact_cli/modules/contract/src/commands.py +6 -3
  39. specfact_cli-0.28.0/src/specfact_cli/modules/drift/src/__init__.py +1 -0
  40. specfact_cli-0.28.0/src/specfact_cli/modules/drift/src/app.py +6 -0
  41. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/enforce/module-package.yaml +2 -1
  42. specfact_cli-0.28.0/src/specfact_cli/modules/enforce/src/__init__.py +1 -0
  43. specfact_cli-0.28.0/src/specfact_cli/modules/enforce/src/app.py +6 -0
  44. specfact_cli-0.27.0/src/specfact_cli/commands/enforce.py → specfact_cli-0.28.0/src/specfact_cli/modules/enforce/src/commands.py +1 -1
  45. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/generate/module-package.yaml +2 -1
  46. specfact_cli-0.28.0/src/specfact_cli/modules/generate/src/__init__.py +1 -0
  47. specfact_cli-0.28.0/src/specfact_cli/modules/generate/src/app.py +6 -0
  48. specfact_cli-0.27.0/src/specfact_cli/commands/generate.py → specfact_cli-0.28.0/src/specfact_cli/modules/generate/src/commands.py +1 -1
  49. specfact_cli-0.28.0/src/specfact_cli/modules/import_cmd/src/__init__.py +1 -0
  50. specfact_cli-0.28.0/src/specfact_cli/modules/import_cmd/src/app.py +6 -0
  51. specfact_cli-0.28.0/src/specfact_cli/modules/init/src/__init__.py +1 -0
  52. specfact_cli-0.28.0/src/specfact_cli/modules/init/src/app.py +6 -0
  53. specfact_cli-0.28.0/src/specfact_cli/modules/migrate/src/__init__.py +1 -0
  54. specfact_cli-0.28.0/src/specfact_cli/modules/migrate/src/app.py +6 -0
  55. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/plan/module-package.yaml +2 -1
  56. specfact_cli-0.28.0/src/specfact_cli/modules/plan/src/__init__.py +1 -0
  57. specfact_cli-0.28.0/src/specfact_cli/modules/plan/src/app.py +6 -0
  58. specfact_cli-0.27.0/src/specfact_cli/commands/plan.py → specfact_cli-0.28.0/src/specfact_cli/modules/plan/src/commands.py +29 -16
  59. specfact_cli-0.28.0/src/specfact_cli/modules/project/src/__init__.py +1 -0
  60. specfact_cli-0.28.0/src/specfact_cli/modules/project/src/app.py +6 -0
  61. specfact_cli-0.27.0/src/specfact_cli/commands/project_cmd.py → specfact_cli-0.28.0/src/specfact_cli/modules/project/src/commands.py +6 -9
  62. specfact_cli-0.28.0/src/specfact_cli/modules/repro/src/__init__.py +1 -0
  63. specfact_cli-0.28.0/src/specfact_cli/modules/repro/src/app.py +6 -0
  64. specfact_cli-0.28.0/src/specfact_cli/modules/sdd/src/__init__.py +1 -0
  65. specfact_cli-0.28.0/src/specfact_cli/modules/sdd/src/app.py +6 -0
  66. specfact_cli-0.28.0/src/specfact_cli/modules/spec/src/__init__.py +1 -0
  67. specfact_cli-0.28.0/src/specfact_cli/modules/spec/src/app.py +6 -0
  68. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/sync/module-package.yaml +3 -1
  69. specfact_cli-0.28.0/src/specfact_cli/modules/sync/src/__init__.py +1 -0
  70. specfact_cli-0.28.0/src/specfact_cli/modules/sync/src/app.py +6 -0
  71. specfact_cli-0.27.0/src/specfact_cli/commands/sync.py → specfact_cli-0.28.0/src/specfact_cli/modules/sync/src/commands.py +87 -9
  72. specfact_cli-0.28.0/src/specfact_cli/modules/upgrade/src/__init__.py +1 -0
  73. specfact_cli-0.28.0/src/specfact_cli/modules/upgrade/src/app.py +6 -0
  74. specfact_cli-0.28.0/src/specfact_cli/modules/validate/src/__init__.py +1 -0
  75. specfact_cli-0.28.0/src/specfact_cli/modules/validate/src/app.py +6 -0
  76. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/parsers/persona_importer.py +2 -2
  77. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/registry/registry.py +17 -3
  78. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/git.py +3 -3
  79. specfact_cli-0.28.0/src/specfact_cli/utils/persona_ownership.py +34 -0
  80. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/source_scanner.py +14 -11
  81. specfact_cli-0.27.0/src/specfact_cli/modules/analyze/src/app.py +0 -6
  82. specfact_cli-0.27.0/src/specfact_cli/modules/auth/src/app.py +0 -6
  83. specfact_cli-0.27.0/src/specfact_cli/modules/backlog/src/app.py +0 -6
  84. specfact_cli-0.27.0/src/specfact_cli/modules/contract/src/app.py +0 -6
  85. specfact_cli-0.27.0/src/specfact_cli/modules/drift/src/app.py +0 -6
  86. specfact_cli-0.27.0/src/specfact_cli/modules/enforce/src/app.py +0 -6
  87. specfact_cli-0.27.0/src/specfact_cli/modules/generate/src/app.py +0 -6
  88. specfact_cli-0.27.0/src/specfact_cli/modules/import_cmd/src/app.py +0 -6
  89. specfact_cli-0.27.0/src/specfact_cli/modules/init/src/app.py +0 -6
  90. specfact_cli-0.27.0/src/specfact_cli/modules/migrate/src/app.py +0 -6
  91. specfact_cli-0.27.0/src/specfact_cli/modules/plan/src/app.py +0 -6
  92. specfact_cli-0.27.0/src/specfact_cli/modules/project/src/app.py +0 -6
  93. specfact_cli-0.27.0/src/specfact_cli/modules/repro/src/app.py +0 -6
  94. specfact_cli-0.27.0/src/specfact_cli/modules/sdd/src/app.py +0 -6
  95. specfact_cli-0.27.0/src/specfact_cli/modules/spec/src/app.py +0 -6
  96. specfact_cli-0.27.0/src/specfact_cli/modules/sync/src/app.py +0 -6
  97. specfact_cli-0.27.0/src/specfact_cli/modules/upgrade/src/app.py +0 -6
  98. specfact_cli-0.27.0/src/specfact_cli/modules/validate/src/app.py +0 -6
  99. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/LICENSE.md +0 -0
  100. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/mappings/node-async.yaml +0 -0
  101. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/mappings/python-async.yaml +0 -0
  102. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/mappings/speckit-default.yaml +0 -0
  103. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/shared/cli-enforcement.md +0 -0
  104. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.01-import.md +0 -0
  105. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.02-plan.md +0 -0
  106. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.03-review.md +0 -0
  107. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.04-sdd.md +0 -0
  108. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.05-enforce.md +0 -0
  109. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.06-sync.md +0 -0
  110. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.07-contracts.md +0 -0
  111. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.backlog-daily.md +0 -0
  112. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.backlog-refine.md +0 -0
  113. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.compare.md +0 -0
  114. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.sync-backlog.md +0 -0
  115. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/prompts/specfact.validate.md +0 -0
  116. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/schemas/deviation.schema.json +0 -0
  117. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/schemas/plan.schema.json +0 -0
  118. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/schemas/protocol.schema.json +0 -0
  119. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/defaults/defect_v1.yaml +0 -0
  120. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/defaults/enabler_v1.yaml +0 -0
  121. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/defaults/spike_v1.yaml +0 -0
  122. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/defaults/user_story_v1.yaml +0 -0
  123. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/field_mappings/ado_agile.yaml +0 -0
  124. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/field_mappings/ado_default.yaml +0 -0
  125. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/field_mappings/ado_kanban.yaml +0 -0
  126. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/field_mappings/ado_safe.yaml +0 -0
  127. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/field_mappings/ado_scrum.yaml +0 -0
  128. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/frameworks/safe/safe_feature_v1.yaml +0 -0
  129. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/frameworks/scrum/user_story_v1.yaml +0 -0
  130. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/personas/developer/developer_task_v1.yaml +0 -0
  131. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/personas/product-owner/user_story_v1.yaml +0 -0
  132. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/backlog/providers/ado/work_item_v1.yaml +0 -0
  133. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/github-action.yml.j2 +0 -0
  134. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/persona/architect.md.j2 +0 -0
  135. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/persona/developer.md.j2 +0 -0
  136. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/persona/product-owner.md.j2 +0 -0
  137. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/plan.bundle.yaml.j2 +0 -0
  138. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/pr-template.md.j2 +0 -0
  139. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/protocol.yaml.j2 +0 -0
  140. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/resources/templates/telemetry.yaml.example +0 -0
  141. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/__main__.py +0 -0
  142. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/adapters/__init__.py +0 -0
  143. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/adapters/ado.py +0 -0
  144. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/adapters/backlog_base.py +0 -0
  145. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/adapters/base.py +0 -0
  146. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/adapters/github.py +0 -0
  147. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/adapters/openspec.py +0 -0
  148. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/adapters/openspec_parser.py +0 -0
  149. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/adapters/registry.py +0 -0
  150. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/adapters/speckit.py +0 -0
  151. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/agents/__init__.py +0 -0
  152. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/agents/analyze_agent.py +0 -0
  153. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/agents/base.py +0 -0
  154. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/agents/plan_agent.py +0 -0
  155. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/agents/registry.py +0 -0
  156. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/agents/sync_agent.py +0 -0
  157. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/analyzers/__init__.py +0 -0
  158. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
  159. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
  160. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
  161. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
  162. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
  163. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
  164. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
  165. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
  166. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/__init__.py +0 -0
  167. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
  168. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/adapters/base.py +0 -0
  169. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/adapters/local_yaml_adapter.py +0 -0
  170. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/ai_refiner.py +0 -0
  171. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/converter.py +0 -0
  172. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/filters.py +0 -0
  173. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/format_detector.py +0 -0
  174. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/formats/__init__.py +0 -0
  175. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/formats/base.py +0 -0
  176. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/formats/markdown_format.py +0 -0
  177. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/formats/structured_format.py +0 -0
  178. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
  179. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
  180. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/mappers/base.py +0 -0
  181. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
  182. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
  183. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/backlog/template_detector.py +0 -0
  184. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/cli.py +0 -0
  185. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/commands/__init__.py +0 -0
  186. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/common/__init__.py +0 -0
  187. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/common/logger_setup.py +0 -0
  188. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/common/logging_utils.py +0 -0
  189. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/common/text_utils.py +0 -0
  190. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/common/utils.py +0 -0
  191. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/comparators/__init__.py +0 -0
  192. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/comparators/plan_comparator.py +0 -0
  193. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/contracts/__init__.py +0 -0
  194. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/contracts/crosshair_props.py +0 -0
  195. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
  196. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
  197. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/generators/__init__.py +0 -0
  198. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/generators/contract_generator.py +0 -0
  199. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/generators/openapi_extractor.py +0 -0
  200. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/generators/plan_generator.py +0 -0
  201. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/generators/protocol_generator.py +0 -0
  202. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/generators/report_generator.py +0 -0
  203. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/generators/task_generator.py +0 -0
  204. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/generators/test_to_openapi.py +0 -0
  205. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/generators/workflow_generator.py +0 -0
  206. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/importers/__init__.py +0 -0
  207. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/importers/speckit_converter.py +0 -0
  208. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/importers/speckit_scanner.py +0 -0
  209. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/integrations/__init__.py +0 -0
  210. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/integrations/specmatic.py +0 -0
  211. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/merge/__init__.py +0 -0
  212. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/migrations/__init__.py +0 -0
  213. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/migrations/plan_migrator.py +0 -0
  214. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/__init__.py +0 -0
  215. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/backlog_item.py +0 -0
  216. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/bridge.py +0 -0
  217. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/capabilities.py +0 -0
  218. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/change.py +0 -0
  219. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/contract.py +0 -0
  220. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/deviation.py +0 -0
  221. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/dor_config.py +0 -0
  222. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/enforcement.py +0 -0
  223. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/persona_template.py +0 -0
  224. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/project.py +0 -0
  225. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/protocol.py +0 -0
  226. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/quality.py +0 -0
  227. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/sdd.py +0 -0
  228. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/source_tracking.py +0 -0
  229. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/models/task.py +0 -0
  230. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modes/__init__.py +0 -0
  231. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modes/detector.py +0 -0
  232. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modes/router.py +0 -0
  233. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/__init__.py +0 -0
  234. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/analyze/module-package.yaml +0 -0
  235. /specfact_cli-0.27.0/src/specfact_cli/commands/analyze.py → /specfact_cli-0.28.0/src/specfact_cli/modules/analyze/src/commands.py +0 -0
  236. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/auth/module-package.yaml +0 -0
  237. /specfact_cli-0.27.0/src/specfact_cli/commands/auth.py → /specfact_cli-0.28.0/src/specfact_cli/modules/auth/src/commands.py +0 -0
  238. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/backlog/module-package.yaml +0 -0
  239. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/contract/module-package.yaml +0 -0
  240. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/drift/module-package.yaml +0 -0
  241. /specfact_cli-0.27.0/src/specfact_cli/commands/drift.py → /specfact_cli-0.28.0/src/specfact_cli/modules/drift/src/commands.py +0 -0
  242. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/import_cmd/module-package.yaml +0 -0
  243. /specfact_cli-0.27.0/src/specfact_cli/commands/import_cmd.py → /specfact_cli-0.28.0/src/specfact_cli/modules/import_cmd/src/commands.py +0 -0
  244. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/init/module-package.yaml +0 -0
  245. /specfact_cli-0.27.0/src/specfact_cli/commands/init.py → /specfact_cli-0.28.0/src/specfact_cli/modules/init/src/commands.py +0 -0
  246. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/migrate/module-package.yaml +0 -0
  247. /specfact_cli-0.27.0/src/specfact_cli/commands/migrate.py → /specfact_cli-0.28.0/src/specfact_cli/modules/migrate/src/commands.py +0 -0
  248. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/project/module-package.yaml +0 -0
  249. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/repro/module-package.yaml +0 -0
  250. /specfact_cli-0.27.0/src/specfact_cli/commands/repro.py → /specfact_cli-0.28.0/src/specfact_cli/modules/repro/src/commands.py +0 -0
  251. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/sdd/module-package.yaml +0 -0
  252. /specfact_cli-0.27.0/src/specfact_cli/commands/sdd.py → /specfact_cli-0.28.0/src/specfact_cli/modules/sdd/src/commands.py +0 -0
  253. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/spec/module-package.yaml +0 -0
  254. /specfact_cli-0.27.0/src/specfact_cli/commands/spec.py → /specfact_cli-0.28.0/src/specfact_cli/modules/spec/src/commands.py +0 -0
  255. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/upgrade/module-package.yaml +0 -0
  256. /specfact_cli-0.27.0/src/specfact_cli/commands/update.py → /specfact_cli-0.28.0/src/specfact_cli/modules/upgrade/src/commands.py +0 -0
  257. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/modules/validate/module-package.yaml +0 -0
  258. /specfact_cli-0.27.0/src/specfact_cli/commands/validate.py → /specfact_cli-0.28.0/src/specfact_cli/modules/validate/src/commands.py +0 -0
  259. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/parsers/__init__.py +0 -0
  260. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/registry/__init__.py +0 -0
  261. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/registry/bootstrap.py +0 -0
  262. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/registry/help_cache.py +0 -0
  263. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/registry/metadata.py +0 -0
  264. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/registry/module_packages.py +0 -0
  265. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/registry/module_state.py +0 -0
  266. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/resources/semgrep/async.yml +0 -0
  267. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
  268. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
  269. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/runtime.py +0 -0
  270. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/__init__.py +0 -0
  271. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/bridge_probe.py +0 -0
  272. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/bridge_sync.py +0 -0
  273. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/bridge_watch.py +0 -0
  274. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/change_detector.py +0 -0
  275. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/code_to_spec.py +0 -0
  276. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/drift_detector.py +0 -0
  277. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/repository_sync.py +0 -0
  278. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/spec_to_code.py +0 -0
  279. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/spec_to_tests.py +0 -0
  280. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/watcher.py +0 -0
  281. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
  282. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/telemetry.py +0 -0
  283. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/__init__.py +0 -0
  284. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/bridge_templates.py +0 -0
  285. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
  286. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
  287. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
  288. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
  289. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
  290. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
  291. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
  292. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/registry.py +0 -0
  293. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/templates/specification_templates.py +0 -0
  294. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/__init__.py +0 -0
  295. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
  296. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/auth_tokens.py +0 -0
  297. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/bundle_loader.py +0 -0
  298. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/code_change_detector.py +0 -0
  299. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/console.py +0 -0
  300. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/content_sanitizer.py +0 -0
  301. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/context_detection.py +0 -0
  302. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/enrichment_context.py +0 -0
  303. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/enrichment_parser.py +0 -0
  304. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/env_manager.py +0 -0
  305. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/feature_keys.py +0 -0
  306. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/github_annotations.py +0 -0
  307. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/ide_setup.py +0 -0
  308. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/incremental_check.py +0 -0
  309. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/metadata.py +0 -0
  310. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/optional_deps.py +0 -0
  311. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/performance.py +0 -0
  312. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/progress.py +0 -0
  313. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
  314. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/prompts.py +0 -0
  315. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/sdd_discovery.py +0 -0
  316. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/startup_checks.py +0 -0
  317. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/structure.py +0 -0
  318. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/structured_io.py +0 -0
  319. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/suggestions.py +0 -0
  320. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/terminal.py +0 -0
  321. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/utils/yaml_utils.py +0 -0
  322. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/__init__.py +0 -0
  323. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/agile_validation.py +0 -0
  324. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
  325. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/cli_first_validator.py +0 -0
  326. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/contract_validator.py +0 -0
  327. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/fsm.py +0 -0
  328. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/repro_checker.py +0 -0
  329. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/schema.py +0 -0
  330. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
  331. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
  332. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
  333. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
  334. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/dependency_installer.py +0 -0
  335. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
  336. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
  337. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
  338. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
  339. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
  340. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
  341. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
  342. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
  343. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/models.py +0 -0
  344. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/orchestrator.py +0 -0
  345. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
  346. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
  347. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/versioning/__init__.py +0 -0
  348. {specfact_cli-0.27.0 → specfact_cli-0.28.0}/src/specfact_cli/versioning/analyzer.py +0 -0
@@ -107,6 +107,10 @@ docs/internal/
107
107
  .github/prompts/specfact.*.md
108
108
  .github/prompts/opsx-*.md
109
109
 
110
+ .claude/commands/opsx/
111
+ .claude/skills/openspec-*/
112
+ !.claude/skills/openspec-workflows/
113
+
110
114
  # Semgrep rules (generated from tools/semgrep/ - source rules are versioned)
111
115
  .semgrep/
112
116
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specfact-cli
3
- Version: 0.27.0
3
+ Version: 0.28.0
4
4
  Summary: The swiss knife CLI for agile DevOps teams. Keep backlog, specs, tests, and code in sync with validation and contract enforcement for new projects and long-lived codebases.
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
@@ -414,6 +414,19 @@ Most tools help **either** coders **or** agile teams. SpecFact does both:
414
414
 
415
415
  ---
416
416
 
417
+ ## Developer Note: Command Layout
418
+
419
+ - Primary command implementations live in `src/specfact_cli/modules/<module>/src/commands.py`.
420
+ - Legacy imports from `src/specfact_cli/commands/*.py` are compatibility shims and only guarantee `app` re-exports.
421
+ - Preferred imports for module code:
422
+ - `from specfact_cli.modules.<module>.src.commands import app`
423
+ - `from specfact_cli.modules.<module>.src.commands import <symbol>`
424
+ - Shim deprecation timeline:
425
+ - Legacy shim usage is deprecated for non-`app` symbols now.
426
+ - Shim removal is planned no earlier than `v0.30` (or the next major migration window).
427
+
428
+ ---
429
+
417
430
  ## Where SpecFact Fits
418
431
 
419
432
  SpecFact complements your stack rather than replacing it.
@@ -136,6 +136,19 @@ Most tools help **either** coders **or** agile teams. SpecFact does both:
136
136
 
137
137
  ---
138
138
 
139
+ ## Developer Note: Command Layout
140
+
141
+ - Primary command implementations live in `src/specfact_cli/modules/<module>/src/commands.py`.
142
+ - Legacy imports from `src/specfact_cli/commands/*.py` are compatibility shims and only guarantee `app` re-exports.
143
+ - Preferred imports for module code:
144
+ - `from specfact_cli.modules.<module>.src.commands import app`
145
+ - `from specfact_cli.modules.<module>.src.commands import <symbol>`
146
+ - Shim deprecation timeline:
147
+ - Legacy shim usage is deprecated for non-`app` symbols now.
148
+ - Shim removal is planned no earlier than `v0.30` (or the next major migration window).
149
+
150
+ ---
151
+
139
152
  ## Where SpecFact Fits
140
153
 
141
154
  SpecFact complements your stack rather than replacing it.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "specfact-cli"
7
- version = "0.27.0"
7
+ version = "0.28.0"
8
8
  description = "The swiss knife CLI for agile DevOps teams. Keep backlog, specs, tests, and code in sync with validation and contract enforcement for new projects and long-lived codebases."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -193,8 +193,8 @@ validate-prompts = "python tools/validate_prompts.py"
193
193
  # Development scripts
194
194
  test = "pytest {args}"
195
195
  test-cov = "pytest --cov=src --cov-report=term-missing {args}"
196
- type-check = "basedpyright {args}"
197
- lint = "ruff format . --check && basedpyright && ruff check . && pylint src tests tools"
196
+ type-check = "basedpyright --pythonpath $(python -c 'import sys; print(sys.executable)') {args}"
197
+ lint = "ruff format . --check && basedpyright --pythonpath $(python -c 'import sys; print(sys.executable)') && ruff check . && pylint src tests tools"
198
198
  governance = "pylint src tests tools --reports=y --output-format=parseable"
199
199
  format = "ruff check . --fix && ruff format ."
200
200
 
@@ -705,6 +705,9 @@ ignore = [
705
705
  "src/specfact_cli/commands/**/*" = [
706
706
  "B008", # typer.Option/Argument in defaults (common Typer pattern)
707
707
  ]
708
+ "src/specfact_cli/modules/**/src/commands.py" = [
709
+ "B008", # typer.Option/Argument in defaults (common Typer pattern)
710
+ ]
708
711
 
709
712
  [tool.ruff.lint.isort]
710
713
  # Match isort ruff profile configuration
@@ -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.27.0"
6
+ __version__ = "0.28.0"
@@ -8,6 +8,6 @@ This package provides command-line tools for:
8
8
  - Supporting agile ceremonies and team workflows
9
9
  """
10
10
 
11
- __version__ = "0.27.0"
11
+ __version__ = "0.28.0"
12
12
 
13
13
  __all__ = ["__version__"]
@@ -370,11 +370,11 @@ class GraphAnalyzer:
370
370
 
371
371
  Tries multiple strategies:
372
372
  1. Exact match
373
- 2. Last part match (e.g., "import_cmd" matches "src.specfact_cli.commands.import_cmd")
374
- 3. Partial path match (e.g., "specfact_cli.commands" matches "src.specfact_cli.commands.import_cmd")
373
+ 2. Last part match (e.g., "import_cmd" matches "src.specfact_cli.modules.import_cmd.src.commands")
374
+ 3. Partial path match (e.g., "specfact_cli.commands" matches "src.specfact_cli.modules.import_cmd.src.commands")
375
375
 
376
376
  Args:
377
- imported: Imported module name (e.g., "specfact_cli.commands.import_cmd")
377
+ imported: Imported module name (e.g., "specfact_cli.modules.import_cmd.src.commands")
378
378
  known_modules: List of known module names in the graph
379
379
 
380
380
  Returns:
@@ -385,14 +385,14 @@ class GraphAnalyzer:
385
385
  return imported
386
386
 
387
387
  # Strategy 2: Last part match
388
- # e.g., "import_cmd" matches "src.specfact_cli.commands.import_cmd"
388
+ # e.g., "import_cmd" matches "src.specfact_cli.modules.import_cmd.src.commands"
389
389
  imported_last = imported.split(".")[-1]
390
390
  for module in known_modules:
391
391
  if module.endswith(f".{imported_last}") or module == imported_last:
392
392
  return module
393
393
 
394
394
  # Strategy 3: Partial path match
395
- # e.g., "specfact_cli.commands" matches "src.specfact_cli.commands.import_cmd"
395
+ # e.g., "specfact_cli.commands" matches "src.specfact_cli.modules.import_cmd.src.commands"
396
396
  for module in known_modules:
397
397
  # Check if imported is a prefix of module
398
398
  if module.startswith(imported + ".") or module == imported:
@@ -406,7 +406,7 @@ class GraphAnalyzer:
406
406
  for module in known_modules:
407
407
  module_parts = module.split(".")
408
408
  # Check if there's overlap in the path
409
- # e.g., "commands.import_cmd" might match "src.specfact_cli.commands.import_cmd"
409
+ # e.g., "commands.import_cmd" might match "src.specfact_cli.modules.import_cmd.src.commands"
410
410
  if len(imported_parts) >= 2 and len(module_parts) >= 2 and imported_parts[-2:] == module_parts[-2:]:
411
411
  return module
412
412
 
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/analyze/."""
2
+
3
+ from specfact_cli.modules.analyze.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/auth/."""
2
+
3
+ from specfact_cli.modules.auth.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/backlog/."""
2
+
3
+ from specfact_cli.modules.backlog.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/contract/."""
2
+
3
+ from specfact_cli.modules.contract.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/drift/."""
2
+
3
+ from specfact_cli.modules.drift.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/enforce/."""
2
+
3
+ from specfact_cli.modules.enforce.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/generate/."""
2
+
3
+ from specfact_cli.modules.generate.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/import_cmd/."""
2
+
3
+ from specfact_cli.modules.import_cmd.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/init/."""
2
+
3
+ from specfact_cli.modules.init.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/migrate/."""
2
+
3
+ from specfact_cli.modules.migrate.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/plan/."""
2
+
3
+ from specfact_cli.modules.plan.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/project/."""
2
+
3
+ from specfact_cli.modules.project.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/repro/."""
2
+
3
+ from specfact_cli.modules.repro.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/sdd/."""
2
+
3
+ from specfact_cli.modules.sdd.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/spec/."""
2
+
3
+ from specfact_cli.modules.spec.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/sync/."""
2
+
3
+ from specfact_cli.modules.sync.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/upgrade/."""
2
+
3
+ from specfact_cli.modules.upgrade.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,6 @@
1
+ """Backward-compatible app shim. Implementation moved to modules/validate/."""
2
+
3
+ from specfact_cli.modules.validate.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -108,7 +108,7 @@ class PersonaExporter:
108
108
  Returns:
109
109
  Template context dictionary
110
110
  """
111
- from specfact_cli.commands.project_cmd import match_section_pattern
111
+ from specfact_cli.utils.persona_ownership import match_section_pattern
112
112
 
113
113
  context: dict[str, Any] = {
114
114
  "bundle_name": bundle.bundle_name,
@@ -355,7 +355,7 @@ class PersonaMergeResolver:
355
355
  Returns:
356
356
  Persona name if persona owns section, None otherwise
357
357
  """
358
- from specfact_cli.commands.project_cmd import check_persona_ownership
358
+ from specfact_cli.utils.persona_ownership import check_persona_ownership
359
359
 
360
360
  if check_persona_ownership(persona, manifest, section_path):
361
361
  return persona
@@ -290,4 +290,7 @@ class PlanBundle(BaseModel):
290
290
  external_dependencies=[],
291
291
  summary=None,
292
292
  )
293
- self.metadata.summary = self.compute_summary(include_hash=include_hash)
293
+ metadata = self.metadata
294
+ if metadata is None:
295
+ return
296
+ metadata.summary = self.compute_summary(include_hash=include_hash)
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """analyze command entrypoint."""
2
+
3
+ from specfact_cli.modules.analyze.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """auth command entrypoint."""
2
+
3
+ from specfact_cli.modules.auth.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """backlog command entrypoint."""
2
+
3
+ from specfact_cli.modules.backlog.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -1538,14 +1538,16 @@ def refine(
1538
1538
  built_in_loaded = True
1539
1539
  else:
1540
1540
  # Fallback: Try relative to repo root (development mode)
1541
- repo_root = Path(__file__).parent.parent.parent.parent
1541
+ # __file__ = src/specfact_cli/modules/backlog/src/commands.py → 6 parents to repo root
1542
+ repo_root = Path(__file__).parent.parent.parent.parent.parent.parent
1542
1543
  resources_templates_dir = repo_root / "resources" / "templates" / "backlog"
1543
1544
  if resources_templates_dir.exists():
1544
1545
  registry.load_templates_from_directory(resources_templates_dir)
1545
1546
  built_in_loaded = True
1546
1547
  else:
1547
1548
  # 2. Fallback to src/specfact_cli/templates/ for backward compatibility
1548
- src_templates_dir = Path(__file__).parent.parent / "templates"
1549
+ # __file__ → 4 parents to reach src/specfact_cli/
1550
+ src_templates_dir = Path(__file__).parent.parent.parent.parent / "templates"
1549
1551
  if src_templates_dir.exists():
1550
1552
  registry.load_templates_from_directory(src_templates_dir)
1551
1553
  built_in_loaded = True
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """contract command entrypoint."""
2
+
3
+ from specfact_cli.modules.contract.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -113,7 +113,7 @@ def init_contract(
113
113
  if not bundle_names:
114
114
  print_error("No valid bundle names found")
115
115
  raise typer.Exit(1)
116
- bundle = Prompt.ask("Select bundle", choices=bundle_names)
116
+ bundle = Prompt.ask("Select bundle", choices=bundle_names)
117
117
  elif bundle is None:
118
118
  print_error("Bundle not specified and no active bundle found")
119
119
  raise typer.Exit(1)
@@ -278,7 +278,7 @@ def _update_contract_index(bundle: ProjectBundle, feature_key: str, contract_pat
278
278
  endpoints_count = count_endpoints(contract_data)
279
279
  checksum = hashlib.sha256(contract_file.read_bytes()).hexdigest()
280
280
  except Exception:
281
- pass
281
+ print_warning(f"Failed to load or analyze contract file '{contract_file}'. Using default metadata.")
282
282
 
283
283
  contract_index = ContractIndex(
284
284
  feature_key=feature_key,
@@ -718,7 +718,10 @@ def serve_contract(
718
718
 
719
719
  feature_choices = [f"{key}: {obj.title}" for key, obj in features_with_contracts]
720
720
  selected = Prompt.ask("Select feature contract", choices=feature_choices)
721
- feature = selected.split(":")[0]
721
+ feature = selected.split(":", 1)[0].strip()
722
+ if feature not in bundle_obj.features:
723
+ print_error(f"Selected feature '{feature}' not found in bundle")
724
+ raise typer.Exit(1)
722
725
  feature_obj = bundle_obj.features[feature]
723
726
  if not feature_obj.contract:
724
727
  print_error(f"Feature '{feature}' has no contract")
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """drift command entrypoint."""
2
+
3
+ from specfact_cli.modules.drift.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -6,5 +6,6 @@ commands:
6
6
  command_help:
7
7
  enforce: "Configure quality gates"
8
8
  pip_dependencies: []
9
- module_dependencies: []
9
+ module_dependencies:
10
+ - plan
10
11
  tier: community
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """enforce command entrypoint."""
2
+
3
+ from specfact_cli.modules.enforce.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -296,7 +296,7 @@ def enforce_sdd(
296
296
  raise typer.Exit(1)
297
297
 
298
298
  # Convert to PlanBundle for compatibility with validation functions
299
- from specfact_cli.commands.plan import _convert_project_bundle_to_plan_bundle
299
+ from specfact_cli.modules.plan.src.commands import _convert_project_bundle_to_plan_bundle
300
300
 
301
301
  plan_bundle = _convert_project_bundle_to_plan_bundle(project_bundle)
302
302
 
@@ -6,5 +6,6 @@ commands:
6
6
  command_help:
7
7
  generate: "Generate artifacts from SDD and plans"
8
8
  pip_dependencies: []
9
- module_dependencies: []
9
+ module_dependencies:
10
+ - plan
10
11
  tier: community
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """generate command entrypoint."""
2
+
3
+ from specfact_cli.modules.generate.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -241,7 +241,7 @@ def generate_contracts(
241
241
  plan_hash = None
242
242
  if format_type == BundleFormat.MODULAR or bundle:
243
243
  # Load modular ProjectBundle and convert to PlanBundle for compatibility
244
- from specfact_cli.commands.plan import _convert_project_bundle_to_plan_bundle
244
+ from specfact_cli.modules.plan.src.commands import _convert_project_bundle_to_plan_bundle
245
245
 
246
246
  project_bundle = load_bundle_with_progress(plan_path, validate_hashes=False, console_instance=console)
247
247
 
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """import_cmd command entrypoint."""
2
+
3
+ from specfact_cli.modules.import_cmd.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """init command entrypoint."""
2
+
3
+ from specfact_cli.modules.init.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """migrate command entrypoint."""
2
+
3
+ from specfact_cli.modules.migrate.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]
@@ -6,5 +6,6 @@ commands:
6
6
  command_help:
7
7
  plan: "Manage development plans"
8
8
  pip_dependencies: []
9
- module_dependencies: []
9
+ module_dependencies:
10
+ - sync
10
11
  tier: community
@@ -0,0 +1 @@
1
+ """Module package source namespace."""
@@ -0,0 +1,6 @@
1
+ """plan command entrypoint."""
2
+
3
+ from specfact_cli.modules.plan.src.commands import app
4
+
5
+
6
+ __all__ = ["app"]