specfact-cli 0.43.3__tar.gz → 0.45.1__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 (278) hide show
  1. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/PKG-INFO +38 -27
  2. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/README.md +31 -19
  3. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/pyproject.toml +29 -18
  4. specfact_cli-0.45.1/resources/templates/github-action.yml.j2 +200 -0
  5. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/pr-template.md.j2 +9 -0
  6. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/__init__.py +1 -1
  7. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/__init__.py +1 -1
  8. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/speckit.py +1 -1
  9. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/analyze_agent.py +1 -1
  10. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/ambiguity_scanner.py +3 -3
  11. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/code_analyzer.py +2 -2
  12. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/contract_extractor.py +3 -3
  13. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/graph_analyzer.py +2 -2
  14. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/relationship_mapper.py +2 -2
  15. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/cli.py +200 -74
  16. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/logger_setup.py +2 -2
  17. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/enrichers/constitution_enricher.py +5 -5
  18. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/persona_exporter.py +2 -2
  19. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/plan_generator.py +4 -2
  20. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/workflow_generator.py +7 -2
  21. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/_bundle_import.py +7 -3
  22. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/init/module-package.yaml +3 -3
  23. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/init/src/commands.py +15 -50
  24. specfact_cli-0.45.1/src/specfact_cli/modules/init/src/first_run_selection.py +354 -0
  25. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/module_io_shim.py +0 -4
  26. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/module_registry/module-package.yaml +3 -3
  27. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/module_registry/src/commands.py +505 -105
  28. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/bootstrap.py +13 -3
  29. specfact_cli-0.45.1/src/specfact_cli/registry/dependency_resolver.py +186 -0
  30. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_installer.py +40 -8
  31. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_packages.py +147 -201
  32. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync.py +4 -4
  33. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/spec_to_code.py +1 -1
  34. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/context_detection.py +2 -2
  35. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/progress.py +3 -3
  36. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/progressive_disclosure.py +0 -16
  37. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/source_scanner.py +2 -2
  38. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/structure.py +2 -2
  39. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/dependency_installer.py +1 -1
  40. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/orchestrator.py +1 -1
  41. specfact_cli-0.43.3/resources/templates/github-action.yml.j2 +0 -172
  42. specfact_cli-0.43.3/src/specfact_cli/modules/init/src/first_run_selection.py +0 -198
  43. specfact_cli-0.43.3/src/specfact_cli/registry/dependency_resolver.py +0 -109
  44. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/.gitignore +0 -0
  45. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/LICENSE +0 -0
  46. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/keys/README.md +0 -0
  47. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/keys/module-signing-public.pem +0 -0
  48. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/mappings/node-async.yaml +0 -0
  49. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/mappings/python-async.yaml +0 -0
  50. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/mappings/speckit-default.yaml +0 -0
  51. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/schemas/deviation.schema.json +0 -0
  52. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/schemas/plan.schema.json +0 -0
  53. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/schemas/protocol.schema.json +0 -0
  54. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/persona/architect.md.j2 +0 -0
  55. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/persona/developer.md.j2 +0 -0
  56. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/persona/product-owner.md.j2 +0 -0
  57. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/plan.bundle.yaml.j2 +0 -0
  58. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/policies/kanban.yaml +0 -0
  59. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/policies/mixed.yaml +0 -0
  60. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/policies/safe.yaml +0 -0
  61. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/policies/scrum.yaml +0 -0
  62. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/protocol.yaml.j2 +0 -0
  63. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/telemetry.yaml.example +0 -0
  64. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/__main__.py +0 -0
  65. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/__init__.py +0 -0
  66. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/ado.py +0 -0
  67. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/backlog_base.py +0 -0
  68. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/base.py +0 -0
  69. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/github.py +0 -0
  70. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/openspec.py +0 -0
  71. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/openspec_parser.py +0 -0
  72. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/registry.py +0 -0
  73. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/__init__.py +0 -0
  74. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/base.py +0 -0
  75. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/plan_agent.py +0 -0
  76. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/registry.py +0 -0
  77. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/sync_agent.py +0 -0
  78. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/__init__.py +0 -0
  79. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
  80. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
  81. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
  82. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
  83. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/__init__.py +0 -0
  84. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
  85. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/adapters/base.py +0 -0
  86. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/converter.py +0 -0
  87. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/filters.py +0 -0
  88. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
  89. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
  90. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/mappers/base.py +0 -0
  91. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
  92. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
  93. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/__init__.py +0 -0
  94. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/_bundle_shim.py +0 -0
  95. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/analyze.py +0 -0
  96. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/contract_cmd.py +0 -0
  97. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/drift.py +0 -0
  98. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/enforce.py +0 -0
  99. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/generate.py +0 -0
  100. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/import_cmd.py +0 -0
  101. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/init.py +0 -0
  102. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/migrate.py +0 -0
  103. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/plan.py +0 -0
  104. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/project_cmd.py +0 -0
  105. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/repro.py +0 -0
  106. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/sdd.py +0 -0
  107. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/spec.py +0 -0
  108. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/sync.py +0 -0
  109. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/update.py +0 -0
  110. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/validate.py +0 -0
  111. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/__init__.py +0 -0
  112. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/bundle_factory.py +0 -0
  113. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/logging_utils.py +0 -0
  114. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/text_utils.py +0 -0
  115. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/utils.py +0 -0
  116. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/comparators/__init__.py +0 -0
  117. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/comparators/plan_comparator.py +0 -0
  118. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/contracts/__init__.py +0 -0
  119. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/contracts/crosshair_props.py +0 -0
  120. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/contracts/module_interface.py +0 -0
  121. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
  122. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/__init__.py +0 -0
  123. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/contract_generator.py +0 -0
  124. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/openapi_extractor.py +0 -0
  125. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/protocol_generator.py +0 -0
  126. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/report_generator.py +0 -0
  127. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/task_generator.py +0 -0
  128. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/test_to_openapi.py +0 -0
  129. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/__init__.py +0 -0
  130. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/codebase_group.py +0 -0
  131. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/govern_group.py +0 -0
  132. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/member_group.py +0 -0
  133. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/project_group.py +0 -0
  134. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/spec_group.py +0 -0
  135. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/importers/__init__.py +0 -0
  136. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/importers/speckit_converter.py +0 -0
  137. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/importers/speckit_scanner.py +0 -0
  138. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/integrations/__init__.py +0 -0
  139. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/integrations/specmatic.py +0 -0
  140. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/merge/__init__.py +0 -0
  141. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/merge/resolver.py +0 -0
  142. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/migrations/__init__.py +0 -0
  143. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/migrations/plan_migrator.py +0 -0
  144. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/__init__.py +0 -0
  145. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/backlog_item.py +0 -0
  146. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/bridge.py +0 -0
  147. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/capabilities.py +0 -0
  148. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/change.py +0 -0
  149. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/contract.py +0 -0
  150. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/deviation.py +0 -0
  151. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/dor_config.py +0 -0
  152. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/enforcement.py +0 -0
  153. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/module_package.py +0 -0
  154. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/persona_template.py +0 -0
  155. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/plan.py +0 -0
  156. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/project.py +0 -0
  157. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/protocol.py +0 -0
  158. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/quality.py +0 -0
  159. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/sdd.py +0 -0
  160. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/source_tracking.py +0 -0
  161. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/task.py +0 -0
  162. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/validation.py +0 -0
  163. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modes/__init__.py +0 -0
  164. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modes/detector.py +0 -0
  165. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modes/router.py +0 -0
  166. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/__init__.py +0 -0
  167. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/init/src/__init__.py +0 -0
  168. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/init/src/app.py +0 -0
  169. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/module_registry/src/__init__.py +0 -0
  170. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/module_registry/src/app.py +0 -0
  171. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/upgrade/module-package.yaml +0 -0
  172. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/upgrade/src/__init__.py +0 -0
  173. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/upgrade/src/app.py +0 -0
  174. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/upgrade/src/commands.py +0 -0
  175. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/parsers/__init__.py +0 -0
  176. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/parsers/persona_importer.py +0 -0
  177. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/__init__.py +0 -0
  178. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/alias_manager.py +0 -0
  179. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/bridge_registry.py +0 -0
  180. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/crypto_validator.py +0 -0
  181. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/custom_registries.py +0 -0
  182. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/extension_registry.py +0 -0
  183. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/help_cache.py +0 -0
  184. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/marketplace_client.py +0 -0
  185. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/metadata.py +0 -0
  186. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_discovery.py +0 -0
  187. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_grouping.py +0 -0
  188. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_lifecycle.py +0 -0
  189. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_security.py +0 -0
  190. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_state.py +0 -0
  191. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/registry.py +0 -0
  192. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/resources/semgrep/async.yml +0 -0
  193. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
  194. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
  195. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/runtime.py +0 -0
  196. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/__init__.py +0 -0
  197. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_probe.py +0 -0
  198. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_openspec_md_parse.py +0 -0
  199. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_requirement_from_proposal.py +0 -0
  200. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_requirement_helpers.py +0 -0
  201. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_tasks_from_proposal.py +0 -0
  202. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_what_changes_format.py +0 -0
  203. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_write_openspec_from_proposal.py +0 -0
  204. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_watch.py +0 -0
  205. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/change_detector.py +0 -0
  206. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/code_to_spec.py +0 -0
  207. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/drift_detector.py +0 -0
  208. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/repository_sync.py +0 -0
  209. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/spec_to_tests.py +0 -0
  210. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/watcher.py +0 -0
  211. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
  212. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/telemetry.py +0 -0
  213. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/__init__.py +0 -0
  214. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
  215. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
  216. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
  217. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
  218. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
  219. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
  220. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
  221. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/registry.py +0 -0
  222. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/specification_templates.py +0 -0
  223. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/__init__.py +0 -0
  224. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
  225. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/auth_tokens.py +0 -0
  226. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/bundle_converters.py +0 -0
  227. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/bundle_loader.py +0 -0
  228. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/code_change_detector.py +0 -0
  229. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/console.py +0 -0
  230. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/content_sanitizer.py +0 -0
  231. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/contract_predicates.py +0 -0
  232. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/enrichment_context.py +0 -0
  233. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/enrichment_parser.py +0 -0
  234. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/env_manager.py +0 -0
  235. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/feature_keys.py +0 -0
  236. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/git.py +0 -0
  237. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/github_annotations.py +0 -0
  238. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/icontract_helpers.py +0 -0
  239. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/ide_setup.py +0 -0
  240. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/incremental_check.py +0 -0
  241. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/metadata.py +0 -0
  242. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/optional_deps.py +0 -0
  243. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/performance.py +0 -0
  244. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/persona_ownership.py +0 -0
  245. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/prompts.py +0 -0
  246. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/sdd_discovery.py +0 -0
  247. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/startup_checks.py +0 -0
  248. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/structured_io.py +0 -0
  249. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/suggestions.py +0 -0
  250. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/terminal.py +0 -0
  251. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/yaml_utils.py +0 -0
  252. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validation/__init__.py +0 -0
  253. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validation/command_audit.py +0 -0
  254. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/__init__.py +0 -0
  255. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/agile_validation.py +0 -0
  256. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
  257. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/cli_first_validator.py +0 -0
  258. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/contract_validator.py +0 -0
  259. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/fsm.py +0 -0
  260. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/repro_checker.py +0 -0
  261. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/schema.py +0 -0
  262. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
  263. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
  264. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
  265. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
  266. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
  267. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
  268. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
  269. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
  270. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
  271. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
  272. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
  273. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
  274. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/models.py +0 -0
  275. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
  276. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
  277. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/versioning/__init__.py +0 -0
  278. {specfact_cli-0.43.3 → specfact_cli-0.45.1}/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.43.3
