specify-cli 0.12.11__tar.gz → 0.12.13__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.11 → specify_cli-0.12.13}/CHANGELOG.md +30 -0
  2. {specify_cli-0.12.11 → specify_cli-0.12.13}/PKG-INFO +2 -2
  3. {specify_cli-0.12.11 → specify_cli-0.12.13}/README.md +1 -1
  4. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/community/extensions.md +1 -0
  5. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/install/one-time.md +2 -1
  6. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/install/pipx.md +2 -1
  7. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/installation.md +1 -1
  8. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/reference/bundles.md +5 -4
  9. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/reference/integrations.md +2 -1
  10. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/catalog.community.json +35 -1
  11. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/ARCHITECTURE.md +1 -2
  12. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/self-test/preset.yml +0 -6
  13. {specify_cli-0.12.11 → specify_cli-0.12.13}/pyproject.toml +1 -1
  14. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/agents.py +49 -0
  15. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/commands/bundle/__init__.py +37 -23
  16. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/extensions/__init__.py +25 -6
  17. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/extensions/_commands.py +8 -1
  18. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/kiro_cli/__init__.py +1 -0
  19. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/presets/__init__.py +40 -2
  20. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/presets/_commands.py +8 -1
  21. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/catalog.py +13 -5
  22. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/engine.py +10 -1
  23. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/expressions.py +22 -2
  24. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/if_then/__init__.py +2 -2
  25. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/shell/__init__.py +43 -20
  26. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/switch/__init__.py +14 -0
  27. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/commands/constitution.md +1 -1
  28. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/contract/test_bundle_cli.py +29 -7
  29. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integration/test_bundler_local_install.py +59 -0
  30. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_kiro_cli.py +3 -0
  31. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_extension_skills.py +59 -0
  32. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_extensions.py +268 -0
  33. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_presets.py +368 -1
  34. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_workflows.py +318 -101
  35. {specify_cli-0.12.11 → specify_cli-0.12.13}/workflows/README.md +6 -0
  36. specify_cli-0.12.11/presets/self-test/templates/agent-file-template.md +0 -9
  37. {specify_cli-0.12.11 → specify_cli-0.12.13}/.devcontainer/devcontainer.json +0 -0
  38. {specify_cli-0.12.11 → specify_cli-0.12.13}/.devcontainer/post-create.sh +0 -0
  39. {specify_cli-0.12.11 → specify_cli-0.12.13}/.editorconfig +0 -0
  40. {specify_cli-0.12.11 → specify_cli-0.12.13}/.gitattributes +0 -0
  41. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/CODEOWNERS +0 -0
  42. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/agent_request.yml +0 -0
  43. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  44. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/bundle_submission.yml +0 -0
  45. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  46. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/extension_submission.yml +0 -0
  47. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  48. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/preset_submission.yml +0 -0
  49. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  50. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/aw/actions-lock.json +0 -0
  51. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/dependabot.yml +0 -0
  52. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/skills/add-community-extension/SKILL.md +0 -0
  53. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/RELEASE-PROCESS.md +0 -0
  54. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/add-community-extension.lock.yml +0 -0
  55. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/add-community-extension.md +0 -0
  56. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/add-community-preset.lock.yml +0 -0
  57. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/add-community-preset.md +0 -0
  58. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/bug-assess.lock.yml +0 -0
  59. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/bug-assess.md +0 -0
  60. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/bug-fix.lock.yml +0 -0
  61. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/bug-fix.md +0 -0
  62. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/bug-test.lock.yml +0 -0
  63. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/bug-test.md +0 -0
  64. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/catalog-assign.yml +0 -0
  65. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/codeql.yml +0 -0
  66. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/docs.yml +0 -0
  67. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/lint.yml +0 -0
  68. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/publish-pypi.yml +0 -0
  69. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/release-trigger.yml +0 -0
  70. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/release.yml +0 -0
  71. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/stale.yml +0 -0
  72. {specify_cli-0.12.11 → specify_cli-0.12.13}/.github/workflows/test.yml +0 -0
  73. {specify_cli-0.12.11 → specify_cli-0.12.13}/.gitignore +0 -0
  74. {specify_cli-0.12.11 → specify_cli-0.12.13}/.markdownlint-cli2.jsonc +0 -0
  75. {specify_cli-0.12.11 → specify_cli-0.12.13}/.pre-commit-config.yaml +0 -0
  76. {specify_cli-0.12.11 → specify_cli-0.12.13}/.zenodo.json +0 -0
  77. {specify_cli-0.12.11 → specify_cli-0.12.13}/AGENTS.md +0 -0
  78. {specify_cli-0.12.11 → specify_cli-0.12.13}/CITATION.cff +0 -0
  79. {specify_cli-0.12.11 → specify_cli-0.12.13}/CODE_OF_CONDUCT.md +0 -0
  80. {specify_cli-0.12.11 → specify_cli-0.12.13}/CONTRIBUTING.md +0 -0
  81. {specify_cli-0.12.11 → specify_cli-0.12.13}/DEVELOPMENT.md +0 -0
  82. {specify_cli-0.12.11 → specify_cli-0.12.13}/LICENSE +0 -0
  83. {specify_cli-0.12.11 → specify_cli-0.12.13}/SECURITY.md +0 -0
  84. {specify_cli-0.12.11 → specify_cli-0.12.13}/SUPPORT.md +0 -0
  85. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/.gitignore +0 -0
  86. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/README.md +0 -0
  87. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/community/bundles.md +0 -0
  88. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/community/friends.md +0 -0
  89. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/community/overview.md +0 -0
  90. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/community/presets.md +0 -0
  91. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/community/walkthroughs.md +0 -0
  92. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/concepts/complex-features.md +0 -0
  93. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/concepts/sdd.md +0 -0
  94. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/concepts/spec-persistence.md +0 -0
  95. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/docfx.json +0 -0
  96. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/guides/evolving-specs.md +0 -0
  97. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/guides/monorepo.md +0 -0
  98. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/index.md +0 -0
  99. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/install/air-gapped.md +0 -0
  100. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/install/uv.md +0 -0
  101. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/local-development.md +0 -0
  102. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/quickstart.md +0 -0
  103. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/reference/authentication.md +0 -0
  104. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/reference/core.md +0 -0
  105. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/reference/extensions.md +0 -0
  106. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/reference/overview.md +0 -0
  107. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/reference/presets.md +0 -0
  108. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/reference/workflows.md +0 -0
  109. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/template/public/main.css +0 -0
  110. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/toc.yml +0 -0
  111. {specify_cli-0.12.11 → specify_cli-0.12.13}/docs/upgrade.md +0 -0
  112. {specify_cli-0.12.11 → specify_cli-0.12.13}/examples/bundles/business-analyst/README.md +0 -0
  113. {specify_cli-0.12.11 → specify_cli-0.12.13}/examples/bundles/business-analyst/bundle.yml +0 -0
  114. {specify_cli-0.12.11 → specify_cli-0.12.13}/examples/bundles/developer/README.md +0 -0
  115. {specify_cli-0.12.11 → specify_cli-0.12.13}/examples/bundles/developer/bundle.yml +0 -0
  116. {specify_cli-0.12.11 → specify_cli-0.12.13}/examples/bundles/product-manager/README.md +0 -0
  117. {specify_cli-0.12.11 → specify_cli-0.12.13}/examples/bundles/product-manager/bundle.yml +0 -0
  118. {specify_cli-0.12.11 → specify_cli-0.12.13}/examples/bundles/security-researcher/README.md +0 -0
  119. {specify_cli-0.12.11 → specify_cli-0.12.13}/examples/bundles/security-researcher/bundle.yml +0 -0
  120. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/EXTENSION-API-REFERENCE.md +0 -0
  121. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/EXTENSION-DEVELOPMENT-GUIDE.md +0 -0
  122. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/EXTENSION-PUBLISHING-GUIDE.md +0 -0
  123. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/EXTENSION-USER-GUIDE.md +0 -0
  124. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/README.md +0 -0
  125. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/RFC-EXTENSION-SYSTEM.md +0 -0
  126. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/agent-context/README.md +0 -0
  127. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/agent-context/agent-context-config.yml +0 -0
  128. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/agent-context/agent-context-defaults.json +0 -0
  129. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/agent-context/commands/speckit.agent-context.update.md +0 -0
  130. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/agent-context/extension.yml +0 -0
  131. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/agent-context/scripts/bash/update-agent-context.sh +0 -0
  132. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +0 -0
  133. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/agent-context/scripts/python/update_agent_context.py +0 -0
  134. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/bug/README.md +0 -0
  135. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/bug/commands/speckit.bug.assess.md +0 -0
  136. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/bug/commands/speckit.bug.fix.md +0 -0
  137. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/bug/commands/speckit.bug.test.md +0 -0
  138. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/bug/extension.yml +0 -0
  139. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/catalog.json +0 -0
  140. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/README.md +0 -0
  141. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/commands/speckit.git.commit.md +0 -0
  142. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/commands/speckit.git.feature.md +0 -0
  143. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/commands/speckit.git.initialize.md +0 -0
  144. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/commands/speckit.git.remote.md +0 -0
  145. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/commands/speckit.git.validate.md +0 -0
  146. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/config-template.yml +0 -0
  147. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/extension.yml +0 -0
  148. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/git-config.yml +0 -0
  149. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/scripts/bash/auto-commit.sh +0 -0
  150. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/scripts/bash/create-new-feature-branch.sh +0 -0
  151. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/scripts/bash/git-common.sh +0 -0
  152. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/scripts/bash/initialize-repo.sh +0 -0
  153. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
  154. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/scripts/powershell/create-new-feature-branch.ps1 +0 -0
  155. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/scripts/powershell/git-common.ps1 +0 -0
  156. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
  157. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/selftest/commands/selftest.md +0 -0
  158. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/selftest/extension.yml +0 -0
  159. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/template/.gitignore +0 -0
  160. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/template/CHANGELOG.md +0 -0
  161. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/template/EXAMPLE-README.md +0 -0
  162. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/template/LICENSE +0 -0
  163. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/template/README.md +0 -0
  164. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/template/commands/example.md +0 -0
  165. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/template/config-template.yml +0 -0
  166. {specify_cli-0.12.11 → specify_cli-0.12.13}/extensions/template/extension.yml +0 -0
  167. {specify_cli-0.12.11 → specify_cli-0.12.13}/integrations/CONTRIBUTING.md +0 -0
  168. {specify_cli-0.12.11 → specify_cli-0.12.13}/integrations/README.md +0 -0
  169. {specify_cli-0.12.11 → specify_cli-0.12.13}/integrations/catalog.community.json +0 -0
  170. {specify_cli-0.12.11 → specify_cli-0.12.13}/integrations/catalog.json +0 -0
  171. {specify_cli-0.12.11 → specify_cli-0.12.13}/media/bootstrap-claude-code.gif +0 -0
  172. {specify_cli-0.12.11 → specify_cli-0.12.13}/media/logo_large.webp +0 -0
  173. {specify_cli-0.12.11 → specify_cli-0.12.13}/media/logo_small.webp +0 -0
  174. {specify_cli-0.12.11 → specify_cli-0.12.13}/media/spec-kit-video-header.jpg +0 -0
  175. {specify_cli-0.12.11 → specify_cli-0.12.13}/media/specify_cli.gif +0 -0
  176. {specify_cli-0.12.11 → specify_cli-0.12.13}/newsletters/2026-April.md +0 -0
  177. {specify_cli-0.12.11 → specify_cli-0.12.13}/newsletters/2026-February.md +0 -0
  178. {specify_cli-0.12.11 → specify_cli-0.12.13}/newsletters/2026-June.md +0 -0
  179. {specify_cli-0.12.11 → specify_cli-0.12.13}/newsletters/2026-March.md +0 -0
  180. {specify_cli-0.12.11 → specify_cli-0.12.13}/newsletters/2026-May.md +0 -0
  181. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/PUBLISHING.md +0 -0
  182. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/README.md +0 -0
  183. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/catalog.community.json +0 -0
  184. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/catalog.json +0 -0
  185. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/lean/README.md +0 -0
  186. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/lean/commands/speckit.constitution.md +0 -0
  187. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/lean/commands/speckit.implement.md +0 -0
  188. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/lean/commands/speckit.plan.md +0 -0
  189. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/lean/commands/speckit.specify.md +0 -0
  190. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/lean/commands/speckit.tasks.md +0 -0
  191. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/lean/preset.yml +0 -0
  192. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/scaffold/README.md +0 -0
  193. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/scaffold/commands/speckit.myext.myextcmd.md +0 -0
  194. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/scaffold/commands/speckit.specify.md +0 -0
  195. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/scaffold/preset.yml +0 -0
  196. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/scaffold/templates/myext-template.md +0 -0
  197. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/scaffold/templates/spec-template.md +0 -0
  198. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/self-test/commands/speckit.specify.md +0 -0
  199. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/self-test/commands/speckit.wrap-test.md +0 -0
  200. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/self-test/templates/checklist-template.md +0 -0
  201. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/self-test/templates/constitution-template.md +0 -0
  202. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/self-test/templates/plan-template.md +0 -0
  203. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/self-test/templates/spec-template.md +0 -0
  204. {specify_cli-0.12.11 → specify_cli-0.12.13}/presets/self-test/templates/tasks-template.md +0 -0
  205. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/bash/check-prerequisites.sh +0 -0
  206. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/bash/common.sh +0 -0
  207. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/bash/create-new-feature.sh +0 -0
  208. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/bash/setup-plan.sh +0 -0
  209. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/bash/setup-tasks.sh +0 -0
  210. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/powershell/check-prerequisites.ps1 +0 -0
  211. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/powershell/common.ps1 +0 -0
  212. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/powershell/create-new-feature.ps1 +0 -0
  213. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/powershell/setup-plan.ps1 +0 -0
  214. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/powershell/setup-tasks.ps1 +0 -0
  215. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/python/check_prerequisites.py +0 -0
  216. {specify_cli-0.12.11 → specify_cli-0.12.13}/scripts/python/common.py +0 -0
  217. {specify_cli-0.12.11 → specify_cli-0.12.13}/spec-driven.md +0 -0
  218. {specify_cli-0.12.11 → specify_cli-0.12.13}/spec-kit.code-workspace +0 -0
  219. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/__init__.py +0 -0
  220. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/_agent_config.py +0 -0
  221. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/_assets.py +0 -0
  222. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/_console.py +0 -0
  223. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/_github_http.py +0 -0
  224. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/_init_options.py +0 -0
  225. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/_invocation_style.py +0 -0
  226. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/_project.py +0 -0
  227. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/_toml_string.py +0 -0
  228. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/_utils.py +0 -0
  229. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/_version.py +0 -0
  230. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/authentication/__init__.py +0 -0
  231. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/authentication/azure_devops.py +0 -0
  232. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/authentication/base.py +0 -0
  233. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/authentication/config.py +0 -0
  234. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/authentication/github.py +0 -0
  235. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/authentication/http.py +0 -0
  236. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/__init__.py +0 -0
  237. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/commands_impl/__init__.py +0 -0
  238. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/commands_impl/catalog_config.py +0 -0
  239. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/lib/__init__.py +0 -0
  240. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/lib/project.py +0 -0
  241. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/lib/versioning.py +0 -0
  242. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/lib/yamlio.py +0 -0
  243. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/models/__init__.py +0 -0
  244. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/models/catalog.py +0 -0
  245. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/models/manifest.py +0 -0
  246. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/models/records.py +0 -0
  247. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/services/__init__.py +0 -0
  248. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/services/adapters.py +0 -0
  249. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/services/catalog_stack.py +0 -0
  250. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/services/conflict.py +0 -0
  251. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/services/installer.py +0 -0
  252. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/services/packager.py +0 -0
  253. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/services/primitives.py +0 -0
  254. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/services/references.py +0 -0
  255. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/services/resolver.py +0 -0
  256. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/bundler/services/validator.py +0 -0
  257. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/catalogs.py +0 -0
  258. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/commands/__init__.py +0 -0
  259. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/commands/init.py +0 -0
  260. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integration_runtime.py +0 -0
  261. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integration_scaffold.py +0 -0
  262. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integration_state.py +0 -0
  263. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integration_status.py +0 -0
  264. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/__init__.py +0 -0
  265. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/_commands.py +0 -0
  266. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/_helpers.py +0 -0
  267. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/_install_commands.py +0 -0
  268. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/_migrate_commands.py +0 -0
  269. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/_query_commands.py +0 -0
  270. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/_scaffold_commands.py +0 -0
  271. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/agy/__init__.py +0 -0
  272. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/amp/__init__.py +0 -0
  273. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/auggie/__init__.py +0 -0
  274. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/base.py +0 -0
  275. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/bob/__init__.py +0 -0
  276. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/catalog.py +0 -0
  277. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/claude/__init__.py +0 -0
  278. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/cline/__init__.py +0 -0
  279. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/codebuddy/__init__.py +0 -0
  280. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/codex/__init__.py +0 -0
  281. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/copilot/__init__.py +0 -0
  282. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/cursor_agent/__init__.py +0 -0
  283. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/devin/__init__.py +0 -0
  284. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/firebender/__init__.py +0 -0
  285. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/forge/__init__.py +0 -0
  286. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/gemini/__init__.py +0 -0
  287. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/generic/__init__.py +0 -0
  288. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/goose/__init__.py +0 -0
  289. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/hermes/__init__.py +0 -0
  290. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/junie/__init__.py +0 -0
  291. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/kilocode/__init__.py +0 -0
  292. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/kimi/__init__.py +0 -0
  293. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/lingma/__init__.py +0 -0
  294. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/manifest.py +0 -0
  295. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/omp/__init__.py +0 -0
  296. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/opencode/__init__.py +0 -0
  297. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/pi/__init__.py +0 -0
  298. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/qodercli/__init__.py +0 -0
  299. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/qwen/__init__.py +0 -0
  300. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/rovodev/__init__.py +0 -0
  301. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/shai/__init__.py +0 -0
  302. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/tabnine/__init__.py +0 -0
  303. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/trae/__init__.py +0 -0
  304. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/vibe/__init__.py +0 -0
  305. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/zcode/__init__.py +0 -0
  306. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/integrations/zed/__init__.py +0 -0
  307. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/shared_infra.py +0 -0
  308. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/__init__.py +0 -0
  309. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/_commands.py +0 -0
  310. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/base.py +0 -0
  311. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/__init__.py +0 -0
  312. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/command/__init__.py +0 -0
  313. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/do_while/__init__.py +0 -0
  314. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/fan_in/__init__.py +0 -0
  315. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/fan_out/__init__.py +0 -0
  316. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/gate/__init__.py +0 -0
  317. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/init/__init__.py +0 -0
  318. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/prompt/__init__.py +0 -0
  319. {specify_cli-0.12.11 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/while_loop/__init__.py +0 -0
  320. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/checklist-template.md +0 -0
  321. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/commands/analyze.md +0 -0
  322. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/commands/checklist.md +0 -0
  323. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/commands/clarify.md +0 -0
  324. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/commands/converge.md +0 -0
  325. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/commands/implement.md +0 -0
  326. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/commands/plan.md +0 -0
  327. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/commands/specify.md +0 -0
  328. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/commands/tasks.md +0 -0
  329. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/commands/taskstoissues.md +0 -0
  330. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/constitution-template.md +0 -0
  331. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/plan-template.md +0 -0
  332. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/spec-template.md +0 -0
  333. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/tasks-template.md +0 -0
  334. {specify_cli-0.12.11 → specify_cli-0.12.13}/templates/vscode-settings.json +0 -0
  335. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/__init__.py +0 -0
  336. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/auth_helpers.py +0 -0
  337. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/bundler_helpers.py +0 -0
  338. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/conftest.py +0 -0
  339. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/contract/test_catalog_schema.py +0 -0
  340. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/contract/test_manifest_schema.py +0 -0
  341. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/extensions/__init__.py +0 -0
  342. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/extensions/bug/__init__.py +0 -0
  343. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/extensions/bug/test_bug_extension.py +0 -0
  344. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/extensions/git/__init__.py +0 -0
  345. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/extensions/git/test_git_extension.py +0 -0
  346. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/extensions/test_agent_context_cli_free.py +0 -0
  347. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/extensions/test_extension_agent_context.py +0 -0
  348. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/extensions/test_update_agent_context_feature_json.py +0 -0
  349. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/extensions/test_update_agent_context_python_parity.py +0 -0
  350. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/hooks/TESTING.md +0 -0
  351. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/hooks/plan.md +0 -0
  352. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/hooks/spec.md +0 -0
  353. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/hooks/tasks.md +0 -0
  354. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/http_helpers.py +0 -0
  355. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integration/test_bundler_catalog_stack.py +0 -0
  356. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integration/test_bundler_init_install.py +0 -0
  357. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integration/test_bundler_install_flow.py +0 -0
  358. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integration/test_bundler_offline.py +0 -0
  359. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integration/test_bundler_security_paths.py +0 -0
  360. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/__init__.py +0 -0
  361. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/conftest.py +0 -0
  362. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_base.py +0 -0
  363. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_cli.py +0 -0
  364. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_extra_args.py +0 -0
  365. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_home_isolation.py +0 -0
  366. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_agy.py +0 -0
  367. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_amp.py +0 -0
  368. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_auggie.py +0 -0
  369. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_base_markdown.py +0 -0
  370. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_base_skills.py +0 -0
  371. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_base_toml.py +0 -0
  372. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_base_yaml.py +0 -0
  373. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_bob.py +0 -0
  374. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_catalog.py +0 -0
  375. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_claude.py +0 -0
  376. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_cline.py +0 -0
  377. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_codebuddy.py +0 -0
  378. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_codex.py +0 -0
  379. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_copilot.py +0 -0
  380. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_cursor_agent.py +0 -0
  381. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_devin.py +0 -0
  382. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_firebender.py +0 -0
  383. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_forge.py +0 -0
  384. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_gemini.py +0 -0
  385. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_generic.py +0 -0
  386. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_goose.py +0 -0
  387. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_hermes.py +0 -0
  388. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_junie.py +0 -0
  389. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_kilocode.py +0 -0
  390. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_kimi.py +0 -0
  391. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_lingma.py +0 -0
  392. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_omp.py +0 -0
  393. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_opencode.py +0 -0
  394. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_pi.py +0 -0
  395. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_qodercli.py +0 -0
  396. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_qwen.py +0 -0
  397. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_rovodev.py +0 -0
  398. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_scaffold.py +0 -0
  399. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_shai.py +0 -0
  400. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_state.py +0 -0
  401. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_subcommand.py +0 -0
  402. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_tabnine.py +0 -0
  403. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_trae.py +0 -0
  404. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_vibe.py +0 -0
  405. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_zcode.py +0 -0
  406. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_integration_zed.py +0 -0
  407. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_manifest.py +0 -0
  408. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_registry.py +0 -0
  409. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/integrations/test_skill_frontmatter_quoting.py +0 -0
  410. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/self_upgrade_helpers.py +0 -0
  411. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_agent_config_consistency.py +0 -0
  412. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_authentication.py +0 -0
  413. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_branch_numbering.py +0 -0
  414. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_check_prerequisites_paths_only.py +0 -0
  415. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_check_prerequisites_python_parity.py +0 -0
  416. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_check_tool.py +0 -0
  417. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_cli_version.py +0 -0
  418. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_command_template_py_scripts.py +0 -0
  419. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_commands_package.py +0 -0
  420. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_console_imports.py +0 -0
  421. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_extension_registration.py +0 -0
  422. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_extension_update_hardening.py +0 -0
  423. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_github_http.py +0 -0
  424. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_github_workflows.py +0 -0
  425. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_init_dir.py +0 -0
  426. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_init_dir_cli.py +0 -0
  427. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_live_transient_windows.py +0 -0
  428. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_merge.py +0 -0
  429. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_post_process.py +0 -0
  430. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_ps1_encoding.py +0 -0
  431. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_registrar_path_traversal.py +0 -0
  432. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_self_upgrade_detection.py +0 -0
  433. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_self_upgrade_execution.py +0 -0
  434. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_self_upgrade_guidance.py +0 -0
  435. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_self_upgrade_verification.py +0 -0
  436. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_setup_plan_feature_json.py +0 -0
  437. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_setup_plan_no_overwrite.py +0 -0
  438. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_setup_tasks.py +0 -0
  439. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_shared_infra_integrity.py +0 -0
  440. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_timestamp_branches.py +0 -0
  441. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_upgrade.py +0 -0
  442. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_utils.py +0 -0
  443. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_utils_assets_imports.py +0 -0
  444. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_version_imports.py +0 -0
  445. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/test_workflow_run_without_project.py +0 -0
  446. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/unit/test_bundler_adapters.py +0 -0
  447. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/unit/test_bundler_catalog_config.py +0 -0
  448. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/unit/test_bundler_conflict.py +0 -0
  449. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/unit/test_bundler_packager.py +0 -0
  450. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/unit/test_bundler_primitives.py +0 -0
  451. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/unit/test_bundler_records.py +0 -0
  452. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/unit/test_bundler_references.py +0 -0
  453. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/unit/test_bundler_resolver.py +0 -0
  454. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/unit/test_bundler_validator.py +0 -0
  455. {specify_cli-0.12.11 → specify_cli-0.12.13}/tests/unit/test_bundler_versioning.py +0 -0
  456. {specify_cli-0.12.11 → specify_cli-0.12.13}/workflows/ARCHITECTURE.md +0 -0
  457. {specify_cli-0.12.11 → specify_cli-0.12.13}/workflows/PUBLISHING.md +0 -0
  458. {specify_cli-0.12.11 → specify_cli-0.12.13}/workflows/catalog.community.json +0 -0
  459. {specify_cli-0.12.11 → specify_cli-0.12.13}/workflows/catalog.json +0 -0
  460. {specify_cli-0.12.11 → specify_cli-0.12.13}/workflows/speckit/workflow.yml +0 -0
  461. {specify_cli-0.12.11 → specify_cli-0.12.13}/workflows/step-catalog.community.json +0 -0
  462. {specify_cli-0.12.11 → specify_cli-0.12.13}/workflows/step-catalog.json +0 -0
@@ -2,6 +2,36 @@
2
2
 
3
3
  <!-- insert new changelog below this comment -->
4
4
 
5
+ ## [0.12.13] - 2026-07-13
6
+
7
+ ### Changed
8
+
9
+ - fix(workflows): fail switch step on non-mapping cases instead of crashing (#3481)
10
+ - Cleanup agent-file-template.md (#2579)
11
+ - fix: mark Kiro integration as multi-install safe (#3472)
12
+ - fix: rewrite extension-relative subdir paths in generated command bodies (#3444)
13
+ - fix(templates): point constitution sync checklist at installed command files (#3418)
14
+ - feat(workflows): make shell step timeout configurable (#3327) (#3328)
15
+ - docs: clarify that release tags keep the leading v prefix (#3463)
16
+ - fix(workflows): don't crash on membership test against a non-iterable (#3448)
17
+ - fix(workflows): if-step validate accepts falsy non-list else (#3264)
18
+ - chore: release 0.12.12, begin 0.12.13.dev0 development (#3490)
19
+
20
+ ## [0.12.12] - 2026-07-13
21
+
22
+ ### Changed
23
+
24
+ - fix(extensions): set-priority repairs corrupted boolean priority (#3268)
25
+ - fix(presets): set-priority repairs corrupted boolean priority (#3269)
26
+ - fix(workflows): engine loop cap ignores bool max_iterations (#3270)
27
+ - docs(bundles): document --integration on 'bundle update' (#3271)
28
+ - fix(workflows): harden catalog.py against mis-shaped registry & non-string fields (#3375)
29
+ - Add Verify Review Ship extension to community catalog (#3450)
30
+ - fix(bundle): reject file:// / local download_url — catalog URLs are HTTPS-only (#3344)
31
+ - fix(extensions): handle prefix-colliding env vars in _get_env_config (#3350)
32
+ - docs: document copilot skills mode (--skills) and markdown deprecation (#3313)
33
+ - chore: release 0.12.11, begin 0.12.12.dev0 development (#3460)
34
+
5
35
  ## [0.12.11] - 2026-07-10
6
36
 
7
37
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specify-cli
3
- Version: 0.12.11
3
+ Version: 0.12.13
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
@@ -65,7 +65,7 @@ Spec-Driven Development **flips the script** on traditional software development
65
65
 
66
66
  ### 1. Install Specify CLI
67
67
 
68
- Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](./docs/install/uv.md)). Replace `vX.Y.Z` with the latest tag from [Releases](https://github.com/github/spec-kit/releases):
68
+ Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](./docs/install/uv.md)). Replace `vX.Y.Z` with the latest release tag from [Releases](https://github.com/github/spec-kit/releases) — keep the leading `v` (for example, `v0.12.11`, not `0.12.11`):
69
69
 
70
70
  ```bash
71
71
  uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z
@@ -45,7 +45,7 @@ Spec-Driven Development **flips the script** on traditional software development
45
45
 
46
46
  ### 1. Install Specify CLI
47
47
 
48
- Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](./docs/install/uv.md)). Replace `vX.Y.Z` with the latest tag from [Releases](https://github.com/github/spec-kit/releases):
48
+ Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](./docs/install/uv.md)). Replace `vX.Y.Z` with the latest release tag from [Releases](https://github.com/github/spec-kit/releases) — keep the leading `v` (for example, `v0.12.11`, not `0.12.11`):
49
49
 
50
50
  ```bash
51
51
  uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z
@@ -148,6 +148,7 @@ The following community-contributed extensions are available in [`catalog.commun
148
148
  | Token Economy | Token routing, measured savings, and context audit workflows | `process` | Read+Write | [spec-kit-token-economy](https://github.com/formin/spec-kit-token-economy) |
149
149
  | V-Model Extension Pack | Enforces V-Model paired generation of development specs and test specs with full traceability | `docs` | Read+Write | [spec-kit-v-model](https://github.com/leocamello/spec-kit-v-model) |
150
150
  | Verify Extension | Post-implementation quality gate that validates implemented code against specification artifacts | `code` | Read-only | [spec-kit-verify](https://github.com/ismaelJimenez/spec-kit-verify) |
151
+ | Verify Review Ship | Adds post-implementation verify, review, and ship readiness gates to Spec Kit workflows | `process` | Read-only | [spec-kit-verify-review-ship](https://github.com/cadugevaerd/spec-kit-verify-review-ship) |
151
152
  | Verify Tasks Extension | Detect phantom completions: tasks marked [X] in tasks.md with no real implementation | `code` | Read-only | [spec-kit-verify-tasks](https://github.com/datastone-inc/spec-kit-verify-tasks) |
152
153
  | Version Guard | Verify tech stack versions against live npm registries before planning and implementation | `process` | Read-only | [spec-kit-version-guard](https://github.com/KevinBrown5280/spec-kit-version-guard) |
153
154
  | What-if Analysis | Preview the downstream impact (complexity, effort, tasks, risks) of requirement changes before committing to them | `visibility` | Read-only | [spec-kit-whatif](https://github.com/DevAbdullah90/spec-kit-whatif) |
@@ -11,7 +11,8 @@ If you want to try Spec Kit without installing it permanently, use `uvx` to run
11
11
  # Create a new project (latest from main)
12
12
  uvx --from git+https://github.com/github/spec-kit.git specify init <PROJECT_NAME>
13
13
 
14
- # Or target a specific release (replace vX.Y.Z with a tag from Releases)
14
+ # Or target a specific release (replace vX.Y.Z with a tag from Releases;
15
+ # keep the leading v, e.g. v0.12.11 not 0.12.11)
15
16
  uvx --from git+https://github.com/github/spec-kit.git@vX.Y.Z specify init <PROJECT_NAME>
16
17
 
17
18
  # Initialize in the current directory
@@ -7,7 +7,8 @@
7
7
  Pin a specific release tag for stability (check [Releases](https://github.com/github/spec-kit/releases) for the latest):
8
8
 
9
9
  ```bash
10
- # Install a specific stable release (recommended — replace vX.Y.Z with the latest tag)
10
+ # Install a specific stable release (recommended — replace vX.Y.Z with the
11
+ # latest tag, keeping the leading v, e.g. v0.12.11 not 0.12.11)
11
12
  pipx install git+https://github.com/github/spec-kit.git@vX.Y.Z
12
13
 
13
14
  # Or install latest from main (may include unreleased changes)
@@ -15,7 +15,7 @@
15
15
 
16
16
  ### Persistent Installation (Recommended)
17
17
 
18
- Install once and use everywhere. Replace `vX.Y.Z` with a tag from [Releases](https://github.com/github/spec-kit/releases):
18
+ Install once and use everywhere. Replace `vX.Y.Z` with a release tag from [Releases](https://github.com/github/spec-kit/releases) — keep the leading `v` (for example, `v0.12.11`, not `0.12.11`):
19
19
 
20
20
  > [!NOTE]
21
21
  > The command below requires **[uv](https://docs.astral.sh/uv/)**. If you see `command not found: uv`, [install uv first](./install/uv.md).
@@ -51,10 +51,11 @@ If the current directory is not yet a Spec Kit project, `install` initializes on
51
51
  specify bundle update [<bundle_id>]
52
52
  ```
53
53
 
54
- | Option | Description |
55
- | ------------ | ------------------------------------ |
56
- | `--all` | Update every installed bundle |
57
- | `--offline` | Do not access the network |
54
+ | Option | Description |
55
+ | ---------------- | --------------------------------------------------------------------------------------------------------------------- |
56
+ | `--all` | Update every installed bundle |
57
+ | `--integration` | Override the integration used when refreshing components; applied only when the project's active integration can't be determined |
58
+ | `--offline` | Do not access the network |
58
59
 
59
60
  Re-resolves a bundle and **refreshes** its components through each primitive's update path, bringing already-installed components up to the bundle's newly pinned versions while preserving primitive-level overrides (such as preset priority). Provide a bundle id, or use `--all` to update everything installed.
60
61
 
@@ -18,7 +18,7 @@ The Specify CLI supports a wide range of AI coding agents. When you run `specify
18
18
  | [Firebender](https://firebender.com/) | `firebender` | IDE-based agent for Android Studio / IntelliJ |
19
19
  | [Forge](https://forgecode.dev/) | `forge` | |
20
20
  | [Gemini CLI](https://github.com/google-gemini/gemini-cli) | `gemini` | |
21
- | [GitHub Copilot](https://code.visualstudio.com/) | `copilot` | |
21
+ | [GitHub Copilot](https://code.visualstudio.com/) | `copilot` | Defaults to legacy markdown mode: `.agent.md` command files under `.github/agents/`, companion `.prompt.md` files under `.github/prompts/`, and a `.vscode/settings.json` merge. Pass `--integration-options="--skills"` to scaffold skills as `speckit-<command>/SKILL.md` under `.github/skills/` instead. Legacy markdown mode is deprecated and will stop being the default in a future release. |
22
22
  | [Goose](https://goose-docs.ai/) | `goose` | Uses YAML recipe format in `.goose/recipes/` |
23
23
  | [Hermes](https://github.com/NousResearch/hermes-agent) | `hermes` | Skills-based integration; installs skills globally into `~/.hermes/skills/` |
24
24
  | [IBM Bob](https://www.ibm.com/products/bob) | `bob` | IDE-based agent |
@@ -219,6 +219,7 @@ Some integrations accept additional options via `--integration-options`:
219
219
  | ----------- | ------------------- | -------------------------------------------------------------- |
220
220
  | `generic` | `--commands-dir` | Required. Directory for command files |
221
221
  | `kimi` | `--migrate-legacy` | Migrate legacy `.kimi/skills/` installs to `.kimi-code/skills/` (including dotted→hyphenated skill naming, e.g. `speckit.xxx` → `speckit-xxx`) |
222
+ | `copilot` | `--skills` | Scaffold commands as agent skills (`speckit-<command>/SKILL.md` under `.github/skills/`, invoked as `/speckit-<command>`) instead of the default legacy markdown mode (`.github/agents/*.agent.md` plus `.github/prompts/*.prompt.md` and a `.vscode/settings.json` merge). Without this flag, install warns that legacy markdown mode is deprecated. |
222
223
 
223
224
  Example:
224
225
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema_version": "1.0",
3
- "updated_at": "2026-07-08T00:00:00Z",
3
+ "updated_at": "2026-07-10T00:00:00Z",
4
4
  "catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.community.json",
5
5
  "extensions": {
6
6
  "aide": {
@@ -4356,6 +4356,40 @@
4356
4356
  "created_at": "2026-03-03T00:00:00Z",
4357
4357
  "updated_at": "2026-04-09T00:00:00Z"
4358
4358
  },
4359
+ "verify-review-ship": {
4360
+ "name": "Verify Review Ship",
4361
+ "id": "verify-review-ship",
4362
+ "description": "Adds post-implementation verify, review, and ship readiness gates to Spec Kit workflows.",
4363
+ "author": "Carlos Eduardo Gevaerd Araujo",
4364
+ "version": "0.1.0",
4365
+ "download_url": "https://github.com/cadugevaerd/spec-kit-verify-review-ship/archive/refs/tags/v0.1.0.zip",
4366
+ "repository": "https://github.com/cadugevaerd/spec-kit-verify-review-ship",
4367
+ "homepage": "https://github.com/cadugevaerd/spec-kit-verify-review-ship",
4368
+ "documentation": "https://github.com/cadugevaerd/spec-kit-verify-review-ship/blob/main/README.md",
4369
+ "changelog": "https://github.com/cadugevaerd/spec-kit-verify-review-ship/blob/main/CHANGELOG.md",
4370
+ "license": "MIT",
4371
+ "category": "process",
4372
+ "effect": "read-only",
4373
+ "requires": {
4374
+ "speckit_version": ">=0.1.0"
4375
+ },
4376
+ "provides": {
4377
+ "commands": 3,
4378
+ "hooks": 1
4379
+ },
4380
+ "tags": [
4381
+ "quality",
4382
+ "review",
4383
+ "shipping",
4384
+ "workflow",
4385
+ "testing"
4386
+ ],
4387
+ "verified": false,
4388
+ "downloads": 0,
4389
+ "stars": 0,
4390
+ "created_at": "2026-07-10T00:00:00Z",
4391
+ "updated_at": "2026-07-10T00:00:00Z"
4392
+ },
4359
4393
  "verify-tasks": {
4360
4394
  "name": "Verify Tasks Extension",
4361
4395
  "id": "verify-tasks",
@@ -158,8 +158,7 @@ presets/
158
158
  ├── plan-template.md
159
159
  ├── tasks-template.md
160
160
  ├── checklist-template.md
161
- ├── constitution-template.md
162
- └── agent-file-template.md
161
+ └── constitution-template.md
163
162
  ```
164
163
 
165
164
  ## Module Structure
@@ -44,12 +44,6 @@ provides:
44
44
  description: "Self-test constitution template"
45
45
  replaces: "constitution-template"
46
46
 
47
- - type: "template"
48
- name: "agent-file-template"
49
- file: "templates/agent-file-template.md"
50
- description: "Self-test agent file template"
51
- replaces: "agent-file-template"
52
-
53
47
  - type: "command"
54
48
  name: "speckit.specify"
55
49
  file: "commands/speckit.specify.md"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "specify-cli"
3
- version = "0.12.11"
3
+ version = "0.12.13"
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"
@@ -213,6 +213,52 @@ class CommandRegistrar:
213
213
  ".specify.specify/", ".specify/"
214
214
  )
215
215
 
216
+ @staticmethod
217
+ def rewrite_extension_paths(
218
+ text: str, extension_id: str, extension_dir: Path
219
+ ) -> str:
220
+ """Rewrite extension-relative paths to their installed locations.
221
+
222
+ Extension command bodies reference bundled files relative to the
223
+ extension root (e.g. ``agents/control/commander.md``). After install
224
+ those files live under ``.specify/extensions/<id>/``, so bare
225
+ references would resolve against the workspace root and never be
226
+ found (#2101).
227
+
228
+ Only directories that actually exist inside *extension_dir* are
229
+ rewritten, keeping the behaviour conservative and avoiding false
230
+ positives on prose. ``commands`` (slash-command sources), ``specs``
231
+ (user project artifacts) and dot-directories are never rewritten.
232
+ """
233
+ if not isinstance(text, str) or not text:
234
+ return text
235
+
236
+ skip = {"commands", ".git", "specs"}
237
+ try:
238
+ subdirs = [
239
+ entry.name
240
+ for entry in extension_dir.iterdir()
241
+ if entry.is_dir()
242
+ and entry.name not in skip
243
+ and not entry.name.startswith(".")
244
+ ]
245
+ except OSError:
246
+ return text
247
+
248
+ for subdir in subdirs:
249
+ # Only rewrite relative references (subdir/... or ./subdir/...);
250
+ # absolute paths like /subdir/... keep their meaning. Use a
251
+ # callable replacement: subdir/extension_id come from the
252
+ # filesystem and could contain backslashes or "\1"-like
253
+ # sequences, which would corrupt a string replacement template.
254
+ replacement = f".specify/extensions/{extension_id}/{subdir}/"
255
+ text = re.sub(
256
+ r'(^|[\s`"\'(])(?:\./)?' + re.escape(subdir) + "/",
257
+ lambda m: m.group(1) + replacement,
258
+ text,
259
+ )
260
+ return text
261
+
216
262
  def render_markdown_command(
217
263
  self, frontmatter: dict, body: str, source_id: str, context_note: str = None
218
264
  ) -> str:
@@ -639,6 +685,9 @@ class CommandRegistrar:
639
685
  frontmatter[key] = core_frontmatter[key]
640
686
  frontmatter.pop("strategy", None)
641
687
 
688
+ if extension_id:
689
+ body = self.rewrite_extension_paths(body, extension_id, source_root)
690
+
642
691
  frontmatter = self._adjust_script_paths(
643
692
  frontmatter, extension_id=extension_id
644
693
  )
@@ -746,11 +746,16 @@ def _resolve_manifest_path(path: Path | None) -> Path:
746
746
  def _download_manifest(resolved, *, offline: bool):
747
747
  """Resolve a bundle's manifest from its catalog ``download_url``.
748
748
 
749
- Local/``file://`` URLs always work offline and may point at a ``.zip``
750
- artifact, a bundle directory, or a ``bundle.yml`` (handled by
751
- :func:`_local_manifest_source`). Remote ``https://`` URLs are fetched with
752
- the shared authenticated, redirect-validated HTTP client, and only when not
753
- ``--offline``.
749
+ Catalog ``download_url``s are HTTPS-only (``http`` allowed for localhost),
750
+ matching the extensions/presets/workflows catalog systems. Remote URLs are
751
+ fetched with the shared authenticated, redirect-validated HTTP client, and
752
+ only when not ``--offline``.
753
+
754
+ Local and ``file://`` sources are intentionally not resolved here: to
755
+ install a bundle from disk, pass the path positionally
756
+ (``specify bundle install ./path/to/bundle.yml`` — a bundle directory or a
757
+ ``.zip`` artifact also works), which :func:`_local_manifest_source` handles
758
+ before catalog resolution and which never touches ``download_url``.
754
759
  """
755
760
  from urllib.parse import urlparse
756
761
 
@@ -763,26 +768,35 @@ def _download_manifest(resolved, *, offline: bool):
763
768
  parsed = urlparse(url)
764
769
  scheme = parsed.scheme.lower()
765
770
 
766
- # On Windows an absolute path like ``C:\bundle.yml`` parses with a
767
- # single-letter ``scheme``; treat it as a local file, not a URL scheme.
771
+ # ``file://`` URLs and bare filesystem paths (including Windows drive paths
772
+ # like ``C:\bundle.yml``, which urlparse reads as a single-letter scheme)
773
+ # are not valid catalog download URLs. Catalog URLs are HTTPS-only across
774
+ # every catalog system; installing from disk is done by passing the path
775
+ # positionally, which never reaches URL resolution. Give an actionable
776
+ # error rather than accepting a scheme the rest of the codebase rejects.
768
777
  if scheme in ("", "file") or re.match(r"^[A-Za-z]:[\\/]", url):
769
- local = Path(parsed.path if scheme == "file" else url)
770
- manifest = _local_manifest_source(str(local))
771
- if manifest is None:
772
- raise BundlerError(f"Bundle manifest not found: {local}")
773
- return manifest
774
-
775
- if scheme in ("http", "https"):
776
- if offline:
777
- raise BundlerError(
778
- f"Network access disabled; cannot download bundle '{resolved.entry.id}' "
779
- f"from {url}."
780
- )
781
- return _download_remote_manifest(resolved.entry.id, url)
778
+ raise BundlerError(
779
+ f"Catalog entry '{resolved.entry.id}' has a non-HTTP(S) download_url "
780
+ f"({url}); catalog download URLs must be HTTPS (http for localhost) — "
781
+ "a file:// URL, a local filesystem path, or a scheme-less value "
782
+ "(e.g. 'example.com/bundle.zip') is not accepted. "
783
+ "To install a bundle from disk, pass the path directly: "
784
+ "'specify bundle install <path-to-bundle.yml | bundle-dir | .zip>'."
785
+ )
782
786
 
783
- raise BundlerError(
784
- f"Unsupported download_url scheme for bundle '{resolved.entry.id}': {url}"
785
- )
787
+ # Validate the scheme/host *before* the offline gate so an invalid or
788
+ # non-HTTPS download_url reports the real problem in every mode, rather
789
+ # than a misleading "Network access disabled" under --offline.
790
+ # (_download_remote_manifest re-checks this, but only once network access
791
+ # is permitted.) HTTPS-only, http allowed for localhost.
792
+ _require_https(f"bundle '{resolved.entry.id}'", url)
793
+
794
+ if offline:
795
+ raise BundlerError(
796
+ f"Network access disabled; cannot download bundle '{resolved.entry.id}' "
797
+ f"from {url}."
798
+ )
799
+ return _download_remote_manifest(resolved.entry.id, url)
786
800
 
787
801
 
788
802
  def _require_https(label: str, url: str) -> None:
@@ -1078,6 +1078,11 @@ class ExtensionManager:
1078
1078
  frontmatter = registrar._adjust_script_paths(
1079
1079
  frontmatter, extension_id=manifest.id
1080
1080
  )
1081
+ # Mirror the register_commands() rewrite (#2101): resolve
1082
+ # extension-relative subdir references (agents/, knowledge-base/,
1083
+ # etc.) to their installed .specify/extensions/<id>/ location
1084
+ # before the generic placeholder/path resolution below.
1085
+ body = registrar.rewrite_extension_paths(body, manifest.id, extension_dir)
1081
1086
  body = registrar.resolve_skill_placeholders(
1082
1087
  selected_ai, frontmatter, body, self.project_root, extension_id=manifest.id
1083
1088
  )
@@ -2755,18 +2760,32 @@ class ConfigManager:
2755
2760
  if not key.startswith(prefix):
2756
2761
  continue
2757
2762
 
2758
- # Remove prefix and split into parts
2759
- config_path = key[len(prefix) :].lower().split("_")
2763
+ # Remove prefix and split into parts. Drop empty components from a
2764
+ # malformed name (e.g. ``SPECKIT_<EXT>_`` with no key, or
2765
+ # consecutive underscores ``SPECKIT_X__Y``) so we never create an
2766
+ # entry under an empty key.
2767
+ config_path = [p for p in key[len(prefix) :].lower().split("_") if p]
2768
+ if not config_path:
2769
+ continue
2760
2770
 
2761
- # Build nested dict
2771
+ # Build nested dict. Two env vars can collide on a prefix, e.g.
2772
+ # SPECKIT_X_CONNECTION=a and SPECKIT_X_CONNECTION_URL=b. Guard the
2773
+ # walk so a colliding scalar is replaced by a dict (deeper/more
2774
+ # specific vars win) instead of being indexed into — which raised
2775
+ # TypeError ('str' object does not support item assignment) — and
2776
+ # guard the leaf so a scalar processed after the nested var does
2777
+ # not clobber the nested dict. Order-independent: both insertion
2778
+ # orders yield {'connection': {'url': ...}}. Nested-wins mirrors
2779
+ # _merge_configs' dict-preserving semantics.
2762
2780
  current = env_config
2763
2781
  for part in config_path[:-1]:
2764
- if part not in current:
2782
+ if not isinstance(current.get(part), dict):
2765
2783
  current[part] = {}
2766
2784
  current = current[part]
2767
2785
 
2768
- # Set the final value
2769
- current[config_path[-1]] = value
2786
+ # Set the final value, unless a nested dict already occupies it.
2787
+ if not isinstance(current.get(config_path[-1]), dict):
2788
+ current[config_path[-1]] = value
2770
2789
 
2771
2790
  return env_config
2772
2791
 
@@ -1566,7 +1566,14 @@ def extension_set_priority(
1566
1566
  raw_priority = metadata.get("priority")
1567
1567
  # Only skip if the stored value is already a valid int equal to requested priority
1568
1568
  # This ensures corrupted values (e.g., "high") get repaired even when setting to default (10)
1569
- if isinstance(raw_priority, int) and raw_priority == priority:
1569
+ # A bool is an int in Python (isinstance(True, int) is True), so exclude it explicitly —
1570
+ # mirroring normalize_priority's bool guard — otherwise a corrupted True/False priority
1571
+ # equals 1/0 here and is never repaired.
1572
+ if (
1573
+ isinstance(raw_priority, int)
1574
+ and not isinstance(raw_priority, bool)
1575
+ and raw_priority == priority
1576
+ ):
1570
1577
  console.print(f"[yellow]Extension '{_escape_markup(str(display_name))}' already has priority {priority}[/yellow]")
1571
1578
  raise typer.Exit(0)
1572
1579
 
@@ -13,6 +13,7 @@ _KIRO_ARG_FALLBACK = "(the user will provide the argument in this conversation)"
13
13
 
14
14
  class KiroCliIntegration(MarkdownIntegration):
15
15
  key = "kiro-cli"
16
+ multi_install_safe = True
16
17
  config = {
17
18
  "name": "Kiro CLI",
18
19
  "folder": ".kiro/",
@@ -778,6 +778,7 @@ class PresetManager:
778
778
  matching_cmds, ext_id, ext_dir,
779
779
  self.project_root,
780
780
  context_note=f"\n<!-- Extension: {ext_id} -->\n<!-- Config: .specify/extensions/{ext_id}/ -->\n",
781
+ extension_id=ext_id,
781
782
  )
782
783
  registered = True
783
784
  except Exception:
@@ -1199,6 +1200,8 @@ class PresetManager:
1199
1200
  "command_name": cmd_name,
1200
1201
  "source_file": source_file,
1201
1202
  "source": f"extension:{manifest.id}",
1203
+ "extension_id": manifest.id,
1204
+ "extension_dir": ext_root,
1202
1205
  }
1203
1206
  modern_skill_name, legacy_skill_name = self._skill_names_for_command(cmd_name)
1204
1207
  restore_index.setdefault(modern_skill_name, restore_info)
@@ -1463,6 +1466,17 @@ class PresetManager:
1463
1466
  if extension_restore:
1464
1467
  content = extension_restore["source_file"].read_text(encoding="utf-8")
1465
1468
  frontmatter, body = registrar.parse_frontmatter(content)
1469
+ # Mirror the register-time rewrite (#2101): resolve
1470
+ # extension-relative subdir references (agents/,
1471
+ # knowledge-base/, etc.) to their installed location before
1472
+ # the generic placeholder resolution below, otherwise
1473
+ # restoring after a preset override removal would leave
1474
+ # bare, unresolvable paths in the skill body.
1475
+ body = registrar.rewrite_extension_paths(
1476
+ body,
1477
+ extension_restore["extension_id"],
1478
+ extension_restore["extension_dir"],
1479
+ )
1466
1480
  if isinstance(selected_ai, str):
1467
1481
  body = registrar.resolve_skill_placeholders(
1468
1482
  selected_ai, frontmatter, body, self.project_root
@@ -3038,6 +3052,8 @@ class PresetResolver:
3038
3052
  "path": candidate,
3039
3053
  "source": source,
3040
3054
  "strategy": "replace",
3055
+ "extension_id": ext_id,
3056
+ "extension_dir": ext_dir,
3041
3057
  })
3042
3058
 
3043
3059
  # Priority 4: Core templates (always "replace")
@@ -3157,10 +3173,32 @@ class PresetResolver:
3157
3173
  if not layers:
3158
3174
  return None
3159
3175
 
3176
+ def _read_layer_content(layer: Dict[str, Any]) -> str:
3177
+ """Read a layer's raw text, rewriting extension-relative subdir
3178
+ references (agents/, knowledge-base/, etc.) to their installed
3179
+ location when the layer is extension-provided (#2101).
3180
+
3181
+ Extension layers are always inserted with strategy "replace"
3182
+ (see collect_all_layers), so a layer only ever needs this
3183
+ rewrite when it wins outright above or serves as the
3184
+ composition base below — never as a mid-stack composing
3185
+ (append/prepend/wrap) layer.
3186
+ """
3187
+ text = layer["path"].read_text(encoding="utf-8")
3188
+ extension_id = layer.get("extension_id")
3189
+ extension_dir = layer.get("extension_dir")
3190
+ if extension_id and extension_dir:
3191
+ from ..agents import CommandRegistrar
3192
+
3193
+ text = CommandRegistrar.rewrite_extension_paths(
3194
+ text, extension_id, extension_dir
3195
+ )
3196
+ return text
3197
+
3160
3198
  # If the top (highest-priority) layer is replace, it wins entirely —
3161
3199
  # lower layers are irrelevant regardless of their strategies.
3162
3200
  if layers[0]["strategy"] == "replace":
3163
- return layers[0]["path"].read_text(encoding="utf-8")
3201
+ return _read_layer_content(layers[0])
3164
3202
 
3165
3203
  # Composition: build content bottom-up from the effective base.
3166
3204
  # The base is the nearest replace layer scanning from highest priority
@@ -3183,7 +3221,7 @@ class PresetResolver:
3183
3221
 
3184
3222
  # Convert to reversed_layers index
3185
3223
  base_reversed_idx = len(layers) - 1 - base_layer_idx
3186
- content = layers[base_layer_idx]["path"].read_text(encoding="utf-8")
3224
+ content = _read_layer_content(layers[base_layer_idx])
3187
3225
  # Compose only the layers above the base (higher priority = lower index in layers,
3188
3226
  # higher index in reversed_layers). Process bottom-up from base+1.
3189
3227
  start_idx = base_reversed_idx + 1
@@ -469,7 +469,14 @@ def preset_set_priority(
469
469
  raw_priority = metadata.get("priority")
470
470
  # Only skip if the stored value is already a valid int equal to requested priority
471
471
  # This ensures corrupted values (e.g., "high") get repaired even when setting to default (10)
472
- if isinstance(raw_priority, int) and raw_priority == priority:
472
+ # A bool is an int in Python (isinstance(True, int) is True), so exclude it explicitly —
473
+ # mirroring normalize_priority's bool guard — otherwise a corrupted True/False priority
474
+ # equals 1/0 here and is never repaired.
475
+ if (
476
+ isinstance(raw_priority, int)
477
+ and not isinstance(raw_priority, bool)
478
+ and raw_priority == priority
479
+ ):
473
480
  console.print(f"[yellow]Preset '{preset_id}' already has priority {priority}[/yellow]")
474
481
  raise typer.Exit(0)
475
482
 
@@ -76,8 +76,16 @@ class WorkflowRegistry:
76
76
  if self.registry_path.exists():
77
77
  try:
78
78
  with open(self.registry_path, encoding="utf-8") as f:
79
- return json.load(f)
80
- except (json.JSONDecodeError, ValueError):
79
+ data = json.load(f)
80
+ # Validate shape: must be a dict with a dict "workflows" field,
81
+ # otherwise every method that indexes data["workflows"] crashes.
82
+ # Mirrors StepRegistry._load.
83
+ if not isinstance(data, dict):
84
+ return {"schema_version": self.SCHEMA_VERSION, "workflows": {}}
85
+ if not isinstance(data.get("workflows"), dict):
86
+ data["workflows"] = {}
87
+ return data
88
+ except (json.JSONDecodeError, ValueError, OSError, UnicodeError):
81
89
  # Corrupted registry file — reset to default
82
90
  return {"schema_version": self.SCHEMA_VERSION, "workflows": {}}
83
91
  return {"schema_version": self.SCHEMA_VERSION, "workflows": {}}
@@ -438,9 +446,9 @@ class WorkflowCatalog:
438
446
  q = query.lower()
439
447
  searchable = " ".join(
440
448
  [
441
- wf_data.get("name", ""),
442
- wf_data.get("description", ""),
443
- wf_data.get("id", ""),
449
+ str(wf_data.get("name") or ""),
450
+ str(wf_data.get("description") or ""),
451
+ str(wf_data.get("id") or ""),
444
452
  ]
445
453
  ).lower()
446
454
  if q not in searchable:
@@ -982,7 +982,16 @@ class WorkflowEngine:
982
982
  from .expressions import evaluate_condition
983
983
 
984
984
  max_iters = step_config.get("max_iterations")
985
- if not isinstance(max_iters, int) or max_iters < 1:
985
+ # A bool is an int in Python (isinstance(True, int) is True
986
+ # and True == 1), so a bool max_iterations would slip past
987
+ # the int check and cap the loop at range(0)==1 iteration
988
+ # instead of the default. Exclude bools, mirroring the
989
+ # while/do-while validators and the continue_on_error guard.
990
+ if (
991
+ isinstance(max_iters, bool)
992
+ or not isinstance(max_iters, int)
993
+ or max_iters < 1
994
+ ):
986
995
  max_iters = 10
987
996
  condition = step_config.get("condition", False)
988
997
  for _loop_iter in range(max_iters - 1):