specfact-cli 0.25.1__tar.gz → 0.25.2__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 (215) hide show
  1. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/PKG-INFO +1 -1
  2. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/pyproject.toml +1 -1
  3. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/__init__.py +1 -1
  4. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/__init__.py +1 -1
  5. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/adapters/ado.py +32 -4
  6. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/adapters/github.py +40 -8
  7. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/bridge_sync.py +1582 -0
  8. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/.gitignore +0 -0
  9. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/LICENSE.md +0 -0
  10. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/README.md +0 -0
  11. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/mappings/node-async.yaml +0 -0
  12. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/mappings/python-async.yaml +0 -0
  13. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/mappings/speckit-default.yaml +0 -0
  14. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/shared/cli-enforcement.md +0 -0
  15. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/specfact.01-import.md +0 -0
  16. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/specfact.02-plan.md +0 -0
  17. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/specfact.03-review.md +0 -0
  18. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/specfact.04-sdd.md +0 -0
  19. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/specfact.05-enforce.md +0 -0
  20. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/specfact.06-sync.md +0 -0
  21. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/specfact.07-contracts.md +0 -0
  22. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/specfact.compare.md +0 -0
  23. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/specfact.sync-backlog.md +0 -0
  24. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/prompts/specfact.validate.md +0 -0
  25. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/schemas/deviation.schema.json +0 -0
  26. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/schemas/plan.schema.json +0 -0
  27. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/schemas/protocol.schema.json +0 -0
  28. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/github-action.yml.j2 +0 -0
  29. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/persona/architect.md.j2 +0 -0
  30. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/persona/developer.md.j2 +0 -0
  31. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/persona/product-owner.md.j2 +0 -0
  32. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/plan.bundle.yaml.j2 +0 -0
  33. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/pr-template.md.j2 +0 -0
  34. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/protocol.yaml.j2 +0 -0
  35. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/STRUCTURE.md +0 -0
  36. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/__init__.py +0 -0
  37. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/common/README.md +0 -0
  38. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/common/adapters.py +0 -0
  39. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/common/bindings.yaml.example +0 -0
  40. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/common/crosshair_plugin.py +0 -0
  41. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/common/generate_harness.py +0 -0
  42. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/common/harness_contracts.py.example +0 -0
  43. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/common/populate_contracts.py +0 -0
  44. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/common/run_sidecar.sh +0 -0
  45. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/common/sidecar-init.sh +0 -0
  46. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/frameworks/django/__init__.py +0 -0
  47. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/frameworks/django/crosshair_django_wrapper.py +0 -0
  48. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/frameworks/django/django_form_extractor.py +0 -0
  49. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/frameworks/django/django_url_extractor.py +0 -0
  50. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/frameworks/drf/__init__.py +0 -0
  51. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/frameworks/drf/drf_serializer_extractor.py +0 -0
  52. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/frameworks/fastapi/__init__.py +0 -0
  53. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/sidecar/frameworks/fastapi/fastapi_route_extractor.py +0 -0
  54. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/resources/templates/telemetry.yaml.example +0 -0
  55. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/adapters/__init__.py +0 -0
  56. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/adapters/backlog_base.py +0 -0
  57. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/adapters/base.py +0 -0
  58. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/adapters/openspec.py +0 -0
  59. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/adapters/openspec_parser.py +0 -0
  60. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/adapters/registry.py +0 -0
  61. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/adapters/speckit.py +0 -0
  62. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/agents/__init__.py +0 -0
  63. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/agents/analyze_agent.py +0 -0
  64. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/agents/base.py +0 -0
  65. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/agents/plan_agent.py +0 -0
  66. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/agents/registry.py +0 -0
  67. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/agents/sync_agent.py +0 -0
  68. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/analyzers/__init__.py +0 -0
  69. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
  70. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
  71. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
  72. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
  73. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
  74. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
  75. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
  76. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
  77. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
  78. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/cli.py +0 -0
  79. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/__init__.py +0 -0
  80. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/analyze.py +0 -0
  81. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/contract_cmd.py +0 -0
  82. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/drift.py +0 -0
  83. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/enforce.py +0 -0
  84. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/generate.py +0 -0
  85. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/import_cmd.py +0 -0
  86. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/init.py +0 -0
  87. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/migrate.py +0 -0
  88. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/plan.py +0 -0
  89. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/project_cmd.py +0 -0
  90. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/repro.py +0 -0
  91. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/sdd.py +0 -0
  92. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/spec.py +0 -0
  93. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/sync.py +0 -0
  94. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/commands/validate.py +0 -0
  95. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/common/__init__.py +0 -0
  96. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/common/logger_setup.py +0 -0
  97. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/common/logging_utils.py +0 -0
  98. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/common/text_utils.py +0 -0
  99. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/common/utils.py +0 -0
  100. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/comparators/__init__.py +0 -0
  101. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/comparators/plan_comparator.py +0 -0
  102. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
  103. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
  104. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/generators/__init__.py +0 -0
  105. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/generators/contract_generator.py +0 -0
  106. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/generators/openapi_extractor.py +0 -0
  107. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/generators/persona_exporter.py +0 -0
  108. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/generators/plan_generator.py +0 -0
  109. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/generators/protocol_generator.py +0 -0
  110. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/generators/report_generator.py +0 -0
  111. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/generators/task_generator.py +0 -0
  112. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/generators/test_to_openapi.py +0 -0
  113. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/generators/workflow_generator.py +0 -0
  114. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/importers/__init__.py +0 -0
  115. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/importers/speckit_converter.py +0 -0
  116. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/importers/speckit_scanner.py +0 -0
  117. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/integrations/__init__.py +0 -0
  118. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/integrations/specmatic.py +0 -0
  119. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/merge/__init__.py +0 -0
  120. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/merge/resolver.py +0 -0
  121. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/migrations/__init__.py +0 -0
  122. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/migrations/plan_migrator.py +0 -0
  123. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/__init__.py +0 -0
  124. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/bridge.py +0 -0
  125. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/capabilities.py +0 -0
  126. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/change.py +0 -0
  127. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/contract.py +0 -0
  128. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/deviation.py +0 -0
  129. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/enforcement.py +0 -0
  130. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/persona_template.py +0 -0
  131. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/plan.py +0 -0
  132. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/project.py +0 -0
  133. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/protocol.py +0 -0
  134. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/quality.py +0 -0
  135. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/sdd.py +0 -0
  136. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/source_tracking.py +0 -0
  137. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/models/task.py +0 -0
  138. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/modes/__init__.py +0 -0
  139. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/modes/detector.py +0 -0
  140. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/modes/router.py +0 -0
  141. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/parsers/__init__.py +0 -0
  142. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/parsers/persona_importer.py +0 -0
  143. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/resources/semgrep/async.yml +0 -0
  144. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
  145. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
  146. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/runtime.py +0 -0
  147. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/__init__.py +0 -0
  148. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/bridge_probe.py +0 -0
  149. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/bridge_watch.py +0 -0
  150. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/change_detector.py +0 -0
  151. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/code_to_spec.py +0 -0
  152. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/drift_detector.py +0 -0
  153. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/repository_sync.py +0 -0
  154. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/spec_to_code.py +0 -0
  155. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/spec_to_tests.py +0 -0
  156. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/watcher.py +0 -0
  157. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
  158. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/telemetry.py +0 -0
  159. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/templates/__init__.py +0 -0
  160. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/templates/bridge_templates.py +0 -0
  161. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/templates/specification_templates.py +0 -0
  162. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/__init__.py +0 -0
  163. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
  164. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/bundle_loader.py +0 -0
  165. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/code_change_detector.py +0 -0
  166. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/console.py +0 -0
  167. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/content_sanitizer.py +0 -0
  168. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/context_detection.py +0 -0
  169. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/enrichment_context.py +0 -0
  170. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/enrichment_parser.py +0 -0
  171. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/env_manager.py +0 -0
  172. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/feature_keys.py +0 -0
  173. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/git.py +0 -0
  174. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/github_annotations.py +0 -0
  175. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/ide_setup.py +0 -0
  176. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/incremental_check.py +0 -0
  177. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/optional_deps.py +0 -0
  178. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/performance.py +0 -0
  179. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/progress.py +0 -0
  180. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
  181. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/prompts.py +0 -0
  182. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/sdd_discovery.py +0 -0
  183. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/source_scanner.py +0 -0
  184. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/structure.py +0 -0
  185. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/structured_io.py +0 -0
  186. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/suggestions.py +0 -0
  187. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/terminal.py +0 -0
  188. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/utils/yaml_utils.py +0 -0
  189. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/__init__.py +0 -0
  190. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/agile_validation.py +0 -0
  191. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
  192. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/cli_first_validator.py +0 -0
  193. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/contract_validator.py +0 -0
  194. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/fsm.py +0 -0
  195. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/repro_checker.py +0 -0
  196. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/schema.py +0 -0
  197. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
  198. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
  199. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
  200. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
  201. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/dependency_installer.py +0 -0
  202. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
  203. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
  204. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
  205. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
  206. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
  207. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
  208. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
  209. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
  210. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/models.py +0 -0
  211. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/orchestrator.py +0 -0
  212. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
  213. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
  214. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/src/specfact_cli/versioning/__init__.py +0 -0
  215. {specfact_cli-0.25.1 → specfact_cli-0.25.2}/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.25.1