3
+ Version: 0.45.1
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
@@ -224,30 +224,28 @@ Classifier: Topic :: Software Development :: Testing
224
224
  Requires-Python: >=3.11
225
225
  Requires-Dist: azure-identity>=1.17.1
226
226
  Requires-Dist: beartype>=0.22.4
227
- Requires-Dist: cffi>=1.17.1
228
- Requires-Dist: crosshair-tool>=0.0.97
229
227
  Requires-Dist: cryptography>=43.0.0
230
228
  Requires-Dist: gitpython>=3.1.45
231
229
  Requires-Dist: graphviz>=0.20.1
232
- Requires-Dist: hypothesis>=6.142.4
233
230
  Requires-Dist: icontract>=2.7.1
234
231
  Requires-Dist: jinja2>=3.1.6
235
232
  Requires-Dist: jsonschema>=4.23.0
236
233
  Requires-Dist: networkx>=3.4.2
237
234
  Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.27.0
238
235
  Requires-Dist: opentelemetry-sdk>=1.27.0
236
+ Requires-Dist: packaging>=24.0
239
237
  Requires-Dist: pydantic>=2.12.3
240
- Requires-Dist: python-dotenv>=1.2.1
241
238
  Requires-Dist: pyyaml>=6.0.3
242
239
  Requires-Dist: questionary>=2.0.1
