specify-cli 0.12.9__tar.gz → 0.12.10__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 (461) hide show
  1. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/lint.yml +1 -1
  2. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/publish-pypi.yml +2 -2
  3. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/test.yml +2 -2
  4. {specify_cli-0.12.9 → specify_cli-0.12.10}/CHANGELOG.md +15 -0
  5. {specify_cli-0.12.9 → specify_cli-0.12.10}/PKG-INFO +1 -1
  6. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/community/friends.md +2 -0
  7. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/agent-context/commands/speckit.agent-context.update.md +2 -2
  8. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/agent-context/scripts/bash/update-agent-context.sh +6 -6
  9. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +2 -4
  10. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/scripts/powershell/create-new-feature-branch.ps1 +8 -2
  11. {specify_cli-0.12.9 → specify_cli-0.12.10}/pyproject.toml +1 -1
  12. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/__init__.py +3 -2
  13. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/shared_infra.py +5 -1
  14. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/shell/__init__.py +22 -2
  15. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/commands/analyze.md +1 -0
  16. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/commands/checklist.md +1 -0
  17. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/commands/clarify.md +1 -0
  18. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/commands/converge.md +1 -0
  19. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/commands/implement.md +1 -0
  20. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/commands/plan.md +1 -2
  21. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/commands/taskstoissues.md +1 -0
  22. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/extensions/git/test_git_extension.py +32 -0
  23. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/extensions/test_extension_agent_context.py +56 -0
  24. specify_cli-0.12.10/tests/test_command_template_py_scripts.py +107 -0
  25. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_workflows.py +100 -0
  26. {specify_cli-0.12.9 → specify_cli-0.12.10}/.devcontainer/devcontainer.json +0 -0
  27. {specify_cli-0.12.9 → specify_cli-0.12.10}/.devcontainer/post-create.sh +0 -0
  28. {specify_cli-0.12.9 → specify_cli-0.12.10}/.editorconfig +0 -0
  29. {specify_cli-0.12.9 → specify_cli-0.12.10}/.gitattributes +0 -0
  30. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/CODEOWNERS +0 -0
  31. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/agent_request.yml +0 -0
  32. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  33. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/bundle_submission.yml +0 -0
  34. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  35. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/extension_submission.yml +0 -0
  36. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  37. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/preset_submission.yml +0 -0
  38. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  39. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/aw/actions-lock.json +0 -0
  40. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/dependabot.yml +0 -0
  41. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/skills/add-community-extension/SKILL.md +0 -0
  42. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/RELEASE-PROCESS.md +0 -0
  43. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/add-community-extension.lock.yml +0 -0
  44. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/add-community-extension.md +0 -0
  45. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/add-community-preset.lock.yml +0 -0
  46. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/add-community-preset.md +0 -0
  47. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/bug-assess.lock.yml +0 -0
  48. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/bug-assess.md +0 -0
  49. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/bug-fix.lock.yml +0 -0
  50. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/bug-fix.md +0 -0
  51. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/bug-test.lock.yml +0 -0
  52. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/bug-test.md +0 -0
  53. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/catalog-assign.yml +0 -0
  54. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/codeql.yml +0 -0
  55. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/docs.yml +0 -0
  56. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/release-trigger.yml +0 -0
  57. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/release.yml +0 -0
  58. {specify_cli-0.12.9 → specify_cli-0.12.10}/.github/workflows/stale.yml +0 -0
  59. {specify_cli-0.12.9 → specify_cli-0.12.10}/.gitignore +0 -0
  60. {specify_cli-0.12.9 → specify_cli-0.12.10}/.markdownlint-cli2.jsonc +0 -0
  61. {specify_cli-0.12.9 → specify_cli-0.12.10}/.zenodo.json +0 -0
  62. {specify_cli-0.12.9 → specify_cli-0.12.10}/AGENTS.md +0 -0
  63. {specify_cli-0.12.9 → specify_cli-0.12.10}/CITATION.cff +0 -0
  64. {specify_cli-0.12.9 → specify_cli-0.12.10}/CODE_OF_CONDUCT.md +0 -0
  65. {specify_cli-0.12.9 → specify_cli-0.12.10}/CONTRIBUTING.md +0 -0
  66. {specify_cli-0.12.9 → specify_cli-0.12.10}/DEVELOPMENT.md +0 -0
  67. {specify_cli-0.12.9 → specify_cli-0.12.10}/LICENSE +0 -0
  68. {specify_cli-0.12.9 → specify_cli-0.12.10}/README.md +0 -0
  69. {specify_cli-0.12.9 → specify_cli-0.12.10}/SECURITY.md +0 -0
  70. {specify_cli-0.12.9 → specify_cli-0.12.10}/SUPPORT.md +0 -0
  71. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/.gitignore +0 -0
  72. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/README.md +0 -0
  73. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/community/bundles.md +0 -0
  74. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/community/extensions.md +0 -0
  75. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/community/overview.md +0 -0
  76. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/community/presets.md +0 -0
  77. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/community/walkthroughs.md +0 -0
  78. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/concepts/complex-features.md +0 -0
  79. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/concepts/sdd.md +0 -0
  80. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/concepts/spec-persistence.md +0 -0
  81. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/docfx.json +0 -0
  82. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/guides/evolving-specs.md +0 -0
  83. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/guides/monorepo.md +0 -0
  84. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/index.md +0 -0
  85. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/install/air-gapped.md +0 -0
  86. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/install/one-time.md +0 -0
  87. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/install/pipx.md +0 -0
  88. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/install/uv.md +0 -0
  89. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/installation.md +0 -0
  90. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/local-development.md +0 -0
  91. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/quickstart.md +0 -0
  92. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/reference/authentication.md +0 -0
  93. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/reference/bundles.md +0 -0
  94. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/reference/core.md +0 -0
  95. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/reference/extensions.md +0 -0
  96. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/reference/integrations.md +0 -0
  97. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/reference/overview.md +0 -0
  98. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/reference/presets.md +0 -0
  99. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/reference/workflows.md +0 -0
  100. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/template/public/main.css +0 -0
  101. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/toc.yml +0 -0
  102. {specify_cli-0.12.9 → specify_cli-0.12.10}/docs/upgrade.md +0 -0
  103. {specify_cli-0.12.9 → specify_cli-0.12.10}/examples/bundles/business-analyst/README.md +0 -0
  104. {specify_cli-0.12.9 → specify_cli-0.12.10}/examples/bundles/business-analyst/bundle.yml +0 -0
  105. {specify_cli-0.12.9 → specify_cli-0.12.10}/examples/bundles/developer/README.md +0 -0
  106. {specify_cli-0.12.9 → specify_cli-0.12.10}/examples/bundles/developer/bundle.yml +0 -0
  107. {specify_cli-0.12.9 → specify_cli-0.12.10}/examples/bundles/product-manager/README.md +0 -0
  108. {specify_cli-0.12.9 → specify_cli-0.12.10}/examples/bundles/product-manager/bundle.yml +0 -0
  109. {specify_cli-0.12.9 → specify_cli-0.12.10}/examples/bundles/security-researcher/README.md +0 -0
  110. {specify_cli-0.12.9 → specify_cli-0.12.10}/examples/bundles/security-researcher/bundle.yml +0 -0
  111. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/EXTENSION-API-REFERENCE.md +0 -0
  112. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/EXTENSION-DEVELOPMENT-GUIDE.md +0 -0
  113. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/EXTENSION-PUBLISHING-GUIDE.md +0 -0
  114. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/EXTENSION-USER-GUIDE.md +0 -0
  115. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/README.md +0 -0
  116. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/RFC-EXTENSION-SYSTEM.md +0 -0
  117. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/agent-context/README.md +0 -0
  118. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/agent-context/agent-context-config.yml +0 -0
  119. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/agent-context/agent-context-defaults.json +0 -0
  120. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/agent-context/extension.yml +0 -0
  121. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/agent-context/scripts/python/update_agent_context.py +0 -0
  122. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/bug/README.md +0 -0
  123. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/bug/commands/speckit.bug.assess.md +0 -0
  124. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/bug/commands/speckit.bug.fix.md +0 -0
  125. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/bug/commands/speckit.bug.test.md +0 -0
  126. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/bug/extension.yml +0 -0
  127. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/catalog.community.json +0 -0
  128. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/catalog.json +0 -0
  129. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/README.md +0 -0
  130. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.commit.md +0 -0
  131. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.feature.md +0 -0
  132. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.initialize.md +0 -0
  133. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.remote.md +0 -0
  134. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.validate.md +0 -0
  135. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/config-template.yml +0 -0
  136. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/extension.yml +0 -0
  137. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/git-config.yml +0 -0
  138. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/scripts/bash/auto-commit.sh +0 -0
  139. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/scripts/bash/create-new-feature-branch.sh +0 -0
  140. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/scripts/bash/git-common.sh +0 -0
  141. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/scripts/bash/initialize-repo.sh +0 -0
  142. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
  143. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/scripts/powershell/git-common.ps1 +0 -0
  144. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
  145. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/selftest/commands/selftest.md +0 -0
  146. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/selftest/extension.yml +0 -0
  147. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/template/.gitignore +0 -0
  148. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/template/CHANGELOG.md +0 -0
  149. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/template/EXAMPLE-README.md +0 -0
  150. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/template/LICENSE +0 -0
  151. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/template/README.md +0 -0
  152. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/template/commands/example.md +0 -0
  153. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/template/config-template.yml +0 -0
  154. {specify_cli-0.12.9 → specify_cli-0.12.10}/extensions/template/extension.yml +0 -0
  155. {specify_cli-0.12.9 → specify_cli-0.12.10}/integrations/CONTRIBUTING.md +0 -0
  156. {specify_cli-0.12.9 → specify_cli-0.12.10}/integrations/README.md +0 -0
  157. {specify_cli-0.12.9 → specify_cli-0.12.10}/integrations/catalog.community.json +0 -0
  158. {specify_cli-0.12.9 → specify_cli-0.12.10}/integrations/catalog.json +0 -0
  159. {specify_cli-0.12.9 → specify_cli-0.12.10}/media/bootstrap-claude-code.gif +0 -0
  160. {specify_cli-0.12.9 → specify_cli-0.12.10}/media/logo_large.webp +0 -0
  161. {specify_cli-0.12.9 → specify_cli-0.12.10}/media/logo_small.webp +0 -0
  162. {specify_cli-0.12.9 → specify_cli-0.12.10}/media/spec-kit-video-header.jpg +0 -0
  163. {specify_cli-0.12.9 → specify_cli-0.12.10}/media/specify_cli.gif +0 -0
  164. {specify_cli-0.12.9 → specify_cli-0.12.10}/newsletters/2026-April.md +0 -0
  165. {specify_cli-0.12.9 → specify_cli-0.12.10}/newsletters/2026-February.md +0 -0
  166. {specify_cli-0.12.9 → specify_cli-0.12.10}/newsletters/2026-June.md +0 -0
  167. {specify_cli-0.12.9 → specify_cli-0.12.10}/newsletters/2026-March.md +0 -0
  168. {specify_cli-0.12.9 → specify_cli-0.12.10}/newsletters/2026-May.md +0 -0
  169. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/ARCHITECTURE.md +0 -0
  170. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/PUBLISHING.md +0 -0
  171. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/README.md +0 -0
  172. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/catalog.community.json +0 -0
  173. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/catalog.json +0 -0
  174. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/lean/README.md +0 -0
  175. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/lean/commands/speckit.constitution.md +0 -0
  176. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/lean/commands/speckit.implement.md +0 -0
  177. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/lean/commands/speckit.plan.md +0 -0
  178. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/lean/commands/speckit.specify.md +0 -0
  179. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/lean/commands/speckit.tasks.md +0 -0
  180. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/lean/preset.yml +0 -0
  181. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/scaffold/README.md +0 -0
  182. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/scaffold/commands/speckit.myext.myextcmd.md +0 -0
  183. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/scaffold/commands/speckit.specify.md +0 -0
  184. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/scaffold/preset.yml +0 -0
  185. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/scaffold/templates/myext-template.md +0 -0
  186. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/scaffold/templates/spec-template.md +0 -0
  187. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/self-test/commands/speckit.specify.md +0 -0
  188. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/self-test/commands/speckit.wrap-test.md +0 -0
  189. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/self-test/preset.yml +0 -0
  190. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/self-test/templates/agent-file-template.md +0 -0
  191. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/self-test/templates/checklist-template.md +0 -0
  192. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/self-test/templates/constitution-template.md +0 -0
  193. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/self-test/templates/plan-template.md +0 -0
  194. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/self-test/templates/spec-template.md +0 -0
  195. {specify_cli-0.12.9 → specify_cli-0.12.10}/presets/self-test/templates/tasks-template.md +0 -0
  196. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/bash/check-prerequisites.sh +0 -0
  197. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/bash/common.sh +0 -0
  198. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/bash/create-new-feature.sh +0 -0
  199. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/bash/setup-plan.sh +0 -0
  200. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/bash/setup-tasks.sh +0 -0
  201. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/powershell/check-prerequisites.ps1 +0 -0
  202. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/powershell/common.ps1 +0 -0
  203. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/powershell/create-new-feature.ps1 +0 -0
  204. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/powershell/setup-plan.ps1 +0 -0
  205. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/powershell/setup-tasks.ps1 +0 -0
  206. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/python/check_prerequisites.py +0 -0
  207. {specify_cli-0.12.9 → specify_cli-0.12.10}/scripts/python/common.py +0 -0
  208. {specify_cli-0.12.9 → specify_cli-0.12.10}/spec-driven.md +0 -0
  209. {specify_cli-0.12.9 → specify_cli-0.12.10}/spec-kit.code-workspace +0 -0
  210. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/_agent_config.py +0 -0
  211. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/_assets.py +0 -0
  212. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/_console.py +0 -0
  213. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/_github_http.py +0 -0
  214. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/_init_options.py +0 -0
  215. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/_invocation_style.py +0 -0
  216. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/_project.py +0 -0
  217. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/_toml_string.py +0 -0
  218. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/_utils.py +0 -0
  219. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/_version.py +0 -0
  220. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/agents.py +0 -0
  221. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/authentication/__init__.py +0 -0
  222. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/authentication/azure_devops.py +0 -0
  223. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/authentication/base.py +0 -0
  224. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/authentication/config.py +0 -0
  225. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/authentication/github.py +0 -0
  226. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/authentication/http.py +0 -0
  227. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/__init__.py +0 -0
  228. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/commands_impl/__init__.py +0 -0
  229. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/commands_impl/catalog_config.py +0 -0
  230. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/__init__.py +0 -0
  231. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/project.py +0 -0
  232. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/versioning.py +0 -0
  233. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/yamlio.py +0 -0
  234. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/models/__init__.py +0 -0
  235. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/models/catalog.py +0 -0
  236. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/models/manifest.py +0 -0
  237. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/models/records.py +0 -0
  238. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/services/__init__.py +0 -0
  239. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/services/adapters.py +0 -0
  240. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/services/catalog_stack.py +0 -0
  241. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/services/conflict.py +0 -0
  242. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/services/installer.py +0 -0
  243. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/services/packager.py +0 -0
  244. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/services/primitives.py +0 -0
  245. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/services/references.py +0 -0
  246. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/services/resolver.py +0 -0
  247. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/bundler/services/validator.py +0 -0
  248. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/catalogs.py +0 -0
  249. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/commands/__init__.py +0 -0
  250. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/commands/bundle/__init__.py +0 -0
  251. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/commands/init.py +0 -0
  252. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/extensions/__init__.py +0 -0
  253. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/extensions/_commands.py +0 -0
  254. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integration_runtime.py +0 -0
  255. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integration_scaffold.py +0 -0
  256. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integration_state.py +0 -0
  257. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integration_status.py +0 -0
  258. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/__init__.py +0 -0
  259. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/_commands.py +0 -0
  260. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/_helpers.py +0 -0
  261. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/_install_commands.py +0 -0
  262. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/_migrate_commands.py +0 -0
  263. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/_query_commands.py +0 -0
  264. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/_scaffold_commands.py +0 -0
  265. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/agy/__init__.py +0 -0
  266. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/amp/__init__.py +0 -0
  267. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/auggie/__init__.py +0 -0
  268. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/base.py +0 -0
  269. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/bob/__init__.py +0 -0
  270. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/catalog.py +0 -0
  271. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/claude/__init__.py +0 -0
  272. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/cline/__init__.py +0 -0
  273. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/codebuddy/__init__.py +0 -0
  274. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/codex/__init__.py +0 -0
  275. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/copilot/__init__.py +0 -0
  276. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/cursor_agent/__init__.py +0 -0
  277. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/devin/__init__.py +0 -0
  278. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/firebender/__init__.py +0 -0
  279. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/forge/__init__.py +0 -0
  280. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/gemini/__init__.py +0 -0
  281. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/generic/__init__.py +0 -0
  282. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/goose/__init__.py +0 -0
  283. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/hermes/__init__.py +0 -0
  284. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/junie/__init__.py +0 -0
  285. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/kilocode/__init__.py +0 -0
  286. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/kimi/__init__.py +0 -0
  287. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/kiro_cli/__init__.py +0 -0
  288. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/lingma/__init__.py +0 -0
  289. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/manifest.py +0 -0
  290. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/omp/__init__.py +0 -0
  291. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/opencode/__init__.py +0 -0
  292. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/pi/__init__.py +0 -0
  293. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/qodercli/__init__.py +0 -0
  294. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/qwen/__init__.py +0 -0
  295. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/rovodev/__init__.py +0 -0
  296. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/shai/__init__.py +0 -0
  297. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/tabnine/__init__.py +0 -0
  298. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/trae/__init__.py +0 -0
  299. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/vibe/__init__.py +0 -0
  300. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/zcode/__init__.py +0 -0
  301. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/integrations/zed/__init__.py +0 -0
  302. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/presets/__init__.py +0 -0
  303. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/presets/_commands.py +0 -0
  304. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/__init__.py +0 -0
  305. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/_commands.py +0 -0
  306. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/base.py +0 -0
  307. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/catalog.py +0 -0
  308. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/engine.py +0 -0
  309. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/expressions.py +0 -0
  310. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/__init__.py +0 -0
  311. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/command/__init__.py +0 -0
  312. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/do_while/__init__.py +0 -0
  313. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/fan_in/__init__.py +0 -0
  314. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/fan_out/__init__.py +0 -0
  315. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/gate/__init__.py +0 -0
  316. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/if_then/__init__.py +0 -0
  317. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/init/__init__.py +0 -0
  318. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/prompt/__init__.py +0 -0
  319. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/switch/__init__.py +0 -0
  320. {specify_cli-0.12.9 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/while_loop/__init__.py +0 -0
  321. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/checklist-template.md +0 -0
  322. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/commands/constitution.md +0 -0
  323. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/commands/specify.md +0 -0
  324. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/commands/tasks.md +0 -0
  325. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/constitution-template.md +0 -0
  326. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/plan-template.md +0 -0
  327. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/spec-template.md +0 -0
  328. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/tasks-template.md +0 -0
  329. {specify_cli-0.12.9 → specify_cli-0.12.10}/templates/vscode-settings.json +0 -0
  330. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/__init__.py +0 -0
  331. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/auth_helpers.py +0 -0
  332. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/bundler_helpers.py +0 -0
  333. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/conftest.py +0 -0
  334. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/contract/test_bundle_cli.py +0 -0
  335. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/contract/test_catalog_schema.py +0 -0
  336. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/contract/test_manifest_schema.py +0 -0
  337. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/extensions/__init__.py +0 -0
  338. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/extensions/bug/__init__.py +0 -0
  339. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/extensions/bug/test_bug_extension.py +0 -0
  340. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/extensions/git/__init__.py +0 -0
  341. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/extensions/test_agent_context_cli_free.py +0 -0
  342. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/extensions/test_update_agent_context_feature_json.py +0 -0
  343. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/extensions/test_update_agent_context_python_parity.py +0 -0
  344. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/hooks/TESTING.md +0 -0
  345. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/hooks/plan.md +0 -0
  346. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/hooks/spec.md +0 -0
  347. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/hooks/tasks.md +0 -0
  348. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/http_helpers.py +0 -0
  349. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integration/test_bundler_catalog_stack.py +0 -0
  350. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integration/test_bundler_init_install.py +0 -0
  351. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integration/test_bundler_install_flow.py +0 -0
  352. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integration/test_bundler_local_install.py +0 -0
  353. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integration/test_bundler_offline.py +0 -0
  354. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integration/test_bundler_security_paths.py +0 -0
  355. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/__init__.py +0 -0
  356. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/conftest.py +0 -0
  357. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_base.py +0 -0
  358. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_cli.py +0 -0
  359. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_extra_args.py +0 -0
  360. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_home_isolation.py +0 -0
  361. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_agy.py +0 -0
  362. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_amp.py +0 -0
  363. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_auggie.py +0 -0
  364. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_base_markdown.py +0 -0
  365. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_base_skills.py +0 -0
  366. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_base_toml.py +0 -0
  367. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_base_yaml.py +0 -0
  368. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_bob.py +0 -0
  369. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_catalog.py +0 -0
  370. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_claude.py +0 -0
  371. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_cline.py +0 -0
  372. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_codebuddy.py +0 -0
  373. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_codex.py +0 -0
  374. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_copilot.py +0 -0
  375. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_cursor_agent.py +0 -0
  376. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_devin.py +0 -0
  377. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_firebender.py +0 -0
  378. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_forge.py +0 -0
  379. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_gemini.py +0 -0
  380. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_generic.py +0 -0
  381. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_goose.py +0 -0
  382. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_hermes.py +0 -0
  383. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_junie.py +0 -0
  384. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_kilocode.py +0 -0
  385. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_kimi.py +0 -0
  386. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_kiro_cli.py +0 -0
  387. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_lingma.py +0 -0
  388. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_omp.py +0 -0
  389. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_opencode.py +0 -0
  390. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_pi.py +0 -0
  391. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_qodercli.py +0 -0
  392. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_qwen.py +0 -0
  393. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_rovodev.py +0 -0
  394. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_scaffold.py +0 -0
  395. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_shai.py +0 -0
  396. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_state.py +0 -0
  397. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_subcommand.py +0 -0
  398. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_tabnine.py +0 -0
  399. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_trae.py +0 -0
  400. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_vibe.py +0 -0
  401. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_zcode.py +0 -0
  402. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_integration_zed.py +0 -0
  403. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_manifest.py +0 -0
  404. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_registry.py +0 -0
  405. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/integrations/test_skill_frontmatter_quoting.py +0 -0
  406. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/self_upgrade_helpers.py +0 -0
  407. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_agent_config_consistency.py +0 -0
  408. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_authentication.py +0 -0
  409. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_branch_numbering.py +0 -0
  410. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_check_prerequisites_paths_only.py +0 -0
  411. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_check_prerequisites_python_parity.py +0 -0
  412. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_check_tool.py +0 -0
  413. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_cli_version.py +0 -0
  414. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_commands_package.py +0 -0
  415. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_console_imports.py +0 -0
  416. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_extension_registration.py +0 -0
  417. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_extension_skills.py +0 -0
  418. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_extension_update_hardening.py +0 -0
  419. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_extensions.py +0 -0
  420. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_github_http.py +0 -0
  421. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_github_workflows.py +0 -0
  422. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_init_dir.py +0 -0
  423. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_init_dir_cli.py +0 -0
  424. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_live_transient_windows.py +0 -0
  425. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_merge.py +0 -0
  426. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_post_process.py +0 -0
  427. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_presets.py +0 -0
  428. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_ps1_encoding.py +0 -0
  429. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_registrar_path_traversal.py +0 -0
  430. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_self_upgrade_detection.py +0 -0
  431. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_self_upgrade_execution.py +0 -0
  432. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_self_upgrade_guidance.py +0 -0
  433. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_self_upgrade_verification.py +0 -0
  434. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_setup_plan_feature_json.py +0 -0
  435. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_setup_plan_no_overwrite.py +0 -0
  436. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_setup_tasks.py +0 -0
  437. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_shared_infra_integrity.py +0 -0
  438. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_timestamp_branches.py +0 -0
  439. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_upgrade.py +0 -0
  440. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_utils.py +0 -0
  441. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_utils_assets_imports.py +0 -0
  442. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_version_imports.py +0 -0
  443. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/test_workflow_run_without_project.py +0 -0
  444. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/unit/test_bundler_adapters.py +0 -0
  445. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/unit/test_bundler_catalog_config.py +0 -0
  446. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/unit/test_bundler_conflict.py +0 -0
  447. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/unit/test_bundler_packager.py +0 -0
  448. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/unit/test_bundler_primitives.py +0 -0
  449. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/unit/test_bundler_records.py +0 -0
  450. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/unit/test_bundler_references.py +0 -0
  451. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/unit/test_bundler_resolver.py +0 -0
  452. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/unit/test_bundler_validator.py +0 -0
  453. {specify_cli-0.12.9 → specify_cli-0.12.10}/tests/unit/test_bundler_versioning.py +0 -0
  454. {specify_cli-0.12.9 → specify_cli-0.12.10}/workflows/ARCHITECTURE.md +0 -0
  455. {specify_cli-0.12.9 → specify_cli-0.12.10}/workflows/PUBLISHING.md +0 -0
  456. {specify_cli-0.12.9 → specify_cli-0.12.10}/workflows/README.md +0 -0
  457. {specify_cli-0.12.9 → specify_cli-0.12.10}/workflows/catalog.community.json +0 -0
  458. {specify_cli-0.12.9 → specify_cli-0.12.10}/workflows/catalog.json +0 -0
  459. {specify_cli-0.12.9 → specify_cli-0.12.10}/workflows/speckit/workflow.yml +0 -0
  460. {specify_cli-0.12.9 → specify_cli-0.12.10}/workflows/step-catalog.community.json +0 -0
  461. {specify_cli-0.12.9 → specify_cli-0.12.10}/workflows/step-catalog.json +0 -0
@@ -37,7 +37,7 @@ jobs:
37
37
  fi
38
38
 
39
39
  - name: Run markdownlint-cli2
40
- uses: DavidAnson/markdownlint-cli2-action@ded1f9488f68a970bc66ea5619e13e9b52e601cd # v23
40
+ uses: DavidAnson/markdownlint-cli2-action@8de2aa07cae85fd17c0b35642db70cf5495f1d25 # v24.0.0
41
41
  with:
42
42
  globs: |
43
43
  '**/*.md'
@@ -32,7 +32,7 @@ jobs:
32
32
  ref: refs/tags/${{ inputs.tag }}
33
33
 
34
34
  - name: Install uv
35
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
35
+ uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
36
36
 
37
37
  - name: Set up Python
38
38
  uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
@@ -74,7 +74,7 @@ jobs:
74
74
  path: dist/
75
75
 
76
76
  - name: Install uv
77
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
77
+ uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
78
78
 
79
79
  - name: Publish to PyPI
80
80
  run: uv publish
@@ -16,7 +16,7 @@ jobs:
16
16
  uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
17
17
 
18
18
  - name: Install uv
19
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
19
+ uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
20
20
 
21
21
  - name: Set up Python
22
22
  uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
@@ -37,7 +37,7 @@ jobs:
37
37
  uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
38
38
 
39
39
  - name: Install uv
40
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
40
+ uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
41
41
 
42
42
  - name: Set up Python ${{ matrix.python-version }}
43
43
  uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
@@ -2,6 +2,21 @@
2
2
 
3
3
  <!-- insert new changelog below this comment -->
4
4
 
5
+ ## [0.12.10] - 2026-07-10
6
+
7
+ ### Changed
8
+
9
+ - chore(deps): bump astral-sh/setup-uv from 8.2.0 to 8.3.2 (#3439)
10
+ - chore(deps): bump DavidAnson/markdownlint-cli2-action (#3438)
11
+ - fix(templates): correct phase numbering in plan.md (#3416)
12
+ - fix(git-ext): honor explicit -Number 0 in PowerShell branch creation (#3412)
13
+ - docs: add 'spectatui' entry to friends.md (#3362)
14
+ - test: pin interpreter probe so py-template render test passes on Windows (#3428)
15
+ - feat(workflows): make shell step timeout configurable (#3404)
16
+ - fix: find plans in nested spec directories (#3405)
17
+ - feat(templates): add py: lines to command templates' scripts frontmatter (#3403)
18
+ - chore: release 0.12.9, begin 0.12.10.dev0 development (#3426)
19
+
5
20
  ## [0.12.9] - 2026-07-09
6
21
 
7
22
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specify-cli
3
- Version: 0.12.9
3
+ Version: 0.12.10
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
@@ -14,3 +14,5 @@ Community projects that extend, visualize, or build on Spec Kit:
14
14
  - **[SpecKit Companion](https://marketplace.visualstudio.com/items?itemName=alfredoperez.speckit-companion)** — A VS Code extension that brings a visual GUI to Spec Kit. Browse specs in a rich markdown viewer with clickable file references, create specifications with image attachments, comment and refine each step inline (GitHub-style review), track your progress through the SDD workflow with a visual phase stepper, and manage steering documents like constitutions and templates.
15
15
 
16
16
  - **[cc-spec-kit](https://github.com/speckit-community/cc-spec-kit)** — Community-maintained plugin for Claude Code and GitHub Copilot CLI that installs Spec Kit skills via the plugin marketplace.
17
+
18
+ - **[spectatui](https://github.com/tinesoft/spectatui)** — A terminal UI (TUI) dashboard for Spec Kit that lets you track features, manage specifications, integrations, presets, workflows, and extensions, and monitor AI agent workflows. Attach to existing AI sessions or launch new ones from your terminal. Keyboard and mouse support. Light/dark theme support. Customizable and performance-oriented. Requires the `specify` CLI in your PATH.
@@ -15,7 +15,7 @@ The script reads the agent-context extension config at
15
15
  - `context_files` — optional project-relative paths for multiple coding agent context files. When non-empty, the script updates each listed file and the list takes precedence over `context_file`.
16
16
  - `context_markers.start` / `.end` — the delimiters surrounding the managed section. Defaults to `<!-- SPECKIT START -->` and `<!-- SPECKIT END -->` when the field is missing.
17
17
 
18
- It then creates, replaces, or appends the managed block so that the section points at the most recent plan path when one can be discovered (`specs/<feature>/plan.md`).
18
+ It then creates, replaces, or appends the managed block so that the section points at the most recent plan path when one can be discovered (`specs/**/plan.md`, any depth).
19
19
 
20
20
  If `context_files` and `context_file` are empty, the command reports nothing to do and exits successfully. Context file paths must stay project-relative; absolute paths, Windows drive paths, backslash separators, and `..` path segments are rejected.
21
21
 
@@ -24,4 +24,4 @@ If `context_files` and `context_file` are empty, the command reports nothing to
24
24
  - **Bash**: `.specify/extensions/agent-context/scripts/bash/update-agent-context.sh [plan_path]`
25
25
  - **PowerShell**: `.specify/extensions/agent-context/scripts/powershell/update-agent-context.ps1 [plan_path]`
26
26
 
27
- When `plan_path` is omitted, the script auto-detects the most recently modified `specs/*/plan.md`.
27
+ When `plan_path` is omitted, the script auto-detects the most recently modified `specs/**/plan.md` (any depth, so scoped layouts like `specs/<scope>/<feature>/plan.md` are found).
@@ -12,7 +12,7 @@
12
12
  #
13
13
  # When `plan_path` is omitted, the script derives it from `.specify/feature.json`
14
14
  # (written by /speckit-specify). Falls back to the most recently modified
15
- # `specs/*/plan.md` only when feature.json is absent or its plan does not exist yet.
15
+ # `specs/**/plan.md` only when feature.json is absent or its plan does not exist yet.
16
16
 
17
17
  set -euo pipefail
18
18
 
@@ -307,14 +307,14 @@ import sys
307
307
  from pathlib import Path
308
308
  root = Path(sys.argv[1]).resolve()
309
309
  specs = root / "specs"
310
- plans = sorted(
311
- specs.glob("*/plan.md"),
310
+ plan = max(
311
+ specs.glob("**/plan.md"),
312
312
  key=lambda p: p.stat().st_mtime,
313
- reverse=True,
313
+ default=None,
314
314
  )
315
- if plans:
315
+ if plan:
316
316
  try:
317
- print(plans[0].relative_to(root).as_posix())
317
+ print(plan.relative_to(root).as_posix())
318
318
  except ValueError:
319
319
  print("")
320
320
  else:
@@ -12,7 +12,7 @@
12
12
  #
13
13
  # When `plan_path` is omitted, the script derives it from `.specify/feature.json`
14
14
  # (written by /speckit-specify). Falls back to the most recently modified
15
- # `specs/*/plan.md` only when feature.json is absent or its plan does not exist yet.
15
+ # `specs/**/plan.md` only when feature.json is absent or its plan does not exist yet.
16
16
 
17
17
  [CmdletBinding()]
18
18
  param(
@@ -426,9 +426,7 @@ if (-not $PlanPath) {
426
426
  if (-not $PlanPath) {
427
427
  try {
428
428
  $specsDir = Join-Path $ProjectRoot 'specs'
429
- $candidate = Get-ChildItem -Path $specsDir -Directory -ErrorAction SilentlyContinue |
430
- ForEach-Object { Get-Item -LiteralPath (Join-Path $_.FullName 'plan.md') -ErrorAction SilentlyContinue } |
431
- Where-Object { $_ } |
429
+ $candidate = Get-ChildItem -Path $specsDir -Recurse -File -Filter 'plan.md' -ErrorAction SilentlyContinue |
432
430
  Sort-Object LastWriteTime -Descending |
433
431
  Select-Object -First 1
434
432
  if ($candidate) {
@@ -446,7 +446,10 @@ if ($env:GIT_BRANCH_NAME) {
446
446
  $branchSuffix = Get-BranchName -Description $featureDesc
447
447
  }
448
448
 
449
- if ($Timestamp -and $Number -ne 0) {
449
+ # Warn if -Number and -Timestamp are both specified. Use ContainsKey (not
450
+ # `-ne 0`) so an explicit `-Number 0` is also detected, matching the bash twin's
451
+ # `[ -n "$BRANCH_NUMBER" ]` check.
452
+ if ($Timestamp -and $PSBoundParameters.ContainsKey('Number')) {
450
453
  Write-Warning "[specify] Warning: -Number is ignored when -Timestamp is used"
451
454
  $Number = 0
452
455
  }
@@ -456,7 +459,10 @@ if ($env:GIT_BRANCH_NAME) {
456
459
  $branchName = New-BranchName -FeatureNum $featureNum -BranchSuffix $branchSuffix
457
460
  } else {
458
461
  $branchScopePrefix = Get-BranchScopePrefix -Template $branchTemplate -BranchSuffix $branchSuffix
459
- if ($Number -eq 0) {
462
+ # Auto-detect the next number only when -Number was not supplied; an
463
+ # explicit value (including 0) is honored, matching the bash twin's
464
+ # `[ -z "$BRANCH_NUMBER" ]` check.
465
+ if (-not $PSBoundParameters.ContainsKey('Number')) {
460
466
  if ($DryRun -and $hasGit) {
461
467
  $Number = Get-NextBranchNumber -SpecsDir $specsDir -SkipFetch -ScopePrefix $branchScopePrefix
462
468
  } elseif ($DryRun) {
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "specify-cli"
3
- version = "0.12.9"
3
+ version = "0.12.10"
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"
@@ -141,8 +141,9 @@ def _install_shared_infra(
141
141
 
142
142
  Copies ``.specify/scripts/<variant>/`` and ``.specify/templates/`` from
143
143
  the bundled core_pack or source checkout, where ``<variant>`` is
144
- ``bash`` when *script_type* is ``"sh"`` and ``powershell`` when it is
145
- ``"ps"``. Tracks all installed files in ``speckit.manifest.json``.
144
+ ``bash`` when *script_type* is ``"sh"``, ``python`` when it is ``"py"``,
145
+ and ``powershell`` when it is ``"ps"``. Tracks all installed files in
146
+ ``speckit.manifest.json``.
146
147
 
147
148
  Shared scripts and page templates are processed to resolve
148
149
  ``__SPECKIT_COMMAND_<NAME>__`` placeholders using *invoke_separator*
@@ -403,7 +403,7 @@ def install_shared_infra(
403
403
  # manifest entries the core no longer ships (stale-script cleanup, #3076).
404
404
  seen_rels: set[str] = set()
405
405
  scripts_scanned = False
406
- variant_dir = "bash" if script_type == "sh" else "powershell"
406
+ variant_dir = {"sh": "bash", "py": "python"}.get(script_type, "powershell")
407
407
 
408
408
  def _decide_overwrite(rel: str, dst: Path) -> tuple[bool, str | None]:
409
409
  """Return (write, bucket) where bucket is 'skip', 'preserved', or None."""
@@ -465,6 +465,10 @@ def install_shared_infra(
465
465
  for src_path in variant_src.rglob("*"):
466
466
  if not src_path.is_file():
467
467
  continue
468
+ # Python bytecode caches are local artifacts, not
469
+ # workflow scripts — never install them.
470
+ if "__pycache__" in src_path.parts:
471
+ continue
468
472
  # Mark scanned only once a real source file is seen. An
469
473
  # empty (or symlink-skipped) variant keeps this False, so
470
474
  # stale-cleanup is skipped — otherwise it would treat every
@@ -25,6 +25,14 @@ class ShellStep(StepBase):
25
25
  run_cmd = str(run_cmd)
26
26
 
27
27
  cwd = context.project_root or "."
28
+ # Defensive: the engine does not auto-validate step config, so an
29
+ # invalid ``timeout`` (string, None, ...) would otherwise raise a
30
+ # TypeError from subprocess.run() and crash the whole run. Mirror
31
+ # the engine's handling of unvalidated ``continue_on_error`` by
32
+ # only honoring well-formed values and falling back to the default.
33
+ timeout = config.get("timeout", 300)
34
+ if isinstance(timeout, bool) or not isinstance(timeout, int) or timeout <= 0:
35
+ timeout = 300
28
36
 
29
37
  # NOTE: shell=True is required to support pipes, redirects, and
30
38
  # multi-command expressions in workflow YAML. Workflow authors
@@ -37,7 +45,7 @@ class ShellStep(StepBase):
37
45
  capture_output=True,
38
46
  text=True,
39
47
  cwd=cwd,
40
- timeout=300,
48
+ timeout=timeout,
41
49
  )
42
50
  output = {
43
51
  "exit_code": proc.returncode,
@@ -74,7 +82,7 @@ class ShellStep(StepBase):
74
82
  except subprocess.TimeoutExpired:
75
83
  return StepResult(
76
84
  status=StepStatus.FAILED,
77
- error="Shell command timed out after 300 seconds.",
85
+ error=f"Shell command timed out after {timeout} seconds.",
78
86
  output={"exit_code": -1, "stdout": "", "stderr": "timeout"},
79
87
  )
80
88
  except OSError as exc:
@@ -106,4 +114,16 @@ class ShellStep(StepBase):
106
114
  f"Shell step {config.get('id', '?')!r}: 'output_format' must "
107
115
  f"be 'json' when present, got {output_format!r}."
108
116
  )
117
+ if "timeout" in config:
118
+ timeout = config["timeout"]
119
+ # bool is an int subclass, so reject it explicitly.
120
+ if (
121
+ isinstance(timeout, bool)
122
+ or not isinstance(timeout, int)
123
+ or timeout <= 0
124
+ ):
125
+ errors.append(
126
+ f"Shell step {config.get('id', '?')!r}: 'timeout' must be a "
127
+ f"positive integer (seconds) when present, got {timeout!r}."
128
+ )
109
129
  return errors
@@ -3,6 +3,7 @@ description: Perform a non-destructive cross-artifact consistency and quality an
3
3
  scripts:
4
4
  sh: scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks
5
5
  ps: scripts/powershell/check-prerequisites.ps1 -Json -RequireTasks -IncludeTasks
6
+ py: scripts/python/check_prerequisites.py --json --require-tasks --include-tasks
6
7
  ---
7
8
 
8
9
  ## User Input
@@ -3,6 +3,7 @@ description: Generate a custom checklist for the current feature based on user r
3
3
  scripts:
4
4
  sh: scripts/bash/check-prerequisites.sh --json
5
5
  ps: scripts/powershell/check-prerequisites.ps1 -Json
6
+ py: scripts/python/check_prerequisites.py --json
6
7
  ---
7
8
 
8
9
  ## Checklist Purpose: "Unit Tests for English"
@@ -7,6 +7,7 @@ handoffs:
7
7
  scripts:
8
8
  sh: scripts/bash/check-prerequisites.sh --json --paths-only
9
9
  ps: scripts/powershell/check-prerequisites.ps1 -Json -PathsOnly
10
+ py: scripts/python/check_prerequisites.py --json --paths-only
10
11
  ---
11
12
 
12
13
  ## User Input
@@ -3,6 +3,7 @@ description: Assess the current codebase against the feature's spec, plan, and t
3
3
  scripts:
4
4
  sh: scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks
5
5
  ps: scripts/powershell/check-prerequisites.ps1 -Json -RequireTasks -IncludeTasks
6
+ py: scripts/python/check_prerequisites.py --json --require-tasks --include-tasks
6
7
  ---
7
8
 
8
9
  ## User Input
@@ -3,6 +3,7 @@ description: Execute the implementation plan by processing and executing all tas
3
3
  scripts:
4
4
  sh: scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks
5
5
  ps: scripts/powershell/check-prerequisites.ps1 -Json -RequireTasks -IncludeTasks
6
+ py: scripts/python/check_prerequisites.py --json --require-tasks --include-tasks
6
7
  ---
7
8
 
8
9
  ## User Input
@@ -68,7 +68,6 @@ You **MUST** consider the user input before proceeding (if not empty).
68
68
  - Evaluate gates (ERROR if violations unjustified)
69
69
  - Phase 0: Generate research.md (resolve all NEEDS CLARIFICATION)
70
70
  - Phase 1: Generate data-model.md, contracts/, quickstart.md
71
- - Phase 1: Update agent context by running the agent script
72
71
  - Re-evaluate Constitution Check post-design
73
72
 
74
73
  ## Mandatory Post-Execution Hooks
@@ -107,7 +106,7 @@ Check if `.specify/extensions.yml` exists in the project root.
107
106
 
108
107
  ## Completion Report
109
108
 
110
- Command ends after Phase 2 planning. Report branch, IMPL_PLAN path, and generated artifacts.
109
+ Command ends after Phase 1 design. Report branch, IMPL_PLAN path, and generated artifacts.
111
110
 
112
111
  ## Phases
113
112
 
@@ -4,6 +4,7 @@ tools: ['github/github-mcp-server/list_issues', 'github/github-mcp-server/issue_
4
4
  scripts:
5
5
  sh: scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks
6
6
  ps: scripts/powershell/check-prerequisites.ps1 -Json -RequireTasks -IncludeTasks
7
+ py: scripts/python/check_prerequisites.py --json --require-tasks --include-tasks
7
8
  ---
8
9
 
9
10
  ## User Input
@@ -638,6 +638,21 @@ class TestCreateFeatureBash:
638
638
  assert result.returncode != 0
639
639
  assert "requires updated Spec Kit core scripts" in result.stderr
640
640
 
641
+ def test_explicit_number_zero_is_honored(self, tmp_path: Path):
642
+ """An explicit --number 0 is honored (yields 000), not treated as
643
+ 'auto-detect'. Pins the canonical behavior the PowerShell twin must
644
+ mirror; the empty-string check (`[ -z "$BRANCH_NUMBER" ]`) already
645
+ distinguishes an unset flag from a supplied 0."""
646
+ project = _setup_project(tmp_path)
647
+ result = _run_bash(
648
+ "create-new-feature-branch.sh", project,
649
+ "--json", "--dry-run", "--number", "0", "--short-name", "zero", "Zero feature",
650
+ )
651
+ assert result.returncode == 0, result.stderr
652
+ data = json.loads(result.stdout)
653
+ assert data["BRANCH_NAME"] == "000-zero"
654
+ assert data["FEATURE_NUM"] == "000"
655
+
641
656
 
642
657
  @pytest.mark.skipif(not HAS_PWSH, reason="pwsh not available")
643
658
  class TestCreateFeaturePowerShell:
@@ -942,6 +957,23 @@ class TestCreateFeaturePowerShell:
942
957
  assert result.returncode != 0
943
958
  assert "requires updated Spec Kit core scripts" in result.stderr
944
959
 
960
+ def test_explicit_number_zero_is_honored(self, tmp_path: Path):
961
+ """An explicit -Number 0 is honored (yields 000), matching the bash twin's
962
+ --number 0. Regression guard: -Number defaults to 0, so a bare `-eq 0`
963
+ check cannot tell an unset flag from a supplied 0 and would silently
964
+ auto-detect instead. Uses PSBoundParameters.ContainsKey('Number')."""
965
+ project = _setup_project(tmp_path)
966
+ result = _run_pwsh(
967
+ "create-new-feature-branch.ps1", project,
968
+ "-Json", "-DryRun", "-Number", "0", "-ShortName", "zero", "Zero feature",
969
+ )
970
+ assert result.returncode == 0, result.stderr
971
+ json_line = [ln for ln in result.stdout.splitlines() if ln.strip().startswith("{")]
972
+ assert json_line, f"No JSON in output: {result.stdout}"
973
+ data = json.loads(json_line[-1])
974
+ assert data["BRANCH_NAME"] == "000-zero"
975
+ assert data["FEATURE_NUM"] == "000"
976
+
945
977
 
946
978
  # ── auto-commit.sh Tests ─────────────────────────────────────────────────────
947
979
 
@@ -688,6 +688,62 @@ class TestExtensionSelfSeed:
688
688
  _MDC_CONTEXT_FILE = ".cursor/rules/specify-rules.mdc"
689
689
 
690
690
 
691
+ class TestPlanDiscovery:
692
+ """Mtime fallback must find plans in nested spec layouts (#3024).
693
+
694
+ Repos using SPECIFY_FEATURE_DIRECTORY place plans at
695
+ ``specs/<scope>/<feature>/plan.md``; a one-level ``specs/*/plan.md``
696
+ glob never matches those.
697
+ """
698
+
699
+ @staticmethod
700
+ def _make_plans(project: Path) -> Path:
701
+ # Older flat plan plus a newer nested plan: recursive discovery
702
+ # must pick the nested one by mtime.
703
+ flat = project / "specs" / "old-feature" / "plan.md"
704
+ flat.parent.mkdir(parents=True)
705
+ flat.write_text("flat plan\n", encoding="utf-8")
706
+ os.utime(flat, (1_000_000_000, 1_000_000_000))
707
+ nested = project / "specs" / "scope" / "new-feature" / "plan.md"
708
+ nested.parent.mkdir(parents=True)
709
+ nested.write_text("nested plan\n", encoding="utf-8")
710
+ return nested
711
+
712
+ @requires_bash
713
+ def test_bash_script_finds_nested_plan(self, tmp_path):
714
+ project = tmp_path / "project"
715
+ project.mkdir()
716
+ _install_agent_context_config(
717
+ project,
718
+ context_file="AGENTS.md",
719
+ context_files=["AGENTS.md"],
720
+ )
721
+ self._make_plans(project)
722
+
723
+ result = _run_bash_agent_context_script(project)
724
+
725
+ assert result.returncode == 0, result.stderr + result.stdout
726
+ content = (project / "AGENTS.md").read_text(encoding="utf-8")
727
+ assert "specs/scope/new-feature/plan.md" in content
728
+
729
+ @pytest.mark.skipif(POWERSHELL is None, reason="PowerShell not available")
730
+ def test_powershell_script_finds_nested_plan(self, tmp_path):
731
+ project = tmp_path / "project"
732
+ project.mkdir()
733
+ _install_agent_context_config(
734
+ project,
735
+ context_file="AGENTS.md",
736
+ context_files=["AGENTS.md"],
737
+ )
738
+ self._make_plans(project)
739
+
740
+ result = _run_powershell_agent_context_script(project)
741
+
742
+ assert result.returncode == 0, result.stderr + result.stdout
743
+ content = (project / "AGENTS.md").read_text(encoding="utf-8")
744
+ assert "specs/scope/new-feature/plan.md" in content
745
+
746
+
691
747
  class TestMdcFrontmatter:
692
748
  """Cursor-style ``.mdc`` targets must carry ``alwaysApply: true`` frontmatter
693
749
  so the rule file is auto-loaded; non-``.mdc`` targets must not gain any."""
@@ -0,0 +1,107 @@
1
+ """Command templates with a py: script line must render for --script py.
2
+
3
+ Covers #3283: ``py:`` lines in the ``scripts:`` frontmatter of
4
+ ``templates/commands/*.md`` reference Python scripts that exist in the repo,
5
+ and ``process_template`` turns them into a valid Python invocation
6
+ (interpreter-prefixed, path rewritten to the ``.specify`` tree).
7
+
8
+ ``plan.md`` and ``tasks.md`` gain their ``py:`` lines together with
9
+ ``setup_plan.py``/``setup_tasks.py`` in the core-scripts port (#3280); the
10
+ existence check below enforces that ordering.
11
+ """
12
+
13
+ import re
14
+ from pathlib import Path
15
+
16
+ import pytest
17
+
18
+ from specify_cli.integrations.base import IntegrationBase
19
+
20
+ REPO_ROOT = Path(__file__).parent.parent
21
+ TEMPLATES_DIR = REPO_ROOT / "templates" / "commands"
22
+
23
+ _PY_LINE = re.compile(r"^\s*py: (scripts/python/\S+\.py)", re.MULTILINE)
24
+
25
+
26
+ def _py_script(name: str) -> str | None:
27
+ match = _PY_LINE.search((TEMPLATES_DIR / name).read_text(encoding="utf-8"))
28
+ return match.group(1) if match else None
29
+
30
+
31
+ PY_TEMPLATES = sorted(
32
+ p.name for p in TEMPLATES_DIR.glob("*.md") if _py_script(p.name)
33
+ )
34
+
35
+
36
+ @pytest.fixture(autouse=True)
37
+ def _pin_interpreter(monkeypatch):
38
+ monkeypatch.setattr(
39
+ "specify_cli.integrations.base.shutil.which",
40
+ lambda name: "/usr/bin/python3" if name == "python3" else None,
41
+ )
42
+ # On Windows, ``resolve_python_interpreter`` guards the ``which`` result
43
+ # with a real ``_interpreter_runs`` subprocess probe (#3304). The mocked
44
+ # ``/usr/bin/python3`` path does not exist on a Windows runner, so the
45
+ # probe would fail and the resolver would fall back to ``sys.executable``
46
+ # (a ``...python.exe`` path), breaking the ``python3``-anchored assertion.
47
+ # Pin the probe to True so the interpreter token stays ``python3`` on all
48
+ # platforms.
49
+ monkeypatch.setattr(
50
+ "specify_cli.integrations.base.IntegrationBase._interpreter_runs",
51
+ staticmethod(lambda path: True),
52
+ )
53
+
54
+
55
+ def test_py_templates_discovered():
56
+ # Guard: the glob must find the known py-scripted templates, otherwise
57
+ # the parametrized tests below would silently pass on an empty set.
58
+ assert "implement.md" in PY_TEMPLATES
59
+ assert "clarify.md" in PY_TEMPLATES
60
+
61
+
62
+ @pytest.mark.parametrize("name", PY_TEMPLATES)
63
+ def test_referenced_python_script_exists(name: str):
64
+ # A py: line must never point at a script the repo does not ship —
65
+ # rendering would produce a broken invocation at runtime.
66
+ script = _py_script(name)
67
+ assert (REPO_ROOT / script).is_file(), f"{name} references missing {script}"
68
+
69
+
70
+ @pytest.mark.parametrize("name", PY_TEMPLATES)
71
+ def test_template_renders_python_invocation(name: str):
72
+ content = (TEMPLATES_DIR / name).read_text(encoding="utf-8")
73
+ result = IntegrationBase.process_template(content, "agent", "py")
74
+ assert "{SCRIPT}" not in result
75
+ assert re.search(
76
+ r"python3 \.specify/scripts/python/\w+\.py(?: --[\w-]+)*", result
77
+ ), f"{name} did not render a Python invocation"
78
+
79
+
80
+ @pytest.mark.parametrize("name", PY_TEMPLATES)
81
+ def test_sh_rendering_unchanged(name: str):
82
+ # Negative: adding py: lines must not leak into sh rendering.
83
+ content = (TEMPLATES_DIR / name).read_text(encoding="utf-8")
84
+ result = IntegrationBase.process_template(content, "agent", "sh")
85
+ assert "{SCRIPT}" not in result
86
+ assert "scripts/python" not in result
87
+
88
+
89
+ def test_install_shared_infra_copies_python_scripts(tmp_path):
90
+ # --script py must install scripts/python/ into .specify/scripts/python/
91
+ # so the rendered invocations point at files that exist.
92
+ from rich.console import Console
93
+
94
+ from specify_cli.shared_infra import install_shared_infra
95
+
96
+ install_shared_infra(
97
+ tmp_path,
98
+ "py",
99
+ version="0.0.0",
100
+ core_pack=None,
101
+ repo_root=REPO_ROOT,
102
+ console=Console(quiet=True),
103
+ force=False,
104
+ )
105
+ dest = tmp_path / ".specify" / "scripts" / "python"
106
+ assert (dest / "check_prerequisites.py").is_file()
107
+ assert not (tmp_path / ".specify" / "scripts" / "powershell").exists()