3
+ Version: 0.25.2
4
4
  Summary: Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions.
5
5
  Project-URL: Homepage, https://github.com/nold-ai/specfact-cli
6
6
  Project-URL: Repository, https://github.com/nold-ai/specfact-cli.git
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "specfact-cli"
7
- version = "0.25.1"
7
+ version = "0.25.2"
8
8
  description = "Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -3,4 +3,4 @@ SpecFact CLI - Spec→Contract→Sentinel tool for contract-driven development.
3
3
  """
4
4
 
5
5
  # Define the package version (kept in sync with pyproject.toml and setup.py)
6
- __version__ = "0.25.1"
6
+ __version__ = "0.25.2"
@@ -9,6 +9,6 @@ This package provides command-line tools for:
9
9
  - Validating reproducibility
10
10
  """
11
11
 
12
- __version__ = "0.25.1"
12
+ __version__ = "0.25.2"
13
13
 
14
14
  __all__ = ["__version__"]
@@ -210,12 +210,13 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin):
210
210
 
211
211
  description = ""
212
212
  rationale = ""
213
+ impact = ""
213
214
 
214
215
  # Parse markdown sections (Why, What Changes)
215
216
  if description_raw:
216
217
  # Extract "Why" section (stop at What Changes or OpenSpec footer)