243
- Requires-Dist: radon>=6.0.1
244
240
  Requires-Dist: requests>=2.32.3
245
241
  Requires-Dist: rich<13.6.0,>=13.5.2
246
242
  Requires-Dist: ruamel-yaml>=0.18.16
247
- Requires-Dist: ruff>=0.14.2
248
- Requires-Dist: typer>=0.20.0
243
+ Requires-Dist: typer<0.24,>=0.20.0
249
244
  Requires-Dist: typing-extensions>=4.15.0
250
245
  Requires-Dist: watchdog>=6.0.0
246
+ Provides-Extra: contracts
247
+ Requires-Dist: crosshair-tool>=0.0.97; extra == 'contracts'
248
+ Requires-Dist: hypothesis>=6.142.4; extra == 'contracts'
251
249
  Provides-Extra: dev
252
250
  Requires-Dist: basedpyright>=1.32.1; extra == 'dev'
253
251
  Requires-Dist: bearer>=3.1.0; extra == 'dev'
@@ -268,6 +266,7 @@ Requires-Dist: pytest>=8.4.2; extra == 'dev'
268
266
  Requires-Dist: radon>=6.0.1; extra == 'dev'
269
267
  Requires-Dist: ruff>=0.14.2; extra == 'dev'
270
268
  Requires-Dist: semgrep>=1.144.0; extra == 'dev'
269
+ Requires-Dist: setuptools>=69.0.0; extra == 'dev'
271
270
  Requires-Dist: tomlkit>=0.13.3; extra == 'dev'
272
271
  Requires-Dist: types-pyyaml>=6.0.12.20250516; extra == 'dev'
273
272
  Provides-Extra: enhanced-analysis
@@ -352,26 +351,40 @@ With SpecFact, you get:
352
351
 
353
352
  ## How do I get started?
354
353
 
355
- ### Start Here (5 minutes)
354
+ ### Start Here (about 2 minutes): scored code review — no `pip install`
356
355
 
357
- ### Install
356
+ **Point SpecFact at your code.** From a **git repository** (any branch), run two commands:
358
357
 
359
358
  ```bash
360
- # Zero-install (recommended)
361
- uvx specfact-cli@latest
362
-
363
- # Or install globally
364
- pip install -U specfact-cli
359
+ uvx specfact-cli init --profile solo-developer
360
+ uvx specfact-cli code review run --path . --scope full
365
361
  ```
366
362
 
367
- ### Bootstrap
363
+ You should see a **Verdict** (PASS/FAIL), a **Score**, and categorized **findings** — the fastest way to see SpecFact on real code before you dive into backlog, specs, or CI.
364
+
365
+ - **Command 1** installs the `solo-developer` bundles (including `specfact-codebase` and `specfact-code-review`) into your user module store so `code review` and related commands are available on the next invocation.
366
+ - **Command 2** runs the clean-code review on the repo at `.`. Use **`--scope full`** on the first run so review does not depend on having local git changes.
367
+
368
+ **Already installed the CLI?** Use the same flow with `specfact` instead of `uvx specfact-cli`:
368
369
 
369
370
  ```bash
370
- # Recommended first run
371
371
  specfact init --profile solo-developer
372
+ specfact code review run --path . --scope full
372
373
  ```
373
374
 
