specify-cli 0.12.5__tar.gz → 0.12.6__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 (456) hide show
  1. {specify_cli-0.12.5 → specify_cli-0.12.6}/CHANGELOG.md +15 -0
  2. {specify_cli-0.12.5 → specify_cli-0.12.6}/PKG-INFO +1 -1
  3. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/extensions.md +1 -0
  4. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/catalog.community.json +45 -6
  5. {specify_cli-0.12.5 → specify_cli-0.12.6}/pyproject.toml +1 -1
  6. specify_cli-0.12.6/scripts/python/check_prerequisites.py +207 -0
  7. specify_cli-0.12.6/scripts/python/common.py +210 -0
  8. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/agents.py +47 -12
  9. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/commands_impl/catalog_config.py +23 -2
  10. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/extensions/__init__.py +12 -3
  11. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/base.py +8 -2
  12. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/hermes/__init__.py +5 -0
  13. specify_cli-0.12.6/tests/integrations/conftest.py +38 -0
  14. specify_cli-0.12.6/tests/integrations/test_home_isolation.py +21 -0
  15. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_base_yaml.py +17 -0
  16. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_hermes.py +35 -0
  17. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_registry.py +81 -54
  18. specify_cli-0.12.6/tests/test_check_prerequisites_python_parity.py +339 -0
  19. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_extension_skills.py +61 -0
  20. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_extensions.py +94 -0
  21. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_catalog_config.py +36 -0
  22. specify_cli-0.12.5/tests/integrations/conftest.py +0 -22
  23. {specify_cli-0.12.5 → specify_cli-0.12.6}/.devcontainer/devcontainer.json +0 -0
  24. {specify_cli-0.12.5 → specify_cli-0.12.6}/.devcontainer/post-create.sh +0 -0
  25. {specify_cli-0.12.5 → specify_cli-0.12.6}/.editorconfig +0 -0
  26. {specify_cli-0.12.5 → specify_cli-0.12.6}/.gitattributes +0 -0
  27. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/CODEOWNERS +0 -0
  28. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/agent_request.yml +0 -0
  29. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  30. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/bundle_submission.yml +0 -0
  31. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  32. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/extension_submission.yml +0 -0
  33. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  34. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/preset_submission.yml +0 -0
  35. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  36. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/aw/actions-lock.json +0 -0
  37. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/dependabot.yml +0 -0
  38. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/skills/add-community-extension/SKILL.md +0 -0
  39. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/RELEASE-PROCESS.md +0 -0
  40. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/add-community-extension.lock.yml +0 -0
  41. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/add-community-extension.md +0 -0
  42. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/add-community-preset.lock.yml +0 -0
  43. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/add-community-preset.md +0 -0
  44. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-assess.lock.yml +0 -0
  45. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-assess.md +0 -0
  46. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-fix.lock.yml +0 -0
  47. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-fix.md +0 -0
  48. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-test.lock.yml +0 -0
  49. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-test.md +0 -0
  50. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/catalog-assign.yml +0 -0
  51. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/codeql.yml +0 -0
  52. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/docs.yml +0 -0
  53. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/lint.yml +0 -0
  54. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/publish-pypi.yml +0 -0
  55. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/release-trigger.yml +0 -0
  56. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/release.yml +0 -0
  57. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/stale.yml +0 -0
  58. {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/test.yml +0 -0
  59. {specify_cli-0.12.5 → specify_cli-0.12.6}/.gitignore +0 -0
  60. {specify_cli-0.12.5 → specify_cli-0.12.6}/.markdownlint-cli2.jsonc +0 -0
  61. {specify_cli-0.12.5 → specify_cli-0.12.6}/.zenodo.json +0 -0
  62. {specify_cli-0.12.5 → specify_cli-0.12.6}/AGENTS.md +0 -0
  63. {specify_cli-0.12.5 → specify_cli-0.12.6}/CITATION.cff +0 -0
  64. {specify_cli-0.12.5 → specify_cli-0.12.6}/CODE_OF_CONDUCT.md +0 -0
  65. {specify_cli-0.12.5 → specify_cli-0.12.6}/CONTRIBUTING.md +0 -0
  66. {specify_cli-0.12.5 → specify_cli-0.12.6}/DEVELOPMENT.md +0 -0
  67. {specify_cli-0.12.5 → specify_cli-0.12.6}/LICENSE +0 -0
  68. {specify_cli-0.12.5 → specify_cli-0.12.6}/README.md +0 -0
  69. {specify_cli-0.12.5 → specify_cli-0.12.6}/SECURITY.md +0 -0
  70. {specify_cli-0.12.5 → specify_cli-0.12.6}/SUPPORT.md +0 -0
  71. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/.gitignore +0 -0
  72. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/README.md +0 -0
  73. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/bundles.md +0 -0
  74. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/friends.md +0 -0
  75. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/overview.md +0 -0
  76. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/presets.md +0 -0
  77. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/walkthroughs.md +0 -0
  78. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/concepts/complex-features.md +0 -0
  79. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/concepts/sdd.md +0 -0
  80. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/concepts/spec-persistence.md +0 -0
  81. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/docfx.json +0 -0
  82. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/guides/evolving-specs.md +0 -0
  83. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/guides/monorepo.md +0 -0
  84. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/index.md +0 -0
  85. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/install/air-gapped.md +0 -0
  86. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/install/one-time.md +0 -0
  87. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/install/pipx.md +0 -0
  88. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/install/uv.md +0 -0
  89. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/installation.md +0 -0
  90. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/local-development.md +0 -0
  91. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/quickstart.md +0 -0
  92. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/authentication.md +0 -0
  93. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/bundles.md +0 -0
  94. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/core.md +0 -0
  95. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/extensions.md +0 -0
  96. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/integrations.md +0 -0
  97. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/overview.md +0 -0
  98. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/presets.md +0 -0
  99. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/workflows.md +0 -0
  100. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/template/public/main.css +0 -0
  101. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/toc.yml +0 -0
  102. {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/upgrade.md +0 -0
  103. {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/business-analyst/README.md +0 -0
  104. {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/business-analyst/bundle.yml +0 -0
  105. {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/developer/README.md +0 -0
  106. {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/developer/bundle.yml +0 -0
  107. {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/product-manager/README.md +0 -0
  108. {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/product-manager/bundle.yml +0 -0
  109. {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/security-researcher/README.md +0 -0
  110. {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/security-researcher/bundle.yml +0 -0
  111. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/EXTENSION-API-REFERENCE.md +0 -0
  112. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/EXTENSION-DEVELOPMENT-GUIDE.md +0 -0
  113. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/EXTENSION-PUBLISHING-GUIDE.md +0 -0
  114. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/EXTENSION-USER-GUIDE.md +0 -0
  115. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/README.md +0 -0
  116. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/RFC-EXTENSION-SYSTEM.md +0 -0
  117. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/README.md +0 -0
  118. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/agent-context-config.yml +0 -0
  119. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/agent-context-defaults.json +0 -0
  120. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/commands/speckit.agent-context.update.md +0 -0
  121. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/extension.yml +0 -0
  122. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/scripts/bash/update-agent-context.sh +0 -0
  123. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +0 -0
  124. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/bug/README.md +0 -0
  125. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/bug/commands/speckit.bug.assess.md +0 -0
  126. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/bug/commands/speckit.bug.fix.md +0 -0
  127. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/bug/commands/speckit.bug.test.md +0 -0
  128. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/bug/extension.yml +0 -0
  129. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/catalog.json +0 -0
  130. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/README.md +0 -0
  131. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/commands/speckit.git.commit.md +0 -0
  132. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/commands/speckit.git.feature.md +0 -0
  133. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/commands/speckit.git.initialize.md +0 -0
  134. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/commands/speckit.git.remote.md +0 -0
  135. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/commands/speckit.git.validate.md +0 -0
  136. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/config-template.yml +0 -0
  137. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/extension.yml +0 -0
  138. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/git-config.yml +0 -0
  139. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/bash/auto-commit.sh +0 -0
  140. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/bash/create-new-feature-branch.sh +0 -0
  141. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/bash/git-common.sh +0 -0
  142. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/bash/initialize-repo.sh +0 -0
  143. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
  144. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/powershell/create-new-feature-branch.ps1 +0 -0
  145. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/powershell/git-common.ps1 +0 -0
  146. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
  147. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/selftest/commands/selftest.md +0 -0
  148. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/selftest/extension.yml +0 -0
  149. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/.gitignore +0 -0
  150. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/CHANGELOG.md +0 -0
  151. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/EXAMPLE-README.md +0 -0
  152. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/LICENSE +0 -0
  153. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/README.md +0 -0
  154. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/commands/example.md +0 -0
  155. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/config-template.yml +0 -0
  156. {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/extension.yml +0 -0
  157. {specify_cli-0.12.5 → specify_cli-0.12.6}/integrations/CONTRIBUTING.md +0 -0
  158. {specify_cli-0.12.5 → specify_cli-0.12.6}/integrations/README.md +0 -0
  159. {specify_cli-0.12.5 → specify_cli-0.12.6}/integrations/catalog.community.json +0 -0
  160. {specify_cli-0.12.5 → specify_cli-0.12.6}/integrations/catalog.json +0 -0
  161. {specify_cli-0.12.5 → specify_cli-0.12.6}/media/bootstrap-claude-code.gif +0 -0
  162. {specify_cli-0.12.5 → specify_cli-0.12.6}/media/logo_large.webp +0 -0
  163. {specify_cli-0.12.5 → specify_cli-0.12.6}/media/logo_small.webp +0 -0
  164. {specify_cli-0.12.5 → specify_cli-0.12.6}/media/spec-kit-video-header.jpg +0 -0
  165. {specify_cli-0.12.5 → specify_cli-0.12.6}/media/specify_cli.gif +0 -0
  166. {specify_cli-0.12.5 → specify_cli-0.12.6}/newsletters/2026-April.md +0 -0
  167. {specify_cli-0.12.5 → specify_cli-0.12.6}/newsletters/2026-February.md +0 -0
  168. {specify_cli-0.12.5 → specify_cli-0.12.6}/newsletters/2026-June.md +0 -0
  169. {specify_cli-0.12.5 → specify_cli-0.12.6}/newsletters/2026-March.md +0 -0
  170. {specify_cli-0.12.5 → specify_cli-0.12.6}/newsletters/2026-May.md +0 -0
  171. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/ARCHITECTURE.md +0 -0
  172. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/PUBLISHING.md +0 -0
  173. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/README.md +0 -0
  174. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/catalog.community.json +0 -0
  175. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/catalog.json +0 -0
  176. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/README.md +0 -0
  177. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/commands/speckit.constitution.md +0 -0
  178. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/commands/speckit.implement.md +0 -0
  179. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/commands/speckit.plan.md +0 -0
  180. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/commands/speckit.specify.md +0 -0
  181. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/commands/speckit.tasks.md +0 -0
  182. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/preset.yml +0 -0
  183. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/README.md +0 -0
  184. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/commands/speckit.myext.myextcmd.md +0 -0
  185. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/commands/speckit.specify.md +0 -0
  186. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/preset.yml +0 -0
  187. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/templates/myext-template.md +0 -0
  188. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/templates/spec-template.md +0 -0
  189. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/commands/speckit.specify.md +0 -0
  190. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/commands/speckit.wrap-test.md +0 -0
  191. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/preset.yml +0 -0
  192. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/agent-file-template.md +0 -0
  193. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/checklist-template.md +0 -0
  194. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/constitution-template.md +0 -0
  195. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/plan-template.md +0 -0
  196. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/spec-template.md +0 -0
  197. {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/tasks-template.md +0 -0
  198. {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/bash/check-prerequisites.sh +0 -0
  199. {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/bash/common.sh +0 -0
  200. {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/bash/create-new-feature.sh +0 -0
  201. {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/bash/setup-plan.sh +0 -0
  202. {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/bash/setup-tasks.sh +0 -0
  203. {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/powershell/check-prerequisites.ps1 +0 -0
  204. {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/powershell/common.ps1 +0 -0
  205. {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/powershell/create-new-feature.ps1 +0 -0
  206. {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/powershell/setup-plan.ps1 +0 -0
  207. {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/powershell/setup-tasks.ps1 +0 -0
  208. {specify_cli-0.12.5 → specify_cli-0.12.6}/spec-driven.md +0 -0
  209. {specify_cli-0.12.5 → specify_cli-0.12.6}/spec-kit.code-workspace +0 -0
  210. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/__init__.py +0 -0
  211. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_agent_config.py +0 -0
  212. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_assets.py +0 -0
  213. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_console.py +0 -0
  214. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_github_http.py +0 -0
  215. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_init_options.py +0 -0
  216. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_invocation_style.py +0 -0
  217. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_project.py +0 -0
  218. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_utils.py +0 -0
  219. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_version.py +0 -0
  220. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/__init__.py +0 -0
  221. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/azure_devops.py +0 -0
  222. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/base.py +0 -0
  223. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/config.py +0 -0
  224. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/github.py +0 -0
  225. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/http.py +0 -0
  226. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/__init__.py +0 -0
  227. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/commands_impl/__init__.py +0 -0
  228. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/lib/__init__.py +0 -0
  229. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/lib/project.py +0 -0
  230. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/lib/versioning.py +0 -0
  231. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/lib/yamlio.py +0 -0
  232. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/models/__init__.py +0 -0
  233. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/models/catalog.py +0 -0
  234. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/models/manifest.py +0 -0
  235. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/models/records.py +0 -0
  236. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/__init__.py +0 -0
  237. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/adapters.py +0 -0
  238. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/catalog_stack.py +0 -0
  239. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/conflict.py +0 -0
  240. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/installer.py +0 -0
  241. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/packager.py +0 -0
  242. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/primitives.py +0 -0
  243. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/references.py +0 -0
  244. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/resolver.py +0 -0
  245. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/validator.py +0 -0
  246. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/catalogs.py +0 -0
  247. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/commands/__init__.py +0 -0
  248. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/commands/bundle/__init__.py +0 -0
  249. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/commands/init.py +0 -0
  250. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/extensions/_commands.py +0 -0
  251. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integration_runtime.py +0 -0
  252. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integration_scaffold.py +0 -0
  253. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integration_state.py +0 -0
  254. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integration_status.py +0 -0
  255. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/__init__.py +0 -0
  256. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_commands.py +0 -0
  257. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_helpers.py +0 -0
  258. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_install_commands.py +0 -0
  259. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_migrate_commands.py +0 -0
  260. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_query_commands.py +0 -0
  261. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_scaffold_commands.py +0 -0
  262. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/agy/__init__.py +0 -0
  263. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/amp/__init__.py +0 -0
  264. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/auggie/__init__.py +0 -0
  265. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/bob/__init__.py +0 -0
  266. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/catalog.py +0 -0
  267. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/claude/__init__.py +0 -0
  268. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/cline/__init__.py +0 -0
  269. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/codebuddy/__init__.py +0 -0
  270. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/codex/__init__.py +0 -0
  271. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/copilot/__init__.py +0 -0
  272. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/cursor_agent/__init__.py +0 -0
  273. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/devin/__init__.py +0 -0
  274. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/firebender/__init__.py +0 -0
  275. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/forge/__init__.py +0 -0
  276. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/gemini/__init__.py +0 -0
  277. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/generic/__init__.py +0 -0
  278. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/goose/__init__.py +0 -0
  279. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/junie/__init__.py +0 -0
  280. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/kilocode/__init__.py +0 -0
  281. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/kimi/__init__.py +0 -0
  282. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/kiro_cli/__init__.py +0 -0
  283. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/lingma/__init__.py +0 -0
  284. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/manifest.py +0 -0
  285. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/omp/__init__.py +0 -0
  286. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/opencode/__init__.py +0 -0
  287. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/pi/__init__.py +0 -0
  288. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/qodercli/__init__.py +0 -0
  289. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/qwen/__init__.py +0 -0
  290. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/rovodev/__init__.py +0 -0
  291. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/shai/__init__.py +0 -0
  292. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/tabnine/__init__.py +0 -0
  293. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/trae/__init__.py +0 -0
  294. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/vibe/__init__.py +0 -0
  295. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/zcode/__init__.py +0 -0
  296. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/zed/__init__.py +0 -0
  297. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/presets/__init__.py +0 -0
  298. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/presets/_commands.py +0 -0
  299. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/shared_infra.py +0 -0
  300. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/__init__.py +0 -0
  301. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/_commands.py +0 -0
  302. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/base.py +0 -0
  303. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/catalog.py +0 -0
  304. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/engine.py +0 -0
  305. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/expressions.py +0 -0
  306. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/__init__.py +0 -0
  307. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/command/__init__.py +0 -0
  308. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/do_while/__init__.py +0 -0
  309. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/fan_in/__init__.py +0 -0
  310. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/fan_out/__init__.py +0 -0
  311. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/gate/__init__.py +0 -0
  312. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/if_then/__init__.py +0 -0
  313. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/init/__init__.py +0 -0
  314. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/prompt/__init__.py +0 -0
  315. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/shell/__init__.py +0 -0
  316. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/switch/__init__.py +0 -0
  317. {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/while_loop/__init__.py +0 -0
  318. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/checklist-template.md +0 -0
  319. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/analyze.md +0 -0
  320. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/checklist.md +0 -0
  321. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/clarify.md +0 -0
  322. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/constitution.md +0 -0
  323. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/converge.md +0 -0
  324. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/implement.md +0 -0
  325. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/plan.md +0 -0
  326. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/specify.md +0 -0
  327. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/tasks.md +0 -0
  328. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/taskstoissues.md +0 -0
  329. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/constitution-template.md +0 -0
  330. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/plan-template.md +0 -0
  331. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/spec-template.md +0 -0
  332. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/tasks-template.md +0 -0
  333. {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/vscode-settings.json +0 -0
  334. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/__init__.py +0 -0
  335. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/auth_helpers.py +0 -0
  336. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/bundler_helpers.py +0 -0
  337. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/conftest.py +0 -0
  338. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/contract/test_bundle_cli.py +0 -0
  339. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/contract/test_catalog_schema.py +0 -0
  340. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/contract/test_manifest_schema.py +0 -0
  341. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/__init__.py +0 -0
  342. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/bug/__init__.py +0 -0
  343. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/bug/test_bug_extension.py +0 -0
  344. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/git/__init__.py +0 -0
  345. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/git/test_git_extension.py +0 -0
  346. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/test_agent_context_cli_free.py +0 -0
  347. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/test_extension_agent_context.py +0 -0
  348. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/test_update_agent_context_feature_json.py +0 -0
  349. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/hooks/TESTING.md +0 -0
  350. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/hooks/plan.md +0 -0
  351. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/hooks/spec.md +0 -0
  352. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/hooks/tasks.md +0 -0
  353. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/http_helpers.py +0 -0
  354. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_catalog_stack.py +0 -0
  355. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_init_install.py +0 -0
  356. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_install_flow.py +0 -0
  357. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_local_install.py +0 -0
  358. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_offline.py +0 -0
  359. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_security_paths.py +0 -0
  360. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/__init__.py +0 -0
  361. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_base.py +0 -0
  362. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_cli.py +0 -0
  363. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_extra_args.py +0 -0
  364. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_agy.py +0 -0
  365. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_amp.py +0 -0
  366. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_auggie.py +0 -0
  367. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_base_markdown.py +0 -0
  368. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_base_skills.py +0 -0
  369. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_base_toml.py +0 -0
  370. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_bob.py +0 -0
  371. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_catalog.py +0 -0
  372. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_claude.py +0 -0
  373. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_cline.py +0 -0
  374. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_codebuddy.py +0 -0
  375. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_codex.py +0 -0
  376. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_copilot.py +0 -0
  377. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_cursor_agent.py +0 -0
  378. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_devin.py +0 -0
  379. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_firebender.py +0 -0
  380. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_forge.py +0 -0
  381. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_gemini.py +0 -0
  382. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_generic.py +0 -0
  383. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_goose.py +0 -0
  384. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_junie.py +0 -0
  385. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_kilocode.py +0 -0
  386. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_kimi.py +0 -0
  387. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_kiro_cli.py +0 -0
  388. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_lingma.py +0 -0
  389. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_omp.py +0 -0
  390. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_opencode.py +0 -0
  391. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_pi.py +0 -0
  392. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_qodercli.py +0 -0
  393. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_qwen.py +0 -0
  394. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_rovodev.py +0 -0
  395. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_scaffold.py +0 -0
  396. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_shai.py +0 -0
  397. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_state.py +0 -0
  398. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_subcommand.py +0 -0
  399. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_tabnine.py +0 -0
  400. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_trae.py +0 -0
  401. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_vibe.py +0 -0
  402. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_zcode.py +0 -0
  403. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_zed.py +0 -0
  404. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_manifest.py +0 -0
  405. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/self_upgrade_helpers.py +0 -0
  406. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_agent_config_consistency.py +0 -0
  407. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_authentication.py +0 -0
  408. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_branch_numbering.py +0 -0
  409. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_check_prerequisites_paths_only.py +0 -0
  410. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_check_tool.py +0 -0
  411. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_cli_version.py +0 -0
  412. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_commands_package.py +0 -0
  413. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_console_imports.py +0 -0
  414. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_extension_registration.py +0 -0
  415. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_extension_update_hardening.py +0 -0
  416. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_github_http.py +0 -0
  417. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_github_workflows.py +0 -0
  418. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_init_dir.py +0 -0
  419. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_init_dir_cli.py +0 -0
  420. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_live_transient_windows.py +0 -0
  421. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_merge.py +0 -0
  422. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_presets.py +0 -0
  423. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_ps1_encoding.py +0 -0
  424. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_registrar_path_traversal.py +0 -0
  425. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_self_upgrade_detection.py +0 -0
  426. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_self_upgrade_execution.py +0 -0
  427. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_self_upgrade_guidance.py +0 -0
  428. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_self_upgrade_verification.py +0 -0
  429. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_setup_plan_feature_json.py +0 -0
  430. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_setup_plan_no_overwrite.py +0 -0
  431. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_setup_tasks.py +0 -0
  432. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_shared_infra_integrity.py +0 -0
  433. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_timestamp_branches.py +0 -0
  434. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_upgrade.py +0 -0
  435. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_utils.py +0 -0
  436. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_utils_assets_imports.py +0 -0
  437. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_version_imports.py +0 -0
  438. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_workflow_run_without_project.py +0 -0
  439. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_workflows.py +0 -0
  440. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_adapters.py +0 -0
  441. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_conflict.py +0 -0
  442. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_packager.py +0 -0
  443. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_primitives.py +0 -0
  444. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_records.py +0 -0
  445. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_references.py +0 -0
  446. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_resolver.py +0 -0
  447. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_validator.py +0 -0
  448. {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_versioning.py +0 -0
  449. {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/ARCHITECTURE.md +0 -0
  450. {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/PUBLISHING.md +0 -0
  451. {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/README.md +0 -0
  452. {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/catalog.community.json +0 -0
  453. {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/catalog.json +0 -0
  454. {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/speckit/workflow.yml +0 -0
  455. {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/step-catalog.community.json +0 -0
  456. {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/step-catalog.json +0 -0
@@ -2,6 +2,21 @@
2
2
 
3
3
  <!-- insert new changelog below this comment -->
4
4
 
5
+ ## [0.12.6] - 2026-07-07
6
+
7
+ ### Changed
8
+
9
+ - fix(bundler): validate catalog URLs in `catalog add` (HTTPS-only, require host) (#3367)
10
+ - Update Ralph Loop extension to v1.2.1 (#3365)
11
+ - fix extension-local script path rewriting (#3364)
12
+ - Add Charter extension to community catalog (#3363)
13
+ - feat(scripts): add Python check-prerequisites PoC (#3302)
14
+ - test: reduce registry manifest test repetition (#3146)
15
+ - fix(integrations): hermes honors SPECKIT_INTEGRATION_HERMES_EXTRA_ARGS (#3346)
16
+ - fix(extensions): coerce non-mapping YAML config roots to {} in ConfigManager (#3345)
17
+ - fix(yaml): pin goose recipe prompt block-scalar indentation (#3343)
18
+ - chore: release 0.12.5, begin 0.12.6.dev0 development (#3381)
19
+
5
20
  ## [0.12.5] - 2026-07-06
6
21
 
7
22
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specify-cli
3
- Version: 0.12.5
3
+ Version: 0.12.6
4
4
  Summary: Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD).
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -42,6 +42,7 @@ The following community-contributed extensions are available in [`catalog.commun
42
42
  | Bugfix Workflow | Structured bugfix workflow — capture bugs, trace to spec artifacts, and patch specs surgically | `process` | Read+Write | [spec-kit-bugfix](https://github.com/Quratulain-bilal/spec-kit-bugfix) |
43
43
  | Canon | Adds canon-driven (baseline-driven) workflows: spec-first, code-first, spec-drift. Requires Canon Core preset installation. | `process` | Read+Write | [spec-kit-canon](https://github.com/maximiliamus/spec-kit-canon/tree/master/extension) |
44
44
  | Catalog CI | Automated validation for spec-kit community catalog entries — structure, URLs, diffs, and linting | `process` | Read-only | [spec-kit-catalog-ci](https://github.com/Quratulain-bilal/spec-kit-catalog-ci) |
45
+ | Charter | Compose modular project constitutions from shared fragment registries. Centralize governance rules, select per-project fragments, track upstream changes, and keep multi-project setups consistent. | `process` | Read+Write | [spec-kit-charter](https://github.com/Fyloss/spec-kit-charter) |
45
46
  | CI Guard | Spec compliance gates for CI/CD — verify specs exist, check drift, and block merges on gaps | `process` | Read-only | [spec-kit-ci-guard](https://github.com/Quratulain-bilal/spec-kit-ci-guard) |
46
47
  | Checkpoint Extension | Commit the changes made during the middle of the implementation, so you don't end up with just one very large commit at the end | `code` | Read+Write | [spec-kit-checkpoint](https://github.com/aaronrsun/spec-kit-checkpoint) |
47
48
  | Cleanup Extension | Post-implementation quality gate that reviews changes, fixes small issues (scout rule), creates tasks for medium issues, and generates analysis for large issues | `code` | Read+Write | [spec-kit-cleanup](https://github.com/dsrednicki/spec-kit-cleanup) |
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema_version": "1.0",
3
- "updated_at": "2026-07-01T00:00:00Z",
3
+ "updated_at": "2026-07-06T00:00:00Z",
4
4
  "catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.community.json",
5
5
  "extensions": {
6
6
  "aide": {
@@ -670,6 +670,40 @@
670
670
  "created_at": "2026-04-11T18:00:00Z",
671
671
  "updated_at": "2026-04-11T18:00:00Z"
672
672
  },
673
+ "charter": {
674
+ "name": "Charter",
675
+ "id": "charter",
676
+ "description": "Compose modular project constitutions from shared fragment registries. Centralize governance rules, select per-project fragments, track upstream changes, and keep multi-project setups consistent.",
677
+ "author": "Fyloss",
678
+ "version": "0.3.1",
679
+ "download_url": "https://github.com/Fyloss/spec-kit-charter/archive/refs/tags/v0.3.1.zip",
680
+ "repository": "https://github.com/Fyloss/spec-kit-charter",
681
+ "homepage": "https://github.com/Fyloss/spec-kit-charter",
682
+ "documentation": "https://github.com/Fyloss/spec-kit-charter/tree/master/docs",
683
+ "changelog": "https://github.com/Fyloss/spec-kit-charter/blob/master/CHANGELOG.md",
684
+ "license": "MIT",
685
+ "category": "process",
686
+ "effect": "read-write",
687
+ "requires": {
688
+ "speckit_version": ">=0.11.9"
689
+ },
690
+ "provides": {
691
+ "commands": 5,
692
+ "hooks": 1
693
+ },
694
+ "tags": [
695
+ "constitution",
696
+ "governance",
697
+ "modular",
698
+ "fragments",
699
+ "registry"
700
+ ],
701
+ "verified": false,
702
+ "downloads": 0,
703
+ "stars": 0,
704
+ "created_at": "2026-07-06T00:00:00Z",
705
+ "updated_at": "2026-07-06T00:00:00Z"
706
+ },
673
707
  "ci-guard": {
674
708
  "name": "CI Guard",
675
709
  "id": "ci-guard",
@@ -2679,8 +2713,8 @@
2679
2713
  "id": "ralph",
2680
2714
  "description": "Autonomous implementation loop using AI agent CLI",
2681
2715
  "author": "Rubiss",
2682
- "version": "1.1.1",
2683
- "download_url": "https://github.com/Rubiss-Projects/spec-kit-ralph/archive/refs/tags/v1.1.1.zip",
2716
+ "version": "1.2.1",
2717
+ "download_url": "https://github.com/Rubiss-Projects/spec-kit-ralph/archive/refs/tags/v1.2.1.zip",
2684
2718
  "repository": "https://github.com/Rubiss-Projects/spec-kit-ralph",
2685
2719
  "homepage": "https://github.com/Rubiss-Projects/spec-kit-ralph",
2686
2720
  "documentation": "https://github.com/Rubiss-Projects/spec-kit-ralph/blob/main/README.md",
@@ -2689,7 +2723,7 @@
2689
2723
  "category": "code",
2690
2724
  "effect": "read-write",
2691
2725
  "requires": {
2692
- "speckit_version": ">=0.1.0",
2726
+ "speckit_version": ">=0.8.5",
2693
2727
  "tools": [
2694
2728
  {
2695
2729
  "name": "copilot",
@@ -2699,6 +2733,10 @@
2699
2733
  "name": "codex",
2700
2734
  "required": false
2701
2735
  },
2736
+ {
2737
+ "name": "claude",
2738
+ "required": false
2739
+ },
2702
2740
  {
2703
2741
  "name": "git",
2704
2742
  "required": true
@@ -2714,13 +2752,14 @@
2714
2752
  "automation",
2715
2753
  "loop",
2716
2754
  "copilot",
2717
- "codex"
2755
+ "codex",
2756
+ "claude"
2718
2757
  ],
2719
2758
  "verified": false,
2720
2759
  "downloads": 0,
2721
2760
  "stars": 0,
2722
2761
  "created_at": "2026-03-09T00:00:00Z",
2723
- "updated_at": "2026-06-05T03:11:06Z"
2762
+ "updated_at": "2026-07-06T00:00:00Z"
2724
2763
  },
2725
2764
  "reconcile": {
2726
2765
  "name": "Reconcile Extension",
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "specify-cli"
3
- version = "0.12.5"
3
+ version = "0.12.6"
4
4
  description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env python3
2
+ """Consolidated prerequisite checking script."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import json
7
+ import sys
8
+ from dataclasses import dataclass
9
+ from pathlib import Path
10
+
11
+ try:
12
+ from common import FeaturePaths, format_speckit_command, get_feature_paths
13
+ except ImportError: # pragma: no cover - direct execution from unusual cwd
14
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
15
+ from common import FeaturePaths, format_speckit_command, get_feature_paths
16
+
17
+
18
+ def _json_line(payload: object) -> str:
19
+ return json.dumps(payload, ensure_ascii=False, separators=(",", ":")) + "\n"
20
+
21
+
22
+ HELP_TEXT = """Usage: check_prerequisites.py [OPTIONS]
23
+
24
+ Consolidated prerequisite checking for Spec-Driven Development workflow.
25
+
26
+ OPTIONS:
27
+ --json Output in JSON format
28
+ --require-tasks Require tasks.md to exist (for implementation phase)
29
+ --include-tasks Include tasks.md in AVAILABLE_DOCS list
30
+ --paths-only Only output path variables (no prerequisite validation)
31
+ --help, -h Show this help message
32
+
33
+ EXAMPLES:
34
+ # Check task prerequisites (plan.md required)
35
+ ./check_prerequisites.py --json
36
+
37
+ # Check implementation prerequisites (plan.md + tasks.md required)
38
+ ./check_prerequisites.py --json --require-tasks --include-tasks
39
+
40
+ # Get feature paths only (no validation)
41
+ ./check_prerequisites.py --paths-only
42
+
43
+ """
44
+
45
+
46
+ @dataclass(frozen=True)
47
+ class Args:
48
+ json_mode: bool = False
49
+ require_tasks: bool = False
50
+ include_tasks: bool = False
51
+ paths_only: bool = False
52
+
53
+
54
+ def _parse_args(argv: list[str]) -> Args:
55
+ json_mode = False
56
+ require_tasks = False
57
+ include_tasks = False
58
+ paths_only = False
59
+
60
+ for arg in argv:
61
+ if arg == "--json":
62
+ json_mode = True
63
+ elif arg == "--require-tasks":
64
+ require_tasks = True
65
+ elif arg == "--include-tasks":
66
+ include_tasks = True
67
+ elif arg == "--paths-only":
68
+ paths_only = True
69
+ elif arg in {"--help", "-h"}:
70
+ sys.stdout.write(HELP_TEXT)
71
+ raise SystemExit(0)
72
+ else:
73
+ print(
74
+ f"ERROR: Unknown option '{arg}'. Use --help for usage information.",
75
+ file=sys.stderr,
76
+ )
77
+ raise SystemExit(1)
78
+
79
+ return Args(
80
+ json_mode=json_mode,
81
+ require_tasks=require_tasks,
82
+ include_tasks=include_tasks,
83
+ paths_only=paths_only,
84
+ )
85
+
86
+
87
+ def _dir_has_entries(path: Path) -> bool:
88
+ try:
89
+ return path.is_dir() and any(path.iterdir())
90
+ except OSError:
91
+ return False
92
+
93
+
94
+ def _available_docs(paths: FeaturePaths, include_tasks: bool) -> list[str]:
95
+ docs: list[str] = []
96
+ if paths.research.is_file():
97
+ docs.append("research.md")
98
+ if paths.data_model.is_file():
99
+ docs.append("data-model.md")
100
+ if _dir_has_entries(paths.contracts_dir):
101
+ docs.append("contracts/")
102
+ if paths.quickstart.is_file():
103
+ docs.append("quickstart.md")
104
+ if include_tasks and paths.tasks.is_file():
105
+ docs.append("tasks.md")
106
+ return docs
107
+
108
+
109
+ def _print_paths_only(paths: FeaturePaths, json_mode: bool) -> None:
110
+ if json_mode:
111
+ sys.stdout.write(
112
+ _json_line(
113
+ {
114
+ "REPO_ROOT": str(paths.repo_root),
115
+ "BRANCH": paths.current_branch,
116
+ "FEATURE_DIR": str(paths.feature_dir),
117
+ "FEATURE_SPEC": str(paths.feature_spec),
118
+ "IMPL_PLAN": str(paths.impl_plan),
119
+ "TASKS": str(paths.tasks),
120
+ }
121
+ )
122
+ )
123
+ return
124
+
125
+ print(f"REPO_ROOT: {paths.repo_root}")
126
+ print(f"BRANCH: {paths.current_branch}")
127
+ print(f"FEATURE_DIR: {paths.feature_dir}")
128
+ print(f"FEATURE_SPEC: {paths.feature_spec}")
129
+ print(f"IMPL_PLAN: {paths.impl_plan}")
130
+ print(f"TASKS: {paths.tasks}")
131
+
132
+
133
+ def _check_file(path: Path, description: str) -> None:
134
+ marker = "✓" if path.is_file() else "✗"
135
+ print(f" {marker} {description}")
136
+
137
+
138
+ def _check_dir(path: Path, description: str) -> None:
139
+ marker = "✓" if _dir_has_entries(path) else "✗"
140
+ print(f" {marker} {description}")
141
+
142
+
143
+ def _print_text_results(paths: FeaturePaths, include_tasks: bool) -> None:
144
+ print(f"FEATURE_DIR:{paths.feature_dir}")
145
+ print("AVAILABLE_DOCS:")
146
+ _check_file(paths.research, "research.md")
147
+ _check_file(paths.data_model, "data-model.md")
148
+ _check_dir(paths.contracts_dir, "contracts/")
149
+ _check_file(paths.quickstart, "quickstart.md")
150
+ if include_tasks:
151
+ _check_file(paths.tasks, "tasks.md")
152
+
153
+
154
+ def main(argv: list[str] | None = None) -> int:
155
+ args = _parse_args(list(argv if argv is not None else sys.argv[1:]))
156
+
157
+ try:
158
+ paths = get_feature_paths(
159
+ no_persist=args.paths_only,
160
+ script_file=Path(__file__),
161
+ )
162
+ except SystemExit as exc:
163
+ if exc.code == 0:
164
+ return 0
165
+ print("ERROR: Failed to resolve feature paths", file=sys.stderr)
166
+ return int(exc.code) if isinstance(exc.code, int) else 1
167
+
168
+ if args.paths_only:
169
+ _print_paths_only(paths, args.json_mode)
170
+ return 0
171
+
172
+ if not paths.feature_dir.is_dir():
173
+ print(f"ERROR: Feature directory not found: {paths.feature_dir}", file=sys.stderr)
174
+ print(
175
+ f"Run {format_speckit_command('specify', paths.repo_root)} first to create the feature structure.",
176
+ file=sys.stderr,
177
+ )
178
+ return 1
179
+
180
+ if not paths.impl_plan.is_file():
181
+ print(f"ERROR: plan.md not found in {paths.feature_dir}", file=sys.stderr)
182
+ print(
183
+ f"Run {format_speckit_command('plan', paths.repo_root)} first to create the implementation plan.",
184
+ file=sys.stderr,
185
+ )
186
+ return 1
187
+
188
+ if args.require_tasks and not paths.tasks.is_file():
189
+ print(f"ERROR: tasks.md not found in {paths.feature_dir}", file=sys.stderr)
190
+ print(
191
+ f"Run {format_speckit_command('tasks', paths.repo_root)} first to create the task list.",
192
+ file=sys.stderr,
193
+ )
194
+ return 1
195
+
196
+ docs = _available_docs(paths, args.include_tasks)
197
+ if args.json_mode:
198
+ sys.stdout.write(
199
+ _json_line({"FEATURE_DIR": str(paths.feature_dir), "AVAILABLE_DOCS": docs})
200
+ )
201
+ else:
202
+ _print_text_results(paths, args.include_tasks)
203
+ return 0
204
+
205
+
206
+ if __name__ == "__main__":
207
+ raise SystemExit(main())
@@ -0,0 +1,210 @@
1
+ """Shared helpers for Spec Kit Python scripts."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import sys
8
+ from dataclasses import dataclass
9
+ from pathlib import Path
10
+
11
+
12
+ def _trim_trailing_separators(value: Path) -> str:
13
+ text = str(value)
14
+ while len(text) > 1 and text.endswith((os.sep, "/")):
15
+ text = text[:-1]
16
+ return text
17
+
18
+
19
+ def find_specify_root(start_dir: Path | None = None) -> Path | None:
20
+ current = (start_dir or Path.cwd()).resolve()
21
+ while True:
22
+ if (current / ".specify").is_dir():
23
+ return current
24
+ parent = current.parent
25
+ if parent == current:
26
+ return None
27
+ current = parent
28
+
29
+
30
+ def resolve_specify_init_dir() -> Path:
31
+ raw = os.environ.get("SPECIFY_INIT_DIR", "")
32
+ candidate = Path(raw)
33
+ if not candidate.is_absolute():
34
+ candidate = Path.cwd() / candidate
35
+ try:
36
+ init_root = candidate.resolve(strict=True)
37
+ except OSError:
38
+ print(
39
+ f"ERROR: SPECIFY_INIT_DIR does not point to an existing directory: {raw}",
40
+ file=sys.stderr,
41
+ )
42
+ raise SystemExit(1)
43
+ if not init_root.is_dir():
44
+ print(
45
+ f"ERROR: SPECIFY_INIT_DIR does not point to an existing directory: {raw}",
46
+ file=sys.stderr,
47
+ )
48
+ raise SystemExit(1)
49
+ if not (init_root / ".specify").is_dir():
50
+ print(
51
+ "ERROR: SPECIFY_INIT_DIR is not a Spec Kit project "
52
+ f"(no .specify/ directory): {init_root}",
53
+ file=sys.stderr,
54
+ )
55
+ raise SystemExit(1)
56
+ return init_root
57
+
58
+
59
+ def get_repo_root(script_file: Path | None = None) -> Path:
60
+ if os.environ.get("SPECIFY_INIT_DIR"):
61
+ return resolve_specify_init_dir()
62
+
63
+ specify_root = find_specify_root()
64
+ if specify_root is not None:
65
+ return specify_root
66
+
67
+ if script_file is not None:
68
+ script_root = find_specify_root(script_file.resolve().parent)
69
+ if script_root is not None:
70
+ return script_root
71
+
72
+ # Installed scripts live at .specify/scripts/python/<script>.py.
73
+ return script_file.resolve().parents[3]
74
+ return Path.cwd().resolve()
75
+
76
+
77
+ def get_current_branch() -> str:
78
+ return os.environ.get("SPECIFY_FEATURE", "")
79
+
80
+
81
+ def read_feature_json_feature_directory(repo_root: Path) -> str:
82
+ feature_json = repo_root / ".specify" / "feature.json"
83
+ if not feature_json.is_file():
84
+ return ""
85
+ try:
86
+ data = json.loads(feature_json.read_text(encoding="utf-8"))
87
+ except (OSError, json.JSONDecodeError):
88
+ return ""
89
+ value = data.get("feature_directory") if isinstance(data, dict) else None
90
+ return value if isinstance(value, str) else ""
91
+
92
+
93
+ def _json_dump(data: dict[str, str]) -> str:
94
+ return json.dumps(data, ensure_ascii=False, separators=(",", ":")) + "\n"
95
+
96
+
97
+ def persist_feature_json(repo_root: Path, feature_dir_value: str) -> None:
98
+ value = feature_dir_value
99
+ try:
100
+ relative = Path(value)
101
+ if relative.is_absolute():
102
+ try:
103
+ value = relative.resolve().relative_to(repo_root.resolve()).as_posix()
104
+ except ValueError:
105
+ value = str(relative)
106
+ except OSError:
107
+ pass
108
+
109
+ current = read_feature_json_feature_directory(repo_root)
110
+ if current == value:
111
+ return
112
+
113
+ specify_dir = repo_root / ".specify"
114
+ specify_dir.mkdir(parents=True, exist_ok=True)
115
+ (specify_dir / "feature.json").write_text(
116
+ _json_dump({"feature_directory": value}),
117
+ encoding="utf-8",
118
+ )
119
+
120
+
121
+ @dataclass(frozen=True)
122
+ class FeaturePaths:
123
+ repo_root: Path
124
+ current_branch: str
125
+ feature_dir: Path
126
+ feature_spec: Path
127
+ impl_plan: Path
128
+ tasks: Path
129
+ research: Path
130
+ data_model: Path
131
+ quickstart: Path
132
+ contracts_dir: Path
133
+
134
+
135
+ def get_feature_paths(
136
+ *, no_persist: bool = False, script_file: Path | None = None
137
+ ) -> FeaturePaths:
138
+ repo_root = get_repo_root(script_file)
139
+ current_branch = get_current_branch()
140
+
141
+ feature_dir_raw = os.environ.get("SPECIFY_FEATURE_DIRECTORY", "")
142
+ if feature_dir_raw:
143
+ feature_dir = Path(feature_dir_raw)
144
+ if not feature_dir.is_absolute():
145
+ feature_dir = repo_root / feature_dir
146
+ if not no_persist:
147
+ persist_feature_json(repo_root, feature_dir_raw)
148
+ elif (repo_root / ".specify" / "feature.json").is_file():
149
+ stored = read_feature_json_feature_directory(repo_root)
150
+ if not stored:
151
+ print(
152
+ "ERROR: Feature directory not found. Set SPECIFY_FEATURE_DIRECTORY "
153
+ "or ensure .specify/feature.json contains feature_directory.",
154
+ file=sys.stderr,
155
+ )
156
+ raise SystemExit(1)
157
+ feature_dir = Path(stored)
158
+ if not feature_dir.is_absolute():
159
+ feature_dir = repo_root / feature_dir
160
+ else:
161
+ print(
162
+ "ERROR: Feature directory not found. Set SPECIFY_FEATURE_DIRECTORY "
163
+ "or run the specify command to create .specify/feature.json.",
164
+ file=sys.stderr,
165
+ )
166
+ raise SystemExit(1)
167
+
168
+ if not current_branch:
169
+ current_branch = Path(_trim_trailing_separators(feature_dir)).name
170
+
171
+ return FeaturePaths(
172
+ repo_root=repo_root,
173
+ current_branch=current_branch,
174
+ feature_dir=feature_dir,
175
+ feature_spec=feature_dir / "spec.md",
176
+ impl_plan=feature_dir / "plan.md",
177
+ tasks=feature_dir / "tasks.md",
178
+ research=feature_dir / "research.md",
179
+ data_model=feature_dir / "data-model.md",
180
+ quickstart=feature_dir / "quickstart.md",
181
+ contracts_dir=feature_dir / "contracts",
182
+ )
183
+
184
+
185
+ def get_invoke_separator(repo_root: Path) -> str:
186
+ integration_json = repo_root / ".specify" / "integration.json"
187
+ if not integration_json.is_file():
188
+ return "."
189
+ try:
190
+ state = json.loads(integration_json.read_text(encoding="utf-8"))
191
+ key = state.get("default_integration") or state.get("integration") or ""
192
+ settings = state.get("integration_settings")
193
+ if isinstance(key, str) and isinstance(settings, dict):
194
+ entry = settings.get(key)
195
+ if isinstance(entry, dict) and entry.get("invoke_separator") in {".", "-"}:
196
+ return entry["invoke_separator"]
197
+ except (OSError, json.JSONDecodeError):
198
+ pass
199
+ return "."
200
+
201
+
202
+ def format_speckit_command(command_name: str, repo_root: Path) -> str:
203
+ separator = get_invoke_separator(repo_root)
204
+ name = command_name.lstrip("/")
205
+ if name.startswith("speckit."):
206
+ name = name[len("speckit.") :]
207
+ elif name.startswith("speckit-"):
208
+ name = name[len("speckit-") :]
209
+ name = name.replace(".", separator)
210
+ return f"/speckit{separator}{name}"