217
218
  why_match = re.search(
218
- r"##\s+Why\s*\n(.*?)(?=\n##\s+What\s+Changes\s|\n---\s*\n\*OpenSpec Change Proposal:|\Z)",
219
+ r"##\s+Why\s*\n(.*?)(?=\n##\s+What\s+Changes\s|\n##\s+Impact\s|\n---\s*\n\*OpenSpec Change Proposal:|\Z)",
219
220
  description_raw,
220
221
  re.DOTALL | re.IGNORECASE,
221
222
  )
@@ -224,7 +225,7 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin):
224
225
 
225
226
  # Extract "What Changes" section (stop at OpenSpec footer)
226
227
  what_match = re.search(
227
- r"##\s+What\s+Changes\s*\n(.*?)(?=\n---\s*\n\*OpenSpec Change Proposal:|\Z)",
228
+ r"##\s+What\s+Changes\s*\n(.*?)(?=\n##\s+Impact\s|\n---\s*\n\*OpenSpec Change Proposal:|\Z)",
228
229
  description_raw,
229
230
  re.DOTALL | re.IGNORECASE,
230
231
  )
@@ -235,6 +236,14 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin):
235
236
  body_clean = re.sub(r"\n---\s*\n\*OpenSpec Change Proposal:.*", "", description_raw, flags=re.DOTALL)
236
237
  description = body_clean.strip()
237
238
 
239
+ impact_match = re.search(
240
+ r"##\s+Impact\s*\n(.*?)(?=\n---\s*\n\*OpenSpec Change Proposal:|\Z)",
241
+ description_raw,
242
+ re.DOTALL | re.IGNORECASE,
243
+ )
244
+ if impact_match:
245
+ impact = impact_match.group(1).strip()
246
+
238
247
  # Extract change ID from OpenSpec metadata footer or work item ID
239
248
  change_id = None
240
249
  if description_raw:
@@ -306,6 +315,7 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin):
306
315
  "title": title,
307
316
  "description": description,
308
317
  "rationale": rationale,
318
+ "impact": impact,
309
319
  "status": status,
310
320
  "created_at": created_at,
