specify-cli 0.12.8__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 (462) hide show
  1. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/lint.yml +1 -1
  2. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/publish-pypi.yml +2 -2
  3. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/test.yml +2 -2
  4. {specify_cli-0.12.8 → specify_cli-0.12.10}/CHANGELOG.md +30 -0
  5. {specify_cli-0.12.8 → specify_cli-0.12.10}/PKG-INFO +1 -1
  6. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/extensions.md +1 -1
  7. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/friends.md +2 -0
  8. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/commands/speckit.agent-context.update.md +2 -2
  9. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/scripts/bash/update-agent-context.sh +6 -6
  10. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +2 -4
  11. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/catalog.community.json +9 -6
  12. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/powershell/create-new-feature-branch.ps1 +8 -2
  13. {specify_cli-0.12.8 → specify_cli-0.12.10}/pyproject.toml +1 -1
  14. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/bash/common.sh +66 -11
  15. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/__init__.py +3 -2
  16. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/agents.py +6 -0
  17. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/primitives.py +49 -6
  18. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/base.py +55 -15
  19. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/hermes/__init__.py +9 -11
  20. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/shared_infra.py +10 -3
  21. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/expressions.py +91 -57
  22. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/shell/__init__.py +22 -2
  23. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/analyze.md +1 -0
  24. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/checklist.md +1 -0
  25. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/clarify.md +1 -0
  26. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/converge.md +1 -0
  27. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/implement.md +1 -0
  28. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/plan.md +1 -2
  29. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/taskstoissues.md +1 -0
  30. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/git/test_git_extension.py +32 -0
  31. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/test_extension_agent_context.py +56 -0
  32. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/conftest.py +24 -4
  33. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_base.py +72 -0
  34. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_cli.py +41 -0
  35. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_home_isolation.py +4 -0
  36. specify_cli-0.12.10/tests/integrations/test_integration_goose.py +85 -0
  37. specify_cli-0.12.10/tests/integrations/test_skill_frontmatter_quoting.py +111 -0
  38. specify_cli-0.12.10/tests/test_command_template_py_scripts.py +107 -0
  39. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_setup_tasks.py +62 -0
  40. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_workflows.py +167 -0
  41. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_primitives.py +84 -0
  42. specify_cli-0.12.8/tests/integrations/test_integration_goose.py +0 -38
  43. {specify_cli-0.12.8 → specify_cli-0.12.10}/.devcontainer/devcontainer.json +0 -0
  44. {specify_cli-0.12.8 → specify_cli-0.12.10}/.devcontainer/post-create.sh +0 -0
  45. {specify_cli-0.12.8 → specify_cli-0.12.10}/.editorconfig +0 -0
  46. {specify_cli-0.12.8 → specify_cli-0.12.10}/.gitattributes +0 -0
  47. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/CODEOWNERS +0 -0
  48. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/agent_request.yml +0 -0
  49. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  50. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/bundle_submission.yml +0 -0
  51. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  52. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/extension_submission.yml +0 -0
  53. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  54. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/preset_submission.yml +0 -0
  55. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  56. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/aw/actions-lock.json +0 -0
  57. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/dependabot.yml +0 -0
  58. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/skills/add-community-extension/SKILL.md +0 -0
  59. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/RELEASE-PROCESS.md +0 -0
  60. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/add-community-extension.lock.yml +0 -0
  61. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/add-community-extension.md +0 -0
  62. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/add-community-preset.lock.yml +0 -0
  63. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/add-community-preset.md +0 -0
  64. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-assess.lock.yml +0 -0
  65. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-assess.md +0 -0
  66. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-fix.lock.yml +0 -0
  67. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-fix.md +0 -0
  68. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-test.lock.yml +0 -0
  69. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-test.md +0 -0
  70. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/catalog-assign.yml +0 -0
  71. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/codeql.yml +0 -0
  72. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/docs.yml +0 -0
  73. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/release-trigger.yml +0 -0
  74. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/release.yml +0 -0
  75. {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/stale.yml +0 -0
  76. {specify_cli-0.12.8 → specify_cli-0.12.10}/.gitignore +0 -0
  77. {specify_cli-0.12.8 → specify_cli-0.12.10}/.markdownlint-cli2.jsonc +0 -0
  78. {specify_cli-0.12.8 → specify_cli-0.12.10}/.zenodo.json +0 -0
  79. {specify_cli-0.12.8 → specify_cli-0.12.10}/AGENTS.md +0 -0
  80. {specify_cli-0.12.8 → specify_cli-0.12.10}/CITATION.cff +0 -0
  81. {specify_cli-0.12.8 → specify_cli-0.12.10}/CODE_OF_CONDUCT.md +0 -0
  82. {specify_cli-0.12.8 → specify_cli-0.12.10}/CONTRIBUTING.md +0 -0
  83. {specify_cli-0.12.8 → specify_cli-0.12.10}/DEVELOPMENT.md +0 -0
  84. {specify_cli-0.12.8 → specify_cli-0.12.10}/LICENSE +0 -0
  85. {specify_cli-0.12.8 → specify_cli-0.12.10}/README.md +0 -0
  86. {specify_cli-0.12.8 → specify_cli-0.12.10}/SECURITY.md +0 -0
  87. {specify_cli-0.12.8 → specify_cli-0.12.10}/SUPPORT.md +0 -0
  88. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/.gitignore +0 -0
  89. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/README.md +0 -0
  90. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/bundles.md +0 -0
  91. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/overview.md +0 -0
  92. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/presets.md +0 -0
  93. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/walkthroughs.md +0 -0
  94. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/concepts/complex-features.md +0 -0
  95. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/concepts/sdd.md +0 -0
  96. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/concepts/spec-persistence.md +0 -0
  97. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/docfx.json +0 -0
  98. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/guides/evolving-specs.md +0 -0
  99. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/guides/monorepo.md +0 -0
  100. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/index.md +0 -0
  101. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/install/air-gapped.md +0 -0
  102. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/install/one-time.md +0 -0
  103. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/install/pipx.md +0 -0
  104. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/install/uv.md +0 -0
  105. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/installation.md +0 -0
  106. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/local-development.md +0 -0
  107. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/quickstart.md +0 -0
  108. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/authentication.md +0 -0
  109. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/bundles.md +0 -0
  110. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/core.md +0 -0
  111. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/extensions.md +0 -0
  112. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/integrations.md +0 -0
  113. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/overview.md +0 -0
  114. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/presets.md +0 -0
  115. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/workflows.md +0 -0
  116. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/template/public/main.css +0 -0
  117. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/toc.yml +0 -0
  118. {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/upgrade.md +0 -0
  119. {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/business-analyst/README.md +0 -0
  120. {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/business-analyst/bundle.yml +0 -0
  121. {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/developer/README.md +0 -0
  122. {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/developer/bundle.yml +0 -0
  123. {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/product-manager/README.md +0 -0
  124. {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/product-manager/bundle.yml +0 -0
  125. {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/security-researcher/README.md +0 -0
  126. {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/security-researcher/bundle.yml +0 -0
  127. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/EXTENSION-API-REFERENCE.md +0 -0
  128. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/EXTENSION-DEVELOPMENT-GUIDE.md +0 -0
  129. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/EXTENSION-PUBLISHING-GUIDE.md +0 -0
  130. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/EXTENSION-USER-GUIDE.md +0 -0
  131. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/README.md +0 -0
  132. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/RFC-EXTENSION-SYSTEM.md +0 -0
  133. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/README.md +0 -0
  134. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/agent-context-config.yml +0 -0
  135. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/agent-context-defaults.json +0 -0
  136. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/extension.yml +0 -0
  137. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/scripts/python/update_agent_context.py +0 -0
  138. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/bug/README.md +0 -0
  139. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/bug/commands/speckit.bug.assess.md +0 -0
  140. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/bug/commands/speckit.bug.fix.md +0 -0
  141. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/bug/commands/speckit.bug.test.md +0 -0
  142. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/bug/extension.yml +0 -0
  143. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/catalog.json +0 -0
  144. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/README.md +0 -0
  145. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.commit.md +0 -0
  146. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.feature.md +0 -0
  147. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.initialize.md +0 -0
  148. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.remote.md +0 -0
  149. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.validate.md +0 -0
  150. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/config-template.yml +0 -0
  151. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/extension.yml +0 -0
  152. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/git-config.yml +0 -0
  153. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/bash/auto-commit.sh +0 -0
  154. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/bash/create-new-feature-branch.sh +0 -0
  155. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/bash/git-common.sh +0 -0
  156. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/bash/initialize-repo.sh +0 -0
  157. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
  158. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/powershell/git-common.ps1 +0 -0
  159. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
  160. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/selftest/commands/selftest.md +0 -0
  161. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/selftest/extension.yml +0 -0
  162. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/.gitignore +0 -0
  163. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/CHANGELOG.md +0 -0
  164. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/EXAMPLE-README.md +0 -0
  165. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/LICENSE +0 -0
  166. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/README.md +0 -0
  167. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/commands/example.md +0 -0
  168. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/config-template.yml +0 -0
  169. {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/extension.yml +0 -0
  170. {specify_cli-0.12.8 → specify_cli-0.12.10}/integrations/CONTRIBUTING.md +0 -0
  171. {specify_cli-0.12.8 → specify_cli-0.12.10}/integrations/README.md +0 -0
  172. {specify_cli-0.12.8 → specify_cli-0.12.10}/integrations/catalog.community.json +0 -0
  173. {specify_cli-0.12.8 → specify_cli-0.12.10}/integrations/catalog.json +0 -0
  174. {specify_cli-0.12.8 → specify_cli-0.12.10}/media/bootstrap-claude-code.gif +0 -0
  175. {specify_cli-0.12.8 → specify_cli-0.12.10}/media/logo_large.webp +0 -0
  176. {specify_cli-0.12.8 → specify_cli-0.12.10}/media/logo_small.webp +0 -0
  177. {specify_cli-0.12.8 → specify_cli-0.12.10}/media/spec-kit-video-header.jpg +0 -0
  178. {specify_cli-0.12.8 → specify_cli-0.12.10}/media/specify_cli.gif +0 -0
  179. {specify_cli-0.12.8 → specify_cli-0.12.10}/newsletters/2026-April.md +0 -0
  180. {specify_cli-0.12.8 → specify_cli-0.12.10}/newsletters/2026-February.md +0 -0
  181. {specify_cli-0.12.8 → specify_cli-0.12.10}/newsletters/2026-June.md +0 -0
  182. {specify_cli-0.12.8 → specify_cli-0.12.10}/newsletters/2026-March.md +0 -0
  183. {specify_cli-0.12.8 → specify_cli-0.12.10}/newsletters/2026-May.md +0 -0
  184. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/ARCHITECTURE.md +0 -0
  185. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/PUBLISHING.md +0 -0
  186. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/README.md +0 -0
  187. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/catalog.community.json +0 -0
  188. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/catalog.json +0 -0
  189. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/README.md +0 -0
  190. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/commands/speckit.constitution.md +0 -0
  191. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/commands/speckit.implement.md +0 -0
  192. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/commands/speckit.plan.md +0 -0
  193. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/commands/speckit.specify.md +0 -0
  194. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/commands/speckit.tasks.md +0 -0
  195. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/preset.yml +0 -0
  196. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/README.md +0 -0
  197. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/commands/speckit.myext.myextcmd.md +0 -0
  198. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/commands/speckit.specify.md +0 -0
  199. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/preset.yml +0 -0
  200. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/templates/myext-template.md +0 -0
  201. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/templates/spec-template.md +0 -0
  202. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/commands/speckit.specify.md +0 -0
  203. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/commands/speckit.wrap-test.md +0 -0
  204. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/preset.yml +0 -0
  205. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/agent-file-template.md +0 -0
  206. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/checklist-template.md +0 -0
  207. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/constitution-template.md +0 -0
  208. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/plan-template.md +0 -0
  209. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/spec-template.md +0 -0
  210. {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/tasks-template.md +0 -0
  211. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/bash/check-prerequisites.sh +0 -0
  212. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/bash/create-new-feature.sh +0 -0
  213. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/bash/setup-plan.sh +0 -0
  214. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/bash/setup-tasks.sh +0 -0
  215. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/powershell/check-prerequisites.ps1 +0 -0
  216. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/powershell/common.ps1 +0 -0
  217. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/powershell/create-new-feature.ps1 +0 -0
  218. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/powershell/setup-plan.ps1 +0 -0
  219. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/powershell/setup-tasks.ps1 +0 -0
  220. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/python/check_prerequisites.py +0 -0
  221. {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/python/common.py +0 -0
  222. {specify_cli-0.12.8 → specify_cli-0.12.10}/spec-driven.md +0 -0
  223. {specify_cli-0.12.8 → specify_cli-0.12.10}/spec-kit.code-workspace +0 -0
  224. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_agent_config.py +0 -0
  225. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_assets.py +0 -0
  226. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_console.py +0 -0
  227. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_github_http.py +0 -0
  228. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_init_options.py +0 -0
  229. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_invocation_style.py +0 -0
  230. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_project.py +0 -0
  231. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_toml_string.py +0 -0
  232. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_utils.py +0 -0
  233. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_version.py +0 -0
  234. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/__init__.py +0 -0
  235. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/azure_devops.py +0 -0
  236. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/base.py +0 -0
  237. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/config.py +0 -0
  238. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/github.py +0 -0
  239. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/http.py +0 -0
  240. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/__init__.py +0 -0
  241. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/commands_impl/__init__.py +0 -0
  242. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/commands_impl/catalog_config.py +0 -0
  243. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/__init__.py +0 -0
  244. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/project.py +0 -0
  245. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/versioning.py +0 -0
  246. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/yamlio.py +0 -0
  247. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/models/__init__.py +0 -0
  248. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/models/catalog.py +0 -0
  249. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/models/manifest.py +0 -0
  250. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/models/records.py +0 -0
  251. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/__init__.py +0 -0
  252. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/adapters.py +0 -0
  253. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/catalog_stack.py +0 -0
  254. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/conflict.py +0 -0
  255. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/installer.py +0 -0
  256. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/packager.py +0 -0
  257. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/references.py +0 -0
  258. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/resolver.py +0 -0
  259. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/validator.py +0 -0
  260. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/catalogs.py +0 -0
  261. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/commands/__init__.py +0 -0
  262. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/commands/bundle/__init__.py +0 -0
  263. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/commands/init.py +0 -0
  264. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/extensions/__init__.py +0 -0
  265. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/extensions/_commands.py +0 -0
  266. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integration_runtime.py +0 -0
  267. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integration_scaffold.py +0 -0
  268. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integration_state.py +0 -0
  269. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integration_status.py +0 -0
  270. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/__init__.py +0 -0
  271. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_commands.py +0 -0
  272. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_helpers.py +0 -0
  273. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_install_commands.py +0 -0
  274. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_migrate_commands.py +0 -0
  275. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_query_commands.py +0 -0
  276. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_scaffold_commands.py +0 -0
  277. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/agy/__init__.py +0 -0
  278. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/amp/__init__.py +0 -0
  279. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/auggie/__init__.py +0 -0
  280. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/bob/__init__.py +0 -0
  281. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/catalog.py +0 -0
  282. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/claude/__init__.py +0 -0
  283. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/cline/__init__.py +0 -0
  284. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/codebuddy/__init__.py +0 -0
  285. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/codex/__init__.py +0 -0
  286. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/copilot/__init__.py +0 -0
  287. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/cursor_agent/__init__.py +0 -0
  288. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/devin/__init__.py +0 -0
  289. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/firebender/__init__.py +0 -0
  290. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/forge/__init__.py +0 -0
  291. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/gemini/__init__.py +0 -0
  292. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/generic/__init__.py +0 -0
  293. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/goose/__init__.py +0 -0
  294. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/junie/__init__.py +0 -0
  295. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/kilocode/__init__.py +0 -0
  296. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/kimi/__init__.py +0 -0
  297. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/kiro_cli/__init__.py +0 -0
  298. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/lingma/__init__.py +0 -0
  299. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/manifest.py +0 -0
  300. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/omp/__init__.py +0 -0
  301. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/opencode/__init__.py +0 -0
  302. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/pi/__init__.py +0 -0
  303. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/qodercli/__init__.py +0 -0
  304. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/qwen/__init__.py +0 -0
  305. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/rovodev/__init__.py +0 -0
  306. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/shai/__init__.py +0 -0
  307. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/tabnine/__init__.py +0 -0
  308. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/trae/__init__.py +0 -0
  309. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/vibe/__init__.py +0 -0
  310. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/zcode/__init__.py +0 -0
  311. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/zed/__init__.py +0 -0
  312. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/presets/__init__.py +0 -0
  313. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/presets/_commands.py +0 -0
  314. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/__init__.py +0 -0
  315. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/_commands.py +0 -0
  316. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/base.py +0 -0
  317. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/catalog.py +0 -0
  318. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/engine.py +0 -0
  319. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/__init__.py +0 -0
  320. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/command/__init__.py +0 -0
  321. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/do_while/__init__.py +0 -0
  322. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/fan_in/__init__.py +0 -0
  323. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/fan_out/__init__.py +0 -0
  324. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/gate/__init__.py +0 -0
  325. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/if_then/__init__.py +0 -0
  326. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/init/__init__.py +0 -0
  327. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/prompt/__init__.py +0 -0
  328. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/switch/__init__.py +0 -0
  329. {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/while_loop/__init__.py +0 -0
  330. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/checklist-template.md +0 -0
  331. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/constitution.md +0 -0
  332. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/specify.md +0 -0
  333. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/tasks.md +0 -0
  334. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/constitution-template.md +0 -0
  335. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/plan-template.md +0 -0
  336. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/spec-template.md +0 -0
  337. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/tasks-template.md +0 -0
  338. {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/vscode-settings.json +0 -0
  339. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/__init__.py +0 -0
  340. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/auth_helpers.py +0 -0
  341. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/bundler_helpers.py +0 -0
  342. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/conftest.py +0 -0
  343. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/contract/test_bundle_cli.py +0 -0
  344. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/contract/test_catalog_schema.py +0 -0
  345. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/contract/test_manifest_schema.py +0 -0
  346. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/__init__.py +0 -0
  347. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/bug/__init__.py +0 -0
  348. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/bug/test_bug_extension.py +0 -0
  349. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/git/__init__.py +0 -0
  350. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/test_agent_context_cli_free.py +0 -0
  351. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/test_update_agent_context_feature_json.py +0 -0
  352. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/test_update_agent_context_python_parity.py +0 -0
  353. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/hooks/TESTING.md +0 -0
  354. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/hooks/plan.md +0 -0
  355. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/hooks/spec.md +0 -0
  356. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/hooks/tasks.md +0 -0
  357. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/http_helpers.py +0 -0
  358. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_catalog_stack.py +0 -0
  359. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_init_install.py +0 -0
  360. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_install_flow.py +0 -0
  361. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_local_install.py +0 -0
  362. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_offline.py +0 -0
  363. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_security_paths.py +0 -0
  364. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/__init__.py +0 -0
  365. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_extra_args.py +0 -0
  366. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_agy.py +0 -0
  367. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_amp.py +0 -0
  368. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_auggie.py +0 -0
  369. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_base_markdown.py +0 -0
  370. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_base_skills.py +0 -0
  371. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_base_toml.py +0 -0
  372. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_base_yaml.py +0 -0
  373. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_bob.py +0 -0
  374. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_catalog.py +0 -0
  375. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_claude.py +0 -0
  376. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_cline.py +0 -0
  377. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_codebuddy.py +0 -0
  378. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_codex.py +0 -0
  379. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_copilot.py +0 -0
  380. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_cursor_agent.py +0 -0
  381. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_devin.py +0 -0
  382. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_firebender.py +0 -0
  383. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_forge.py +0 -0
  384. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_gemini.py +0 -0
  385. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_generic.py +0 -0
  386. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_hermes.py +0 -0
  387. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_junie.py +0 -0
  388. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_kilocode.py +0 -0
  389. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_kimi.py +0 -0
  390. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_kiro_cli.py +0 -0
  391. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_lingma.py +0 -0
  392. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_omp.py +0 -0
  393. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_opencode.py +0 -0
  394. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_pi.py +0 -0
  395. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_qodercli.py +0 -0
  396. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_qwen.py +0 -0
  397. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_rovodev.py +0 -0
  398. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_scaffold.py +0 -0
  399. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_shai.py +0 -0
  400. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_state.py +0 -0
  401. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_subcommand.py +0 -0
  402. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_tabnine.py +0 -0
  403. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_trae.py +0 -0
  404. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_vibe.py +0 -0
  405. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_zcode.py +0 -0
  406. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_zed.py +0 -0
  407. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_manifest.py +0 -0
  408. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_registry.py +0 -0
  409. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/self_upgrade_helpers.py +0 -0
  410. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_agent_config_consistency.py +0 -0
  411. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_authentication.py +0 -0
  412. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_branch_numbering.py +0 -0
  413. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_check_prerequisites_paths_only.py +0 -0
  414. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_check_prerequisites_python_parity.py +0 -0
  415. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_check_tool.py +0 -0
  416. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_cli_version.py +0 -0
  417. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_commands_package.py +0 -0
  418. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_console_imports.py +0 -0
  419. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_extension_registration.py +0 -0
  420. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_extension_skills.py +0 -0
  421. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_extension_update_hardening.py +0 -0
  422. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_extensions.py +0 -0
  423. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_github_http.py +0 -0
  424. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_github_workflows.py +0 -0
  425. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_init_dir.py +0 -0
  426. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_init_dir_cli.py +0 -0
  427. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_live_transient_windows.py +0 -0
  428. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_merge.py +0 -0
  429. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_post_process.py +0 -0
  430. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_presets.py +0 -0
  431. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_ps1_encoding.py +0 -0
  432. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_registrar_path_traversal.py +0 -0
  433. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_self_upgrade_detection.py +0 -0
  434. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_self_upgrade_execution.py +0 -0
  435. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_self_upgrade_guidance.py +0 -0
  436. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_self_upgrade_verification.py +0 -0
  437. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_setup_plan_feature_json.py +0 -0
  438. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_setup_plan_no_overwrite.py +0 -0
  439. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_shared_infra_integrity.py +0 -0
  440. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_timestamp_branches.py +0 -0
  441. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_upgrade.py +0 -0
  442. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_utils.py +0 -0
  443. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_utils_assets_imports.py +0 -0
  444. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_version_imports.py +0 -0
  445. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_workflow_run_without_project.py +0 -0
  446. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_adapters.py +0 -0
  447. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_catalog_config.py +0 -0
  448. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_conflict.py +0 -0
  449. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_packager.py +0 -0
  450. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_records.py +0 -0
  451. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_references.py +0 -0
  452. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_resolver.py +0 -0
  453. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_validator.py +0 -0
  454. {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_versioning.py +0 -0
  455. {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/ARCHITECTURE.md +0 -0
  456. {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/PUBLISHING.md +0 -0
  457. {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/README.md +0 -0
  458. {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/catalog.community.json +0 -0
  459. {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/catalog.json +0 -0
  460. {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/speckit/workflow.yml +0 -0
  461. {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/step-catalog.community.json +0 -0
  462. {specify_cli-0.12.8 → 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,36 @@
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
+
20
+ ## [0.12.9] - 2026-07-09
21
+
22
+ ### Changed
23
+
24
+ - fix(integrations): skip Windows Store python3 alias stub in resolve_python_interpreter (#3385)
25
+ - fix(integrations): escape control characters in SKILL.md frontmatter (#3399)
26
+ - fix(workflows): apply chained expression filters left-to-right (#3339)
27
+ - fix(scripts): resolve invoke_separator by parse success, not python3 availability (#3304) (#3320)
28
+ - fix(shared-infra): refresh_shared_templates preserves recovered user files (#3378)
29
+ - fix(agents): resolve skill placeholders in Goose (yaml) command output (#3374)
30
+ - fix(bundler): enforce version pin on bundled preset/extension installs (#3377)
31
+ - Update Golden Demo extension to v0.3.0 (#3394)
32
+ - test: isolate integration test home (#3144)
33
+ - chore: release 0.12.8, begin 0.12.9.dev0 development (#3410)
34
+
5
35
  ## [0.12.8] - 2026-07-08
6
36
 
7
37
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specify-cli
3
- Version: 0.12.8
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
@@ -58,7 +58,7 @@ The following community-contributed extensions are available in [`catalog.commun
58
58
  | Fleet Orchestrator | Orchestrate a full feature lifecycle with human-in-the-loop gates across all SpecKit phases | `process` | Read+Write | [spec-kit-fleet](https://github.com/sharathsatish/spec-kit-fleet) |
59
59
  | GitHub Issues Integration 1 | Generate spec artifacts from GitHub Issues - import issues, sync updates, and maintain bidirectional traceability | `integration` | Read+Write | [spec-kit-github-issues](https://github.com/Fatima367/spec-kit-github-issues) |
60
60
  | GitHub Issues Integration 2 | Creates and syncs local specs from an existing GitHub issue | `integration` | Read+Write | [spec-kit-issue](https://github.com/aaronrsun/spec-kit-issue) |
61
- | Golden Demo | Extracts acceptance criteria from specs, builds test vectors, and produces a behavioral drift report — complementary to Architecture Guard and CDD | `docs` | Read+Write | [spec-kit-golden-demo](https://github.com/jasstt/spec-kit-golden-demo) |
61
+ | Golden Demo | Deterministic behavioral drift oracle. Extracts acceptance criteria, generates fuzz test vectors (seed=42), compares golden Python implementations against real code in any language. CI/CD gatekeeper with warn/strict modes. | `docs` | Read+Write | [spec-kit-golden-demo](https://github.com/jasstt/spec-kit-golden-demo) |
62
62
  | Improve Extension | Audits any codebase as a senior advisor and writes prioritized, self-contained spec prompts under specs/ that the spec-kit lifecycle can process | `process` | Read+Write | [spec-kit-improve](https://github.com/d0whc3r/spec-kit-improve) |
63
63
  | Intake | Normalize PRD, design, HTML SSOT, and test-case evidence into SDD-ready intake artifacts. | `docs` | Read+Write | [spec-kit-intake](https://github.com/bigsmartben/spec-kit-intake) |
64
64
  | Intelligent Agent Orchestrator | Cross-catalog agent discovery and intelligent prompt-to-command routing | `process` | Read+Write | [spec-kit-orchestrator](https://github.com/pragya247/spec-kit-orchestrator) |
@@ -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) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema_version": "1.0",
3
- "updated_at": "2026-07-06T00:00:00Z",
3
+ "updated_at": "2026-07-07T00:00:00Z",
4
4
  "catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.community.json",
5
5
  "extensions": {
6
6
  "aide": {
@@ -1398,10 +1398,10 @@
1398
1398
  "golden-demo": {
1399
1399
  "name": "Golden Demo",
1400
1400
  "id": "golden-demo",
1401
- "description": "Extracts acceptance criteria from specs, builds test vectors, and produces a behavioral drift report — complementary to Architecture Guard and CDD.",
1401
+ "description": "Deterministic behavioral drift oracle. Extracts acceptance criteria, generates fuzz test vectors (seed=42), compares golden Python implementations against real code in any language. CI/CD gatekeeper with warn/strict modes.",
1402
1402
  "author": "jasstt",
1403
- "version": "0.1.1",
1404
- "download_url": "https://github.com/jasstt/spec-kit-golden-demo/archive/refs/tags/v0.1.1.zip",
1403
+ "version": "0.3.0",
1404
+ "download_url": "https://github.com/jasstt/spec-kit-golden-demo/archive/refs/tags/v0.3.0.zip",
1405
1405
  "repository": "https://github.com/jasstt/spec-kit-golden-demo",
1406
1406
  "homepage": "https://github.com/jasstt/spec-kit-golden-demo",
1407
1407
  "documentation": "https://github.com/jasstt/spec-kit-golden-demo",
@@ -1412,13 +1412,16 @@
1412
1412
  "speckit_version": ">=0.1.0"
1413
1413
  },
1414
1414
  "provides": {
1415
- "commands": 2,
1415
+ "commands": 3,
1416
1416
  "hooks": 2
1417
1417
  },
1418
1418
  "tags": [
1419
1419
  "testing",
1420
1420
  "drift-detection",
1421
1421
  "behavioral-oracle",
1422
+ "fuzzing",
1423
+ "ci-cd",
1424
+ "cross-language",
1422
1425
  "tdd",
1423
1426
  "quality"
1424
1427
  ],
@@ -1426,7 +1429,7 @@
1426
1429
  "downloads": 0,
1427
1430
  "stars": 0,
1428
1431
  "created_at": "2026-06-24T00:00:00Z",
1429
- "updated_at": "2026-06-24T00:00:00Z"
1432
+ "updated_at": "2026-07-07T00:00:00Z"
1430
1433
  },
1431
1434
  "harness": {
1432
1435
  "name": "Research Harness",
@@ -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.8"
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"
@@ -244,21 +244,29 @@ get_invoke_separator() {
244
244
 
245
245
  local integration_json="$repo_root/.specify/integration.json"
246
246
  local separator="."
247
- local parsed_with_jq=0
247
+ local parsed=0
248
248
 
249
249
  if [[ -f "$integration_json" ]]; then
250
+ # Try parsers in order (jq -> python3 -> awk), falling through on
251
+ # failure. Selection is by *parse success*, not mere availability: on
252
+ # Windows `python3` commonly resolves to the Microsoft Store App
253
+ # Execution Alias stub, which passes `command -v` but fails at runtime
254
+ # (exit 49). An availability-gated branch would pick python3, swallow
255
+ # its failure, and — because this function historically had no text
256
+ # fallback — silently return "." even for `-`-separator integrations
257
+ # (e.g. forge, cline), yielding wrong command hints (issue #3304).
250
258
  if command -v jq >/dev/null 2>&1; then
251
259
  local jq_separator
252
260
  if jq_separator=$(jq -r '(.default_integration // .integration // "") as $k | if $k == "" then "." else (.integration_settings[$k].invoke_separator // ".") end' "$integration_json" 2>/dev/null); then
253
- parsed_with_jq=1
254
261
  case "$jq_separator" in
255
- "."|"-") separator="$jq_separator" ;;
262
+ "."|"-") separator="$jq_separator"; parsed=1 ;;
256
263
  esac
257
264
  fi
258
265
  fi
259
266
 
260
- if [[ "$parsed_with_jq" -eq 0 ]] && command -v python3 >/dev/null 2>&1; then
261
- if separator=$(python3 - "$integration_json" <<'PY' 2>/dev/null
267
+ if [[ "$parsed" -eq 0 ]] && command -v python3 >/dev/null 2>&1; then
268
+ local py_separator
269
+ if py_separator=$(python3 - "$integration_json" <<'PY' 2>/dev/null
262
270
  import json
263
271
  import sys
264
272
 
@@ -274,17 +282,64 @@ try:
274
282
  separator = entry["invoke_separator"]
275
283
  print(separator)
276
284
  except Exception:
277
- print(".")
285
+ sys.exit(1)
278
286
  PY
279
287
  ); then
280
- case "$separator" in
281
- "."|"-") ;;
282
- *) separator="." ;;
288
+ case "$py_separator" in
289
+ "."|"-") separator="$py_separator"; parsed=1 ;;
283
290
  esac
284
- else
285
- separator="."
286
291
  fi
287
292
  fi
293
+
294
+ if [[ "$parsed" -eq 0 ]]; then
295
+ # Last-resort text fallback for environments with neither jq nor a
296
+ # working python3 (e.g. stock Windows + Git Bash). Reads the active
297
+ # integration key (default_integration, else integration) and its
298
+ # invoke_separator from within the integration_settings object.
299
+ # Handles both pretty-printed (the written form) and compact JSON.
300
+ # Accumulate all lines into one buffer in END rather than using
301
+ # gawk-only whole-file slurp (RS="^$"), so this stays portable to
302
+ # the BSD awk on macOS.
303
+ local awk_separator
304
+ awk_separator=$(awk '
305
+ function keyval(d, name, v) {
306
+ if (match(d, "\"" name "\"[ \t\r\n]*:[ \t\r\n]*\"[^\"]*\"")) {
307
+ v=substr(d,RSTART,RLENGTH); sub(/^.*:[ \t\r\n]*"/,"",v); sub(/"$/,"",v); return v
308
+ }
309
+ return ""
310
+ }
311
+ { doc = doc $0 "\n" }
312
+ END {
313
+ key=keyval(doc,"default_integration"); if (key=="") key=keyval(doc,"integration")
314
+ sep="."
315
+ if (key!="") {
316
+ settings=doc
317
+ if (match(doc, /"integration_settings"[ \t\r\n]*:[ \t\r\n]*[{]/)) {
318
+ settings=substr(doc, RSTART+RLENGTH-1)
319
+ }
320
+ if (match(settings, "\"" key "\"[ \t\r\n]*:[ \t\r\n]*[{]")) {
321
+ start=RSTART+RLENGTH-1
322
+ depth=0
323
+ obj=""
324
+ for (i=start; i<=length(settings); i++) {
325
+ c=substr(settings,i,1)
326
+ obj=obj c
327
+ if (c=="{") depth++
328
+ else if (c=="}") { depth--; if (depth==0) break }
329
+ }
330
+ if (match(obj, /"invoke_separator"[ \t\r\n]*:[ \t\r\n]*"[-.]"/)) {
331
+ tok=substr(obj,RSTART,RLENGTH); s=substr(tok,length(tok)-1,1)
332
+ if (s=="." || s=="-") sep=s
333
+ }
334
+ }
335
+ }
336
+ print sep
337
+ }
338
+ ' "$integration_json" 2>/dev/null)
339
+ case "$awk_separator" in
340
+ "."|"-") separator="$awk_separator" ;;
341
+ esac
342
+ fi
288
343
  fi
289
344
 
290
345
  _SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT="$repo_root"
@@ -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*
@@ -701,6 +701,12 @@ class CommandRegistrar:
701
701
  )
702
702
  output = self.render_toml_command(frontmatter, body, source_id)
703
703
  elif agent_config["format"] == "yaml":
704
+ body = self.resolve_skill_placeholders(
705
+ agent_name, frontmatter, body, project_root
706
+ )
707
+ body = self._convert_argument_placeholder(
708
+ body, "$ARGUMENTS", agent_config["args"]
709
+ )
704
710
  output = self.render_yaml_command(
705
711
  frontmatter, body, source_id, cmd_name
706
712
  )
@@ -33,12 +33,13 @@ DEFAULT_PRIORITY = 10
33
33
  def _assert_pinned_version(
34
34
  kind: str, component_id: str, pinned: str | None, advertised: object
35
35
  ) -> None:
36
- """Refuse to install when the catalog version differs from the manifest pin.
36
+ """Refuse to install when the resolved version differs from the manifest pin.
37
37
 
38
38
  Bundle manifests pin component versions for reproducibility; installing
39
- whatever the active catalog currently serves would silently violate the
40
- pin. When the catalog advertises no version we cannot enforce the pin, so
41
- installation proceeds (the catalog, not the bundler, owns that gap).
39
+ whatever the resolved source (catalog *or* bundled asset) provides would
40
+ silently violate the pin. When the source advertises no version we cannot
41
+ enforce the pin, so installation proceeds (the source, not the bundler,
42
+ owns that gap).
42
43
  """
43
44
  if not pinned or advertised is None:
44
45
  return
@@ -54,11 +55,35 @@ def _assert_pinned_version(
54
55
  if not matches:
55
56
  raise BundlerError(
56
57
  f"{kind} '{component_id}' is pinned to version {pinned} in the bundle "
57
- f"manifest, but the active catalog serves {actual}. Update the bundle's "
58
- "pinned version or the catalog before installing."
58
+ f"manifest, but the resolved version is {actual}. Update the bundle's "
59
+ "pinned version or the source before installing."
59
60
  )
60
61
 
61
62
 
63
+ def _bundled_manifest_version(manifest_path: Path, root_key: str) -> str | None:
64
+ """Best-effort read of a bundled asset's declared version from its manifest.
65
+
66
+ Returns ``None`` when the manifest is missing/unreadable/invalid, which
67
+ ``_assert_pinned_version`` treats as "cannot enforce" (proceed) — matching
68
+ the catalog "advertises no version" escape hatch.
69
+ """
70
+ try:
71
+ import yaml
72
+
73
+ data = yaml.safe_load(manifest_path.read_text(encoding="utf-8"))
74
+ if isinstance(data, dict):
75
+ section = data.get(root_key)
76
+ if isinstance(section, dict):
77
+ version = section.get("version")
78
+ # Only a non-empty string is a usable version; anything else
79
+ # (missing / non-string / whitespace) means "cannot enforce".
80
+ if isinstance(version, str) and version.strip():
81
+ return version
82
+ except Exception: # noqa: BLE001 - unreadable/invalid manifest: skip pin
83
+ return None
84
+ return None
85
+
86
+
62
87
  class _KindManager(Protocol):
63
88
  def is_installed(self, component: ComponentRef) -> bool: ...
64
89
 
@@ -134,6 +159,15 @@ class _PresetKindManager:
134
159
 
135
160
  bundled = _locate_bundled_preset(component.id)
136
161
  if bundled is not None:
162
+ # Enforce the manifest pin against the bundled asset's own version,
163
+ # mirroring the catalog path below (the bundled path previously
164
+ # skipped the pin entirely).
165
+ _assert_pinned_version(
166
+ "Preset",
167
+ component.id,
168
+ component.version,
169
+ _bundled_manifest_version(bundled / "preset.yml", "preset"),
170
+ )
137
171
  self._manager.install_from_directory(bundled, speckit_version, priority)
138
172
  return
139
173
 
@@ -198,6 +232,15 @@ class _ExtensionKindManager:
198
232
 
199
233
  bundled = _locate_bundled_extension(component.id)
200
234
  if bundled is not None:
235
+ # Enforce the manifest pin against the bundled asset's own version,
236
+ # mirroring the catalog path below (the bundled path previously
237
+ # skipped the pin entirely).
238
+ _assert_pinned_version(
239
+ "Extension",
240
+ component.id,
241
+ component.version,
242
+ _bundled_manifest_version(bundled / "extension.yml", "extension"),
243
+ )
201
244
  self._manager.install_from_directory(
202
245
  bundled, speckit_version, priority=priority
203
246
  )
@@ -17,6 +17,7 @@ import os
17
17
  import re
18
18
  import shlex
19
19
  import shutil
20
+ import subprocess
20
21
  import sys
21
22
  from abc import ABC
22
23
  from dataclasses import dataclass
@@ -54,6 +55,18 @@ _CORE_COMMAND_TEMPLATE_RANK = {
54
55
  }
55
56
 
56
57
 
58
+ def yaml_quote(value: str) -> str:
59
+ """Emit *value* as a double-quoted YAML scalar on a single line.
60
+
61
+ A hand-rolled quote cannot carry raw newlines (YAML folds them to
62
+ spaces) or control characters (the reader rejects them), so let the
63
+ YAML emitter produce the escapes.
64
+ """
65
+ return yaml.safe_dump(
66
+ str(value), default_style='"', allow_unicode=True, width=sys.maxsize
67
+ ).strip()
68
+
69
+
57
70
  # ---------------------------------------------------------------------------
58
71
  # IntegrationOption
59
72
  # ---------------------------------------------------------------------------
@@ -592,10 +605,42 @@ class IntegrationBase(ABC):
592
605
  if candidate.exists():
593
606
  return relative
594
607
  for name in ("python3", "python"):
595
- if shutil.which(name):
596
- return name
608
+ found = shutil.which(name)
609
+ if not found:
610
+ continue
611
+ # On Windows, python3/python on PATH may be the Microsoft
612
+ # Store App Execution Alias stub: it exists but only prints
613
+ # an installer hint and exits non-zero, so existence is not
614
+ # enough (see #3304 for the same defect in the sh scripts).
615
+ if sys.platform == "win32" and not IntegrationBase._interpreter_runs(
616
+ found
617
+ ):
618
+ continue
619
+ return name
597
620
  return sys.executable or "python3"
598
621
 
622
+ @staticmethod
623
+ def _interpreter_runs(path: str) -> bool:
624
+ """Return True when *path* executes as a Python interpreter.
625
+
626
+ Runs isolated (``-I``) without ``site`` (``-S``) and discards
627
+ I/O so the probe is a fast liveness check that cannot trigger
628
+ ``sitecustomize``/user startup hooks.
629
+ """
630
+ try:
631
+ return (
632
+ subprocess.run(
633
+ [path, "-I", "-S", "-c", ""],
634
+ stdin=subprocess.DEVNULL,
635
+ stdout=subprocess.DEVNULL,
636
+ stderr=subprocess.DEVNULL,
637
+ timeout=15,
638
+ ).returncode
639
+ == 0
640
+ )
641
+ except (OSError, subprocess.SubprocessError):
642
+ return False
643
+
599
644
  @staticmethod
600
645
  def process_template(
601
646
  content: str,
@@ -1077,7 +1122,6 @@ class TomlIntegration(IntegrationBase):
1077
1122
  # YamlIntegration — YAML-format agents (Goose)
1078
1123
  # ---------------------------------------------------------------------------
1079
1124
 
1080
-
1081
1125
  class YamlIntegration(IntegrationBase):
1082
1126
  """Concrete base for integrations that use YAML recipe format.
1083
1127
 
@@ -1480,21 +1524,17 @@ class SkillsIntegration(IntegrationBase):
1480
1524
  if not description:
1481
1525
  description = f"Spec Kit: {command_name} workflow"
1482
1526
 
1483
- # Build SKILL.md with manually formatted frontmatter to match
1484
- # the release packaging script output exactly (double-quoted
1485
- # values, no yaml.safe_dump quoting differences).
1486
- def _quote(v: str) -> str:
1487
- escaped = v.replace("\\", "\\\\").replace('"', '\\"')
1488
- return f'"{escaped}"'
1489
-
1527
+ # Build SKILL.md with manually formatted frontmatter (stable
1528
+ # double-quoted values). yaml_quote escapes newlines and control
1529
+ # characters that a plain quoted f-string cannot carry.
1490
1530
  skill_content = (
1491
1531
  f"---\n"
1492
- f"name: {_quote(skill_name)}\n"
1493
- f"description: {_quote(description)}\n"
1494
- f"compatibility: {_quote('Requires spec-kit project structure with .specify/ directory')}\n"
1532
+ f"name: {yaml_quote(skill_name)}\n"
1533
+ f"description: {yaml_quote(description)}\n"
1534
+ f"compatibility: {yaml_quote('Requires spec-kit project structure with .specify/ directory')}\n"
1495
1535
  f"metadata:\n"
1496
- f" author: {_quote('github-spec-kit')}\n"
1497
- f" source: {_quote('templates/commands/' + src_file.name)}\n"
1536
+ f" author: {yaml_quote('github-spec-kit')}\n"
1537
+ f" source: {yaml_quote('templates/commands/' + src_file.name)}\n"
1498
1538
  f"---\n"
1499
1539
  f"{processed_body}"
1500
1540
  )
@@ -18,7 +18,7 @@ from typing import Any
18
18
 
19
19
  import yaml
20
20
 
21
- from ..base import IntegrationOption, SkillsIntegration
21
+ from ..base import IntegrationOption, SkillsIntegration, yaml_quote
22
22
  from ..manifest import IntegrationManifest
23
23
 
24
24
 
@@ -153,20 +153,18 @@ class HermesIntegration(SkillsIntegration):
153
153
  if not description:
154
154
  description = f"Spec Kit: {command_name} workflow"
155
155
 
156
- # Build SKILL.md with manually formatted frontmatter
157
- def _quote(v: str) -> str:
158
- escaped = v.replace("\\", "\\\\").replace('"', '\\"')
159
- return f'"{escaped}"'
160
-
156
+ # Build SKILL.md with manually formatted frontmatter. yaml_quote
157
+ # escapes newlines and control characters that a plain quoted
158
+ # f-string cannot carry.
161
159
  skill_content = (
162
160
  f"---\n"
163
- f"name: {_quote(skill_name)}\n"
164
- f"description: {_quote(description)}\n"
161
+ f"name: {yaml_quote(skill_name)}\n"
162
+ f"description: {yaml_quote(description)}\n"
165
163
  f"compatibility: "
166
- f"{_quote('Requires spec-kit project structure with .specify/ directory')}\n"
164
+ f"{yaml_quote('Requires spec-kit project structure with .specify/ directory')}\n"
167
165
  f"metadata:\n"
168
- f" author: {_quote('github-spec-kit')}\n"
169
- f" source: {_quote('templates/commands/' + src_file.name)}\n"
166
+ f" author: {yaml_quote('github-spec-kit')}\n"
167
+ f" source: {yaml_quote('templates/commands/' + src_file.name)}\n"
170
168
  f"---\n"
171
169
  f"{processed_body}"
172
170
  )