374
- ### Get First Value
375
+ **Read the canonical walkthrough:** **[Documentation — Quickstart](https://docs.specfact.io/getting-started/quickstart/)** · **[Installation](https://docs.specfact.io/getting-started/installation/)** (uvx-first, then persistent install).
376
+
377
+ ### Install (persistent CLI for daily use)
378
+
379
+ ```bash
380
+ pip install -U specfact-cli
381
+ ```
382
+
383
+ You can still use **`uvx specfact-cli@latest ...`** anytime without installing; it always fetches the latest published CLI.
384
+
385
+ ### After the wow path: deeper workflows
386
+
387
+ When you want analysis, snapshots, or sidecar validation on top of the review layer:
375
388
 
376
389
  ```bash
377
390
  # Analyze a codebase you care about
@@ -385,10 +398,7 @@ specfact code validate sidecar init my-project /path/to/repo
385
398
  specfact code validate sidecar run my-project /path/to/repo
386
399
  ```
387
400
 
388
- That path gives you a concrete first win: SpecFact understands your project context and gives you a
389
- validated starting point instead of jumping straight into blind change work.
390
-
391
- ### AI IDE Setup
401
+ ### AI IDE setup
392
402
 
393
403
  ```bash
394
404
  specfact init ide
@@ -406,7 +416,7 @@ your IDE. If module prompt payloads are not installed yet, the CLI uses packaged
406
416
  Use SpecFact as the validation layer around fast-moving implementation work.
407
417
 
408
418
  Start with:
409
- - `specfact init --profile solo-developer`
419
+ - `uvx specfact-cli init --profile solo-developer` then `uvx specfact-cli code review run --path . --scope full` (see **Start Here** above)
410
420
  - `specfact code validate sidecar init <bundle> /path/to/repo`
411
421
  - `specfact code validate sidecar run <bundle> /path/to/repo`
412
422
 
@@ -584,10 +594,11 @@ Use `https://modules.specfact.io/` for the in-depth backlog, project, spec, gove
584
594
 
585
595
  ## How It Works (High Level)
586
596
 
587
- 1. **Bootstrap**: install the CLI and initialize the official bundles you need.
588
- 2. **Analyze or sync**: import code, connect backlog systems, or sync external artifacts into project bundles.
589
- 3. **Validate**: run spec, governance, and sidecar validation flows before implementation or release.
590
- 4. **Iterate safely**: use module-provided workflows while the core runtime keeps command mounting, trust, and lifecycle consistent.
597
+ 1. **Bootstrap**: use **uvx** or **pip**, then `init --profile` to install the bundles you need (for example `solo-developer` for a scored **code review** first).
598
+ 2. **Review or analyze**: run **`code review run`** on a repo, or import code and snapshot state for deeper workflows.
599
+ 3. **Sync**: connect backlog systems or sync external artifacts into project bundles when you are ready.
600
+ 4. **Validate**: run spec, governance, and sidecar validation flows before implementation or release.
601
+ 5. **Iterate safely**: use module-provided workflows while the core runtime keeps command mounting, trust, and lifecycle consistent.
591
602
 
592
603
  ## Where SpecFact Fits
593
604
 
@@ -71,26 +71,40 @@ With SpecFact, you get:
71
71
 
72
72
  ## How do I get started?
73
73
 
74
- ### Start Here (5 minutes)
74
+ ### Start Here (about 2 minutes): scored code review — no `pip install`
75
75
 
76
- ### Install
76
+ **Point SpecFact at your code.** From a **git repository** (any branch), run two commands:
77
77
 
78
78
  ```bash
79
- # Zero-install (recommended)
80
- uvx specfact-cli@latest
81
-
82
- # Or install globally
83
- pip install -U specfact-cli
79
+ uvx specfact-cli init --profile solo-developer
80
+ uvx specfact-cli code review run --path . --scope full
84
81
  ```
85
82
 
86
- ### Bootstrap
83
+ You should see a **Verdict** (PASS/FAIL), a **Score**, and categorized **findings** — the fastest way to see SpecFact on real code before you dive into backlog, specs, or CI.
84
+
85
+ - **Command 1** installs the `solo-developer` bundles (including `specfact-codebase` and `specfact-code-review`) into your user module store so `code review` and related commands are available on the next invocation.
86
+ - **Command 2** runs the clean-code review on the repo at `.`. Use **`--scope full`** on the first run so review does not depend on having local git changes.
87
+
88
+ **Already installed the CLI?** Use the same flow with `specfact` instead of `uvx specfact-cli`:
87
89
 
88
90
  ```bash
89
- # Recommended first run
90
91
  specfact init --profile solo-developer
92
+ specfact code review run --path . --scope full
91
93
  ```
92
94
 
93
- ### Get First Value
95
+ **Read the canonical walkthrough:** **[Documentation — Quickstart](https://docs.specfact.io/getting-started/quickstart/)** · **[Installation](https://docs.specfact.io/getting-started/installation/)** (uvx-first, then persistent install).
96
+
97
+ ### Install (persistent CLI for daily use)
98
+
99
+ ```bash
100
+ pip install -U specfact-cli
101
+ ```
102
+
103
+ You can still use **`uvx specfact-cli@latest ...`** anytime without installing; it always fetches the latest published CLI.
104
+
105
+ ### After the wow path: deeper workflows
106
+
107
+ When you want analysis, snapshots, or sidecar validation on top of the review layer:
94
108
 
95
109
  ```bash
96
110
  # Analyze a codebase you care about
@@ -104,10 +118,7 @@ specfact code validate sidecar init my-project /path/to/repo
104
118
  specfact code validate sidecar run my-project /path/to/repo
105
119
  ```
106
120
 
107
- That path gives you a concrete first win: SpecFact understands your project context and gives you a
108
- validated starting point instead of jumping straight into blind change work.
109
-
110
- ### AI IDE Setup
121
+ ### AI IDE setup
111
122
 
112
123
  ```bash
113
124
  specfact init ide
@@ -125,7 +136,7 @@ your IDE. If module prompt payloads are not installed yet, the CLI uses packaged
125
136
  Use SpecFact as the validation layer around fast-moving implementation work.
126
137
 
127
138
  Start with:
128
- - `specfact init --profile solo-developer`
139
+ - `uvx specfact-cli init --profile solo-developer` then `uvx specfact-cli code review run --path . --scope full` (see **Start Here** above)
129
140
  - `specfact code validate sidecar init <bundle> /path/to/repo`
130
141
  - `specfact code validate sidecar run <bundle> /path/to/repo`
131
142
 
@@ -303,10 +314,11 @@ Use `https://modules.specfact.io/` for the in-depth backlog, project, spec, gove
303
314
 
304
315
  ## How It Works (High Level)
305
316
 
306
- 1. **Bootstrap**: install the CLI and initialize the official bundles you need.
307
- 2. **Analyze or sync**: import code, connect backlog systems, or sync external artifacts into project bundles.
308
- 3. **Validate**: run spec, governance, and sidecar validation flows before implementation or release.
309
- 4. **Iterate safely**: use module-provided workflows while the core runtime keeps command mounting, trust, and lifecycle consistent.
317
+ 1. **Bootstrap**: use **uvx** or **pip**, then `init --profile` to install the bundles you need (for example `solo-developer` for a scored **code review** first).
318
+ 2. **Review or analyze**: run **`code review run`** on a repo, or import code and snapshot state for deeper workflows.
319
+ 3. **Sync**: connect backlog systems or sync external artifacts into project bundles when you are ready.
320
+ 4. **Validate**: run spec, governance, and sidecar validation flows before implementation or release.
321
+ 5. **Iterate safely**: use module-provided workflows while the core runtime keeps command mounting, trust, and lifecycle consistent.
310
322
 
311
323
  ## Where SpecFact Fits
312
324
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "specfact-cli"
7
- version = "0.43.3"
7
+ version = "0.45.1"
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"
@@ -36,6 +36,10 @@ keywords = [
36
36
  "cli",
37
37
  "specfact",
38
38
  ]
39
+ # Install profiles (PEP 621 extras):
40
+ # - `pip install specfact-cli` — minimal runtime (CLI, registry, contracts via icontract/beartype, no CrossHair/Hypothesis wheels).
41
+ # - `pip install specfact-cli[contracts]` — add CrossHair + Hypothesis for contract exploration / property tooling.
42
+ # - `pip install specfact-cli[dev]` — contributors: pytest, linters, and same contract tools as [contracts] (see dev list).
39
43
  classifiers = [
40
44
  "Development Status :: 4 - Beta",
41
45
  "Intended Audience :: Developers",
@@ -51,16 +55,17 @@ classifiers = [
51
55
  dependencies = [
52
56
  # Core dependencies
53
57
  "pydantic>=2.12.3",
54
- "python-dotenv>=1.2.1",
55
58
  "typing-extensions>=4.15.0",
56
59
  "PyYAML>=6.0.3",
57
60
  "requests>=2.32.3",
58
61
  "azure-identity>=1.17.1",
59
62
  "cryptography>=43.0.0",
60
- "cffi>=1.17.1",
61
-
63
+ "packaging>=24.0",
64
+ # PEP 440 / markers for module installer and registry (do not rely on transitive pins only)
65
+
62
66
  # CLI framework
63
- "typer>=0.20.0",
67
+ # Typer 0.24+ requires click>=8.2.1 (generic Choice[...]); dev semgrep pins click~=8.1.8 — cap Typer.
68
+ "typer>=0.20.0,<0.24",
64
69
  "rich>=13.5.2,<13.6.0", # Compatible with semgrep (requires rich~=13.5.2)
65
70
  "questionary>=2.0.1", # Interactive prompts with arrow key navigation
66
71
 
@@ -80,16 +85,10 @@ dependencies = [
80
85
  # Schema validation
81
86
  "jsonschema>=4.23.0",
82
87
 
83
- # Contract-First Development Dependencies
88
+ # Contract-First (runtime decorators; exploration tools are optional extra `contracts`)
84
89
  "icontract>=2.7.1", # Design-by-contract decorators
85
90
  "beartype>=0.22.4", # Runtime type checking
86
- "crosshair-tool>=0.0.97", # Contract exploration and counterexample discovery
87
- "hypothesis>=6.142.4", # Property-based testing
88
-
89
- # Code analysis
90
- "ruff>=0.14.2",
91
- "radon>=6.0.1",
92
-
91
+
93
92
  # File system watching
94
93
  "watchdog>=6.0.0",
95
94
 
@@ -99,7 +98,13 @@ dependencies = [
99
98
  ]
100
99
 
101
100
  [project.optional-dependencies]
101
+ contracts = [
102
+ "crosshair-tool>=0.0.97",
103
+ "hypothesis>=6.142.4",
104
+ ]
105
+
102
106
  dev = [
107
+ "setuptools>=69.0.0",
103
108
  "pytest>=8.4.2",
104
109
  "pytest-cov>=7.0.0",
105
110
  "pytest-mock>=3.15.1",
@@ -114,12 +119,14 @@ dev = [
114
119
  "types-PyYAML>=6.0.12.20250516",
115
120
  "pip-tools>=7.5.1",
116
121
  "semgrep>=1.144.0", # Latest version compatible with rich~=13.5.2
117
-
118
- # Contract-First Development Dependencies (dev)
119
- "icontract>=2.7.1",
120
- "beartype>=0.22.4",
122
+
123
+ # Same contract exploration stack as [contracts] (extras cannot self-reference)
121
124
  "crosshair-tool>=0.0.97",
122
125
  "hypothesis>=6.142.4",
126
+
127
+ # Contract-First Development Dependencies (dev)
128
+ "icontract>=2.7.1",
129
+ "beartype>=0.22.4",
123
130
 
124
131
  # Enhanced Analysis Tools (for local development)
125
132
  # Note: syft excluded from dev/test due to rich version conflict with semgrep
@@ -165,12 +172,13 @@ specfact-cli = "specfact_cli.cli:cli_main" # Alias for uvx compatibility
165
172
  [tool.hatch.envs.default]
166
173
  python = "3.12"
167
174
  dependencies = [
175
+ # Semgrep pulls opentelemetry; some versions import pkg_resources (setuptools)
176
+ "setuptools>=69.0.0",
168
177
  "pip-tools",
169
178
  "pytest",
170
179
  "pytest-cov",
171
180
  "pytest-mock",
172
181
  "pytest-xdist",
173
- "python-dotenv",
174
182
  "pre-commit",
175
183
  # Ensure format/lint tools are available in the hatch env
176
184
  "isort>=7.0.0",
@@ -204,6 +212,9 @@ governance = "pylint src tests tools --reports=y --output-format=parseable"
204
212
  format = "ruff check . --fix && ruff format ."
205
213
 
206
214
  # Code scanning (Semgrep)
215
+ # Semgrep 1.38+ deprecated implicit .semgrep.yml discovery; always pass --config explicitly.
216
+ # Script must not be named `semgrep` (Hatch treats that as circular expansion with the semgrep CLI).
217
+ semgrep-full = "semgrep --config tools/semgrep {args}"
207
218
  scan = "semgrep --config tools/semgrep/async.yml {args}"
208
219
  scan-all = "semgrep --config tools/semgrep/async.yml ."
209
220
  scan-json = "semgrep --config tools/semgrep/async.yml --json . > logs/semgrep-results.json"
@@ -0,0 +1,200 @@
1
+ # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
2
+ # yamllint disable rule:line-length rule:truthy
3
+ # Generated workflow — aligns with current SpecFact CLI: non-interactive CI must run
4
+ # `specfact init --profile …` (or `specfact module install …`) before `specfact code …` commands.
5
+ name: SpecFact CLI Validation
6
+
7
+ on:
8
+ pull_request:
9
+ branches: [main, dev]
10
+ paths-ignore:
11
+ - "docs/**"
12
+ - "**.md"
13
+ - "**.mdc"
14
+ push:
15
+ branches: [main, dev]
16
+ paths-ignore:
17
+ - "docs/**"
18
+ - "**.md"
19
+ - "**.mdc"
20
+ workflow_dispatch:
21
+ inputs:
22
+ budget:
23
+ description: "Time budget in seconds for code repro"
24
+ required: false
25
+ default: "{{ budget }}"
26
+ type: string
27
+ mode:
28
+ description: "Enforcement mode (block, warn, log)"
29
+ required: false
30
+ default: "block"
31
+ type: choice
32
+ options:
33
+ - block
34
+ - warn
35
+ - log
36
+ version_check_mode:
37
+ description: "Project bundle version check (info, warn, block; skipped if no .specfact/projects)"
38
+ required: false
39
+ default: "info"
40
+ type: choice
41
+ options:
42
+ - info
43
+ - warn
44
+ - block
45
+ bundle_name:
46
+ description: "Project bundle name for `specfact project version check` (under .specfact/projects/)"
47
+ required: false
48
+ default: "{{ bundle_name }}"
49
+ type: string
50
+
51
+ jobs:
52
+ specfact-validation:
53
+ name: Contract Validation
54
+ runs-on: ubuntu-latest
55
+ permissions:
56
+ contents: read
57
+ pull-requests: write
58
+ checks: write
59
+ steps:
60
+ - name: Checkout
61
+ uses: actions/checkout@v4
62
+
63
+ - name: Set up Python
64
+ uses: actions/setup-python@v5
65
+ with:
66
+ python-version: "{{ python_version }}"
67
+ cache: "pip"
68
+
69
+ - name: Install SpecFact CLI
70
+ run: |
71
+ python -m pip install --upgrade pip
72
+ echo "📦 Installing SpecFact CLI..."
73
+ pip install specfact-cli
74
+
75
+ - name: Bootstrap SpecFact (CI — required for workflow commands)
76
+ run: |
77
+ # Non-interactive CI must pass --profile or --install (see `specfact init --help`).
78
+ specfact init --profile solo-developer --repo .
79
+
80
+ - name: Set validation parameters
81
+ id: validation
82
+ run: |
83
+ BUDGET="{% raw %}${{ github.event.inputs.budget || '{% endraw %}{{ budget }}{% raw %}' }}{% endraw %}"
84
+ MODE="{% raw %}${{ github.event.inputs.mode || 'block' }}{% endraw %}"
85
+ VERSION_CHECK_MODE="{% raw %}${{ github.event.inputs.version_check_mode || 'info' }}{% endraw %}"
86
+ BUNDLE_NAME="{% raw %}${{ github.event.inputs.bundle_name || '{% endraw %}{{ bundle_name }}{% raw %}' }}{% endraw %}"
87
+ echo "budget=$BUDGET" >> "$GITHUB_OUTPUT"
88
+ echo "mode=$MODE" >> "$GITHUB_OUTPUT"
89
+ echo "version_check_mode=$VERSION_CHECK_MODE" >> "$GITHUB_OUTPUT"
90
+ echo "bundle_name=$BUNDLE_NAME" >> "$GITHUB_OUTPUT"
91
+ echo "SPECFACT_BUDGET=$BUDGET" >> "$GITHUB_ENV"
92
+ echo "SPECFACT_MODE=$MODE" >> "$GITHUB_ENV"
93
+ echo "SPECFACT_VERSION_CHECK_MODE=$VERSION_CHECK_MODE" >> "$GITHUB_ENV"
94
+ echo "BUNDLE_NAME=$BUNDLE_NAME" >> "$GITHUB_ENV"
95
+
96
+ - name: Optional — CrossHair / repro tooling setup
97
+ continue-on-error: true
98
+ run: specfact code repro setup
99
+
100
+ - name: Run contract validation (code repro)
101
+ id: repro
102
+ continue-on-error: true
103
+ run: |
104
+ set +e
105
+ specfact code repro --verbose --budget "{% raw %}${{ steps.validation.outputs.budget }}{% endraw %}"
106
+ ec=$?
107
+ set -e
108
+ echo "exit_code=$ec" >> "$GITHUB_OUTPUT"
109
+
110
+ - name: Project bundle version check (optional)
111
+ id: version_check
112
+ continue-on-error: true
113
+ run: |
114
+ VERSION_CHECK_MODE="{% raw %}${{ steps.validation.outputs.version_check_mode }}{% endraw %}"
115
+ BUNDLE_NAME="{% raw %}${{ steps.validation.outputs.bundle_name }}{% endraw %}"
116
+ echo "📌 Bundle version check (mode: $VERSION_CHECK_MODE, bundle: $BUNDLE_NAME)..."
117
+ if [ ! -d .specfact/projects ]; then
118
+ echo "No .specfact/projects — skipping project version check."
119
+ echo "version_check_passed=skipped" >> "$GITHUB_OUTPUT"
120
+ exit 0
121
+ fi
122
+ if ! find .specfact/projects -mindepth 1 -maxdepth 1 -type d 2>/dev/null | grep -q .; then
123
+ echo "No project bundles under .specfact/projects — skipping."
124
+ echo "version_check_passed=skipped" >> "$GITHUB_OUTPUT"
125
+ exit 0
126
+ fi
127
+ if specfact project version check --repo . --bundle "$BUNDLE_NAME"; then
128
+ echo "version_check_passed=true" >> "$GITHUB_OUTPUT"
129
+ else
130
+ echo "version_check_passed=false" >> "$GITHUB_OUTPUT"
131
+ if [ "$VERSION_CHECK_MODE" = "warn" ]; then
132
+ echo "⚠️ Version check did not pass (warn mode — continuing)"
133
+ elif [ "$VERSION_CHECK_MODE" = "block" ]; then
134
+ echo "❌ Version check failed (block mode)"
135
+ exit 1
136
+ else
137
+ echo "ℹ️ Version check finished (info mode — continuing)"
138
+ fi
139
+ fi
140
+
141
+ - name: Find latest repro report
142
+ id: report
143
+ if: always()
144
+ run: |
145
+ REPORT_DIR=".specfact/reports/enforcement"
146
+ if [ -d "$REPORT_DIR" ]; then
147
+ LATEST_REPORT=$(find "$REPORT_DIR" -name "report-*.yaml" -type f -printf "%T@ %p\n" | sort -n | tail -1 | cut -d' ' -f2-)
148
+ if [ -n "$LATEST_REPORT" ]; then
149
+ echo "path=$LATEST_REPORT" >> "$GITHUB_OUTPUT"
150
+ echo "SPECFACT_REPORT_PATH=$LATEST_REPORT" >> "$GITHUB_ENV"
151
+ fi
152
+ fi
153
+
154
+ - name: Create GitHub annotations
155
+ id: annotations
156
+ if: {% raw %}${{ always() && steps.report.outputs.path != '' }}{% endraw %}
157
+ run: |
158
+ python -m specfact_cli.utils.github_annotations || true
159
+
160
+ - name: Generate PR comment
161
+ id: pr-comment
162
+ if: {% raw %}${{ always() && github.event_name == 'pull_request' && steps.report.outputs.path != '' }}{% endraw %}
163
+ run: |
164
+ python -m specfact_cli.utils.github_annotations
165
+ if [ -f ".specfact/pr-comment.md" ]; then
166
+ echo "comment_path=.specfact/pr-comment.md" >> "$GITHUB_OUTPUT"
167
+ fi
168
+
169
+ - name: Post PR comment
170
+ if: {% raw %}${{ always() && github.event_name == 'pull_request' && steps.pr-comment.outputs.comment_path != '' }}{% endraw %}
171
+ uses: actions/github-script@v7
172
+ with:
173
+ script: |
174
+ const fs = require('fs');
175
+ const commentPath = '{% raw %}${{ steps.pr-comment.outputs.comment_path }}{% endraw %}';
176
+ if (fs.existsSync(commentPath)) {
177
+ const comment = fs.readFileSync(commentPath, 'utf8');
178
+ github.rest.issues.createComment({
179
+ issue_number: context.issue.number,
180
+ owner: context.repo.owner,
181
+ repo: context.repo.repo,
182
+ body: comment
183
+ });
184
+ }
185
+
186
+ - name: Upload validation report
187
+ if: always()
188
+ uses: actions/upload-artifact@v4
189
+ with:
190
+ name: specfact-report
191
+ path: |
192
+ .specfact/reports/enforcement/*.yaml
193
+ .specfact/pr-comment.md
194
+ if-no-files-found: ignore
195
+
196
+ - name: Fail workflow if validation failed
197
+ if: {% raw %}${{ steps.repro.outputs.exit_code != '0' && steps.validation.outputs.mode == 'block' }}{% endraw %}
198
+ run: |
199
+ echo "❌ Validation failed. Exiting with error code."
200
+ exit 1
@@ -14,6 +14,15 @@
14
14
 
15
15
  ## ✅ Validation
16
16
 
17
+ **CI / local prerequisites (SpecFact v0.40+):**
18
+
19
+ - Install: `pip install specfact-cli` (or `uvx specfact-cli@latest` for one-off runs).
20
+ - **Non-interactive / CI** must bootstrap workflow bundles before `specfact code …` or `specfact project …`:
21
+ - `specfact init --profile solo-developer --repo .` (or another profile / `specfact init --install …`), **or**
22
+ - `specfact module install nold-ai/specfact-codebase` (and other bundles as needed).
23
+ - Contract repro in CI uses **`specfact code repro`** (not `specfact repro`). Optional: `specfact code repro setup` for CrossHair config.
24
+ - Optional `specfact project version check` needs a project under `.specfact/projects/<bundle>/` and `--bundle <name>`.
25
+
17
26
  **SpecFact CLI Validation Results:**
18
27
 
19
28
  {% if validation_passed %}
@@ -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.43.3"
6
+ __version__ = "0.45.1"
@@ -45,6 +45,6 @@ def _bootstrap_bundle_paths() -> None:
45
45
 
46
46
  _bootstrap_bundle_paths()
47
47
 
48
- __version__ = "0.43.3"
48
+ __version__ = "0.45.1"
49
49
 
50
50
  __all__ = ["__version__"]
@@ -426,7 +426,7 @@ class SpecKitAdapter(BridgeAdapter):
426
426
  )
427
427
  if title_match:
428
428
  feature_title = title_match.group(1).strip()
429
- except Exception:
429
+ except (OSError, UnicodeDecodeError):
430
430
  pass
431
431
  if not feature_title or feature_title.strip() == "":
432
432
  return "Unknown Feature"
@@ -262,7 +262,7 @@ Focus on semantic understanding, not just structural parsing. Generate the plan
262
262
  try:
263
263
  content = dep_file.read_text(encoding="utf-8")[:500]
264
264
  dependencies.append(f"{dep_file.name}: {content[:100]}...")
265
- except Exception:
265
+ except (OSError, UnicodeDecodeError):
266
266
  pass
267
267
  return dependencies
268
268
 
@@ -772,7 +772,7 @@ class AmbiguityScanner:
772
772
  continue
773
773
  if user_clean and len(user_clean) > 2 and user_lower not in excluded and len(user_clean.split()) <= 3:
774
774
  result.add(user_clean.title())
775
- except Exception:
775
+ except (OSError, UnicodeDecodeError, re.error):
776
776
  pass
777
777
  return result
778
778
 
@@ -898,9 +898,9 @@ class AmbiguityScanner:
898
898
  continue
899
899
  try:
900
900
  self._personas_from_py_file(py_file, result, excluded)
901
- except Exception:
901
+ except (OSError, UnicodeDecodeError, re.error):
902
902
  continue
903
- except Exception:
903
+ except (OSError, UnicodeDecodeError, re.error):
904
904
  pass
905
905
  return result
906
906
 
@@ -1794,14 +1794,14 @@ class CodeAnalyzer:
1794
1794
  for commit in commits:
1795
1795
  try:
1796
1796
  self._process_commit_for_feature_bounds(commit)
1797
- except Exception:
1797
+ except (OSError, ValueError):
1798
1798
  # Skip individual commits that fail (corrupted, etc.)
1799
1799
  continue
1800
1800
 
1801
1801
  except ImportError:
1802
1802
  # GitPython not available, skip
1803
1803
  pass
1804
- except Exception:
1804
+ except OSError:
1805
1805
  # Git operations failed, skip gracefully
1806
1806
  pass
1807
1807
 
@@ -240,7 +240,7 @@ class ContractExtractor:
240
240
  if hasattr(ast, "unparse"):
241
241
  try:
242
242
  return ast.unparse(node)
243
- except Exception:
243
+ except (ValueError, TypeError):
244
244
  pass
245
245
 
246
246
  # Fallback: manual conversion
@@ -282,7 +282,7 @@ class ContractExtractor:
282
282
  if hasattr(ast, "unparse"):
283
283
  try:
284
284
  return ast.unparse(node)
285
- except Exception:
285
+ except (ValueError, TypeError):
286
286
  pass
287
287
 
288
288
  return "..."
@@ -295,7 +295,7 @@ class ContractExtractor:
295
295
  if hasattr(ast, "unparse"):
296
296
  try:
297
297
  return ast.unparse(node)
298
- except Exception:
298
+ except (ValueError, TypeError):
299
299
  pass
300
300
 
301
301
  # Fallback: basic conversion