311
321
  "timeline": timeline,
@@ -1208,6 +1218,7 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin):
1208
1218
  title = proposal_data.get("title", "Untitled Change Proposal")
1209
1219
  description = proposal_data.get("description", "")
1210
1220
  rationale = proposal_data.get("rationale", "")
1221
+ impact = proposal_data.get("impact", "")
1211
1222
  status = proposal_data.get("status", "proposed")
1212
1223
  change_id = proposal_data.get("change_id", "unknown")
1213
1224
  raw_title, raw_body = self._extract_raw_fields(proposal_data)
@@ -1243,8 +1254,16 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin):
1243
1254
  body_parts.append(line)
1244
1255
  body_parts.append("") # Blank line
1245
1256
 
1257
+ if impact:
1258
+ body_parts.append("## Impact")
1259
+ body_parts.append("")
1260
+ impact_lines = impact.strip().split("\n")
1261
+ for line in impact_lines:
1262
+ body_parts.append(line)
1263
+ body_parts.append("")
1264
+
1246
1265
  # If no content, add placeholder
1247
- if not body_parts or (not rationale and not description):
1266
+ if not body_parts or (not rationale and not description and not impact):
1248
1267
  body_parts.append("No description provided.")
1249
1268
  body_parts.append("")
1250
1269
 
@@ -1450,6 +1469,7 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin):
1450
1469
  title = proposal_data.get("title", "Untitled Change Proposal")
1451
1470
  description = proposal_data.get("description", "")
1452
1471
  rationale = proposal_data.get("rationale", "")
1472
+ impact = proposal_data.get("impact", "")
1453
1473
  status = proposal_data.get("status", "proposed")
1454
1474
  change_id = proposal_data.get("change_id", "unknown")
1455
1475
  raw_title, raw_body = self._extract_raw_fields(proposal_data)
@@ -1485,8 +1505,16 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin):
1485
1505
  body_parts.append(line)
1486
1506
  body_parts.append("") # Blank line
1487
1507
 
1508
+ if impact:
1509
+ body_parts.append("## Impact")
1510
+ body_parts.append("")
1511
+ impact_lines = impact.strip().split("\n")
1512
+ for line in impact_lines:
1513
+ body_parts.append(line)
1514
+ body_parts.append("")
1515
+
1488
1516
  # If no content, add placeholder
1489
- if not body_parts or (not rationale and not description):
1517
+ if not body_parts or (not rationale and not description and not impact):
1490
1518
  body_parts.append("No description provided.")
1491
1519
  body_parts.append("")
1492
1520
 
@@ -225,12 +225,13 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin):
225
225
  body = item_data.get("body", "") or ""
226
226
  description = ""
227
227
  rationale = ""
228
+ impact = ""
228
229
 
229
230
  # Parse markdown sections (Why, What Changes)
230
231
  if body:
231
232
  # Extract "Why" section (stop at What Changes or OpenSpec footer)
232
233
  why_match = re.search(
233
- r"##\s+Why\s*\n(.*?)(?=\n##\s+What\s+Changes\s|\n---\s*\n\*OpenSpec Change Proposal:|\Z)",
234
+ r"##\s+Why\s*\n(.*?)(?=\n##\s+What\s+Changes\s|\n##\s+Impact\s|\n---\s*\n\*OpenSpec Change Proposal:|\Z)",
234
235
  body,
235
236
  re.DOTALL | re.IGNORECASE,
236
237
  )
@@ -239,7 +240,7 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin):
239
240
 
240
241
  # Extract "What Changes" section (stop at OpenSpec footer)
241
242
  what_match = re.search(
242
- r"##\s+What\s+Changes\s*\n(.*?)(?=\n---\s*\n\*OpenSpec Change Proposal:|\Z)",
243
+ r"##\s+What\s+Changes\s*\n(.*?)(?=\n##\s+Impact\s|\n---\s*\n\*OpenSpec Change Proposal:|\Z)",
243
244
  body,
244
245
  re.DOTALL | re.IGNORECASE,
245
246
  )
@@ -250,6 +251,14 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin):
250
251
  body_clean = re.sub(r"\n---\s*\n\*OpenSpec Change Proposal:.*", "", body, flags=re.DOTALL)
251
252
  description = body_clean.strip()
252
253
 
254
+ impact_match = re.search(
255
+ r"##\s+Impact\s*\n(.*?)(?=\n---\s*\n\*OpenSpec Change Proposal:|\Z)",
256
+ body,
257
+ re.DOTALL | re.IGNORECASE,
258
+ )
259
+ if impact_match:
260
+ impact = impact_match.group(1).strip()
261
+
253
262
  # Extract change ID from OpenSpec metadata footer or issue number
254
263
  change_id = None
255
264
  if body:
@@ -330,6 +339,7 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin):
330
339
  "title": title,
331
340
  "description": description,
332
341
  "rationale": rationale,
342
+ "impact": impact,
333
343
  "status": status,
334
344
  "created_at": created_at,
335
345
  "timeline": timeline,
@@ -922,6 +932,7 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin):
922
932
  title = proposal_data.get("title", "Untitled Change Proposal")
923
933
  description = proposal_data.get("description", "")
924
934
  rationale = proposal_data.get("rationale", "")
935
+ impact = proposal_data.get("impact", "")
925
936
  status = proposal_data.get("status", "proposed")
926
937
  change_id = proposal_data.get("change_id", "unknown")
927
938
  raw_title, raw_body = self._extract_raw_fields(proposal_data)
@@ -959,14 +970,24 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin):
959
970
  body_parts.append(line)
960
971
  body_parts.append("") # Blank line
961
972
 
973
+ # Add Impact section if present
974
+ if impact:
975
+ body_parts.append("## Impact")
976
+ body_parts.append("")
977
+ impact_lines = impact.strip().split("\n")
978
+ for line in impact_lines:
979
+ body_parts.append(line)
980
+ body_parts.append("")
981
+
962
982
  # If no content, add placeholder
963
983
  if not body_parts or (not rationale and not description):
964
984
  body_parts.append("No description provided.")
965
985
  body_parts.append("")
966
986
 
967
- # Add OpenSpec metadata footer
968
- body_parts.append("---")
969
- body_parts.append(f"*OpenSpec Change Proposal: `{change_id}`*")
987
+ # Add OpenSpec metadata footer (avoid duplicates)
988
+ if not any("OpenSpec Change Proposal:" in line for line in body_parts):
989
+ body_parts.append("---")
990
+ body_parts.append(f"*OpenSpec Change Proposal: `{change_id}`*")
970
991
 
971
992
  body = "\n".join(body_parts)
972
993
 
@@ -1172,6 +1193,7 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin):
1172
1193
  title = proposal_data.get("title", "Untitled Change Proposal")
1173
1194
  description = proposal_data.get("description", "")
1174
1195
  rationale = proposal_data.get("rationale", "")
1196
+ impact = proposal_data.get("impact", "")
1175
1197
  change_id = proposal_data.get("change_id", "unknown")
1176
1198
  status = proposal_data.get("status", "proposed")
1177
1199
  raw_title, raw_body = self._extract_raw_fields(proposal_data)
@@ -1238,6 +1260,15 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin):
1238
1260
  body_parts.append(line)
1239
1261
  body_parts.append("") # Blank line
1240
1262
 
1263
+ # Add Impact section if present
1264
+ if impact:
1265
+ body_parts.append("## Impact")
1266
+ body_parts.append("")
1267
+ impact_lines = impact.strip().split("\n")
1268
+ for line in impact_lines:
1269
+ body_parts.append(line)
1270
+ body_parts.append("") # Blank line
1271
+
1241
1272
  # If no content, add placeholder
1242
1273
  if not body_parts or (not rationale and not description):
1243
1274
  body_parts.append("No description provided.")
@@ -1252,9 +1283,10 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin):
1252
1283
  body_parts.append("") # Blank line before preserved section
1253
1284
  body_parts.append(preserved_clean)
1254
1285
 
1255
- # Add OpenSpec metadata footer
1256
- body_parts.append("---")
1257
- body_parts.append(f"*OpenSpec Change Proposal: `{change_id}`*")
1286
+ # Add OpenSpec metadata footer (avoid duplicates)
1287
+ if not any("OpenSpec Change Proposal:" in line for line in body_parts):
1288
+ body_parts.append("---")
1289
+ body_parts.append(f"*OpenSpec Change Proposal: `{change_id}`*")
1258
1290
 
1259
1291
  body = "\n".join(body_parts)
1260
1292