specify-cli 0.15.1__tar.gz → 0.15.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. {specify_cli-0.15.1 → specify_cli-0.15.2}/CHANGELOG.md +25 -0
  2. {specify_cli-0.15.1 → specify_cli-0.15.2}/PKG-INFO +1 -1
  3. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/community/extensions.md +1 -0
  4. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/reference/core.md +2 -1
  5. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/reference/workflows.md +13 -0
  6. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/catalog.community.json +36 -1
  7. {specify_cli-0.15.1 → specify_cli-0.15.2}/pyproject.toml +1 -1
  8. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/__init__.py +2 -0
  9. specify_cli-0.15.2/src/specify_cli/_agent_config.py +56 -0
  10. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/agents.py +1 -1
  11. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/services/adapters.py +3 -3
  12. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/services/packager.py +5 -3
  13. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/commands/bundle/__init__.py +4 -2
  14. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/commands/init.py +220 -5
  15. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/events.py +1 -1
  16. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/extensions/__init__.py +177 -0
  17. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/extensions/_commands.py +194 -128
  18. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/kimi/__init__.py +1 -1
  19. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/presets/__init__.py +88 -7
  20. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/catalog.py +2 -2
  21. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/engine.py +47 -18
  22. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/fan_in/__init__.py +24 -2
  23. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/gate/__init__.py +25 -0
  24. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/init/__init__.py +18 -6
  25. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integration/test_bundler_init_install.py +14 -0
  26. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_cli.py +338 -0
  27. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_events.py +7 -0
  28. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_kimi.py +18 -0
  29. specify_cli-0.15.2/tests/test_commands_package.py +100 -0
  30. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_extensions.py +407 -4
  31. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_post_process.py +26 -0
  32. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_presets.py +230 -0
  33. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_workflows.py +335 -0
  34. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_adapters.py +12 -0
  35. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_packager.py +26 -0
  36. specify_cli-0.15.1/src/specify_cli/_agent_config.py +0 -24
  37. specify_cli-0.15.1/tests/test_commands_package.py +0 -52
  38. {specify_cli-0.15.1 → specify_cli-0.15.2}/.devcontainer/devcontainer.json +0 -0
  39. {specify_cli-0.15.1 → specify_cli-0.15.2}/.devcontainer/post-create.sh +0 -0
  40. {specify_cli-0.15.1 → specify_cli-0.15.2}/.editorconfig +0 -0
  41. {specify_cli-0.15.1 → specify_cli-0.15.2}/.gitattributes +0 -0
  42. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/CODEOWNERS +0 -0
  43. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/ISSUE_TEMPLATE/agent_request.yml +0 -0
  44. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  45. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/ISSUE_TEMPLATE/bundle_submission.yml +0 -0
  46. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  47. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/ISSUE_TEMPLATE/extension_submission.yml +0 -0
  48. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  49. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/ISSUE_TEMPLATE/preset_submission.yml +0 -0
  50. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  51. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/aw/actions-lock.json +0 -0
  52. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/dependabot.yml +0 -0
  53. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/scripts/check_security_requirements.py +0 -0
  54. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/security-audit-requirements.txt +0 -0
  55. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/skills/add-community-extension/SKILL.md +0 -0
  56. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/RELEASE-PROCESS.md +0 -0
  57. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/add-community-bundle.lock.yml +0 -0
  58. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/add-community-bundle.md +0 -0
  59. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/add-community-extension.lock.yml +0 -0
  60. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/add-community-extension.md +0 -0
  61. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/add-community-preset.lock.yml +0 -0
  62. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/add-community-preset.md +0 -0
  63. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/bug-assess.lock.yml +0 -0
  64. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/bug-assess.md +0 -0
  65. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/bug-fix.lock.yml +0 -0
  66. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/bug-fix.md +0 -0
  67. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/bug-test.lock.yml +0 -0
  68. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/bug-test.md +0 -0
  69. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/catalog-assign.yml +0 -0
  70. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/codeql.yml +0 -0
  71. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/docs.yml +0 -0
  72. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/lint.yml +0 -0
  73. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/publish-pypi.yml +0 -0
  74. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/release-trigger.yml +0 -0
  75. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/release.yml +0 -0
  76. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/security.yml +0 -0
  77. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/stale.yml +0 -0
  78. {specify_cli-0.15.1 → specify_cli-0.15.2}/.github/workflows/test.yml +0 -0
  79. {specify_cli-0.15.1 → specify_cli-0.15.2}/.gitignore +0 -0
  80. {specify_cli-0.15.1 → specify_cli-0.15.2}/.markdownlint-cli2.jsonc +0 -0
  81. {specify_cli-0.15.1 → specify_cli-0.15.2}/.pre-commit-config.yaml +0 -0
  82. {specify_cli-0.15.1 → specify_cli-0.15.2}/.zenodo.json +0 -0
  83. {specify_cli-0.15.1 → specify_cli-0.15.2}/AGENTS.md +0 -0
  84. {specify_cli-0.15.1 → specify_cli-0.15.2}/CITATION.cff +0 -0
  85. {specify_cli-0.15.1 → specify_cli-0.15.2}/CODE_OF_CONDUCT.md +0 -0
  86. {specify_cli-0.15.1 → specify_cli-0.15.2}/CONTRIBUTING.md +0 -0
  87. {specify_cli-0.15.1 → specify_cli-0.15.2}/DEVELOPMENT.md +0 -0
  88. {specify_cli-0.15.1 → specify_cli-0.15.2}/LICENSE +0 -0
  89. {specify_cli-0.15.1 → specify_cli-0.15.2}/README.md +0 -0
  90. {specify_cli-0.15.1 → specify_cli-0.15.2}/README.zh-CN.md +0 -0
  91. {specify_cli-0.15.1 → specify_cli-0.15.2}/SECURITY.md +0 -0
  92. {specify_cli-0.15.1 → specify_cli-0.15.2}/SUPPORT.md +0 -0
  93. {specify_cli-0.15.1 → specify_cli-0.15.2}/bundles/catalog.community.json +0 -0
  94. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/.gitignore +0 -0
  95. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/README.md +0 -0
  96. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/community/bundles.md +0 -0
  97. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/community/friends.md +0 -0
  98. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/community/overview.md +0 -0
  99. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/community/presets.md +0 -0
  100. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/community/walkthroughs.md +0 -0
  101. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/concepts/complex-features.md +0 -0
  102. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/concepts/sdd.md +0 -0
  103. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/concepts/spec-of-specs.md +0 -0
  104. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/concepts/spec-persistence.md +0 -0
  105. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/docfx.json +0 -0
  106. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/guides/evolving-specs.md +0 -0
  107. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/guides/monorepo.md +0 -0
  108. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/index.md +0 -0
  109. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/install/air-gapped.md +0 -0
  110. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/install/one-time.md +0 -0
  111. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/install/pipx.md +0 -0
  112. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/install/pypi.md +0 -0
  113. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/install/uv.md +0 -0
  114. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/installation.md +0 -0
  115. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/local-development.md +0 -0
  116. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/quickstart.md +0 -0
  117. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/reference/agentic-bugfix.md +0 -0
  118. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/reference/agentic-sdd.md +0 -0
  119. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/reference/authentication.md +0 -0
  120. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/reference/bundles.md +0 -0
  121. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/reference/extensions.md +0 -0
  122. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/reference/integrations.md +0 -0
  123. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/reference/overview.md +0 -0
  124. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/reference/presets.md +0 -0
  125. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/template/public/main.css +0 -0
  126. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/toc.yml +0 -0
  127. {specify_cli-0.15.1 → specify_cli-0.15.2}/docs/upgrade.md +0 -0
  128. {specify_cli-0.15.1 → specify_cli-0.15.2}/examples/bundles/business-analyst/README.md +0 -0
  129. {specify_cli-0.15.1 → specify_cli-0.15.2}/examples/bundles/business-analyst/bundle.yml +0 -0
  130. {specify_cli-0.15.1 → specify_cli-0.15.2}/examples/bundles/developer/README.md +0 -0
  131. {specify_cli-0.15.1 → specify_cli-0.15.2}/examples/bundles/developer/bundle.yml +0 -0
  132. {specify_cli-0.15.1 → specify_cli-0.15.2}/examples/bundles/product-manager/README.md +0 -0
  133. {specify_cli-0.15.1 → specify_cli-0.15.2}/examples/bundles/product-manager/bundle.yml +0 -0
  134. {specify_cli-0.15.1 → specify_cli-0.15.2}/examples/bundles/security-researcher/README.md +0 -0
  135. {specify_cli-0.15.1 → specify_cli-0.15.2}/examples/bundles/security-researcher/bundle.yml +0 -0
  136. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/EXTENSION-API-REFERENCE.md +0 -0
  137. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/EXTENSION-DEVELOPMENT-GUIDE.md +0 -0
  138. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/EXTENSION-PUBLISHING-GUIDE.md +0 -0
  139. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/EXTENSION-USER-GUIDE.md +0 -0
  140. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/README.md +0 -0
  141. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/RFC-EXTENSION-SYSTEM.md +0 -0
  142. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/agent-context/README.md +0 -0
  143. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/agent-context/agent-context-config.yml +0 -0
  144. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/agent-context/agent-context-defaults.json +0 -0
  145. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/agent-context/commands/speckit.agent-context.update.md +0 -0
  146. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/agent-context/extension.yml +0 -0
  147. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/agent-context/scripts/bash/update-agent-context.sh +0 -0
  148. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +0 -0
  149. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/agent-context/scripts/python/update_agent_context.py +0 -0
  150. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/assess/README.md +0 -0
  151. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/assess/commands/speckit.assess.decide.md +0 -0
  152. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/assess/commands/speckit.assess.define.md +0 -0
  153. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/assess/commands/speckit.assess.intake.md +0 -0
  154. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/assess/commands/speckit.assess.research.md +0 -0
  155. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/assess/commands/speckit.assess.shape.md +0 -0
  156. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/assess/extension.yml +0 -0
  157. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/bug/README.md +0 -0
  158. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/bug/commands/speckit.bug.assess.md +0 -0
  159. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/bug/commands/speckit.bug.fix.md +0 -0
  160. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/bug/commands/speckit.bug.test.md +0 -0
  161. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/bug/extension.yml +0 -0
  162. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/catalog.json +0 -0
  163. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/README.md +0 -0
  164. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/commands/speckit.git.commit.md +0 -0
  165. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/commands/speckit.git.feature.md +0 -0
  166. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/commands/speckit.git.initialize.md +0 -0
  167. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/commands/speckit.git.remote.md +0 -0
  168. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/commands/speckit.git.validate.md +0 -0
  169. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/config-template.yml +0 -0
  170. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/extension.yml +0 -0
  171. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/git-config.yml +0 -0
  172. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/bash/auto-commit.sh +0 -0
  173. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/bash/create-new-feature-branch.sh +0 -0
  174. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/bash/git-common.sh +0 -0
  175. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/bash/initialize-repo.sh +0 -0
  176. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
  177. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/powershell/create-new-feature-branch.ps1 +0 -0
  178. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/powershell/git-common.ps1 +0 -0
  179. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
  180. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/python/auto_commit.py +0 -0
  181. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/python/create_new_feature_branch.py +0 -0
  182. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/python/git_common.py +0 -0
  183. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/git/scripts/python/initialize_repo.py +0 -0
  184. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/selftest/commands/selftest.md +0 -0
  185. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/selftest/extension.yml +0 -0
  186. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/template/.gitignore +0 -0
  187. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/template/CHANGELOG.md +0 -0
  188. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/template/EXAMPLE-README.md +0 -0
  189. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/template/LICENSE +0 -0
  190. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/template/README.md +0 -0
  191. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/template/commands/example.md +0 -0
  192. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/template/config-template.yml +0 -0
  193. {specify_cli-0.15.1 → specify_cli-0.15.2}/extensions/template/extension.yml +0 -0
  194. {specify_cli-0.15.1 → specify_cli-0.15.2}/integrations/CONTRIBUTING.md +0 -0
  195. {specify_cli-0.15.1 → specify_cli-0.15.2}/integrations/README.md +0 -0
  196. {specify_cli-0.15.1 → specify_cli-0.15.2}/integrations/catalog.community.json +0 -0
  197. {specify_cli-0.15.1 → specify_cli-0.15.2}/integrations/catalog.json +0 -0
  198. {specify_cli-0.15.1 → specify_cli-0.15.2}/media/bootstrap-claude-code.gif +0 -0
  199. {specify_cli-0.15.1 → specify_cli-0.15.2}/media/logo_large.webp +0 -0
  200. {specify_cli-0.15.1 → specify_cli-0.15.2}/media/logo_small.webp +0 -0
  201. {specify_cli-0.15.1 → specify_cli-0.15.2}/media/spec-kit-video-header.jpg +0 -0
  202. {specify_cli-0.15.1 → specify_cli-0.15.2}/media/specify_cli.gif +0 -0
  203. {specify_cli-0.15.1 → specify_cli-0.15.2}/newsletters/2026-April.md +0 -0
  204. {specify_cli-0.15.1 → specify_cli-0.15.2}/newsletters/2026-February.md +0 -0
  205. {specify_cli-0.15.1 → specify_cli-0.15.2}/newsletters/2026-June.md +0 -0
  206. {specify_cli-0.15.1 → specify_cli-0.15.2}/newsletters/2026-March.md +0 -0
  207. {specify_cli-0.15.1 → specify_cli-0.15.2}/newsletters/2026-May.md +0 -0
  208. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/ARCHITECTURE.md +0 -0
  209. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/PUBLISHING.md +0 -0
  210. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/README.md +0 -0
  211. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/catalog.community.json +0 -0
  212. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/catalog.json +0 -0
  213. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/constitution-sync/README.md +0 -0
  214. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/constitution-sync/commands/speckit.constitution.md +0 -0
  215. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/constitution-sync/preset.yml +0 -0
  216. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/lean/README.md +0 -0
  217. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/lean/commands/speckit.constitution.md +0 -0
  218. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/lean/commands/speckit.implement.md +0 -0
  219. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/lean/commands/speckit.plan.md +0 -0
  220. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/lean/commands/speckit.specify.md +0 -0
  221. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/lean/commands/speckit.tasks.md +0 -0
  222. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/lean/preset.yml +0 -0
  223. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/scaffold/README.md +0 -0
  224. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/scaffold/commands/speckit.myext.myextcmd.md +0 -0
  225. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/scaffold/commands/speckit.specify.md +0 -0
  226. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/scaffold/preset.yml +0 -0
  227. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/scaffold/templates/myext-template.md +0 -0
  228. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/scaffold/templates/spec-template.md +0 -0
  229. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/self-test/commands/speckit.specify.md +0 -0
  230. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/self-test/commands/speckit.wrap-test.md +0 -0
  231. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/self-test/preset.yml +0 -0
  232. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/self-test/templates/checklist-template.md +0 -0
  233. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/self-test/templates/constitution-template.md +0 -0
  234. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/self-test/templates/plan-template.md +0 -0
  235. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/self-test/templates/spec-template.md +0 -0
  236. {specify_cli-0.15.1 → specify_cli-0.15.2}/presets/self-test/templates/tasks-template.md +0 -0
  237. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/bash/check-prerequisites.sh +0 -0
  238. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/bash/common.sh +0 -0
  239. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/bash/create-new-feature.sh +0 -0
  240. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/bash/setup-plan.sh +0 -0
  241. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/bash/setup-tasks.sh +0 -0
  242. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/powershell/check-prerequisites.ps1 +0 -0
  243. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/powershell/common.ps1 +0 -0
  244. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/powershell/create-new-feature.ps1 +0 -0
  245. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/powershell/setup-plan.ps1 +0 -0
  246. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/powershell/setup-tasks.ps1 +0 -0
  247. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/python/check_prerequisites.py +0 -0
  248. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/python/common.py +0 -0
  249. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/python/create_new_feature.py +0 -0
  250. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/python/setup_plan.py +0 -0
  251. {specify_cli-0.15.1 → specify_cli-0.15.2}/scripts/python/setup_tasks.py +0 -0
  252. {specify_cli-0.15.1 → specify_cli-0.15.2}/spec-driven.md +0 -0
  253. {specify_cli-0.15.1 → specify_cli-0.15.2}/spec-kit.code-workspace +0 -0
  254. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/_assets.py +0 -0
  255. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/_console.py +0 -0
  256. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/_download_security.py +0 -0
  257. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/_github_http.py +0 -0
  258. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/_init_options.py +0 -0
  259. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/_invocation_style.py +0 -0
  260. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/_project.py +0 -0
  261. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/_toml_string.py +0 -0
  262. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/_utils.py +0 -0
  263. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/_version.py +0 -0
  264. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/authentication/__init__.py +0 -0
  265. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/authentication/azure_devops.py +0 -0
  266. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/authentication/base.py +0 -0
  267. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/authentication/config.py +0 -0
  268. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/authentication/github.py +0 -0
  269. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/authentication/http.py +0 -0
  270. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/__init__.py +0 -0
  271. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/commands_impl/__init__.py +0 -0
  272. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/commands_impl/catalog_config.py +0 -0
  273. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/lib/__init__.py +0 -0
  274. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/lib/project.py +0 -0
  275. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/lib/versioning.py +0 -0
  276. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/lib/yamlio.py +0 -0
  277. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/models/__init__.py +0 -0
  278. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/models/catalog.py +0 -0
  279. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/models/manifest.py +0 -0
  280. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/models/records.py +0 -0
  281. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/services/__init__.py +0 -0
  282. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/services/catalog_stack.py +0 -0
  283. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/services/conflict.py +0 -0
  284. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/services/installer.py +0 -0
  285. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/services/primitives.py +0 -0
  286. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/services/references.py +0 -0
  287. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/services/resolver.py +0 -0
  288. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/bundler/services/validator.py +0 -0
  289. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/catalogs.py +0 -0
  290. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/commands/__init__.py +0 -0
  291. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/commands/event.py +0 -0
  292. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integration_runtime.py +0 -0
  293. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integration_scaffold.py +0 -0
  294. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integration_state.py +0 -0
  295. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integration_status.py +0 -0
  296. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/__init__.py +0 -0
  297. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/_commands.py +0 -0
  298. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/_helpers.py +0 -0
  299. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/_install_commands.py +0 -0
  300. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/_migrate_commands.py +0 -0
  301. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/_query_commands.py +0 -0
  302. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/_scaffold_commands.py +0 -0
  303. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/agy/__init__.py +0 -0
  304. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/alquimia/__init__.py +0 -0
  305. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/amp/__init__.py +0 -0
  306. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/auggie/__init__.py +0 -0
  307. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/base.py +0 -0
  308. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/bob/__init__.py +0 -0
  309. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/catalog.py +0 -0
  310. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/claude/__init__.py +0 -0
  311. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/cline/__init__.py +0 -0
  312. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/codebuddy/__init__.py +0 -0
  313. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/codex/__init__.py +0 -0
  314. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/copilot/__init__.py +0 -0
  315. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/cursor_agent/__init__.py +0 -0
  316. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/devin/__init__.py +0 -0
  317. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/droid/__init__.py +0 -0
  318. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/firebender/__init__.py +0 -0
  319. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/forge/__init__.py +0 -0
  320. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/gemini/__init__.py +0 -0
  321. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/generic/__init__.py +0 -0
  322. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/goose/__init__.py +0 -0
  323. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/grok/__init__.py +0 -0
  324. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/hermes/__init__.py +0 -0
  325. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/junie/__init__.py +0 -0
  326. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/kilocode/__init__.py +0 -0
  327. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/kiro_cli/__init__.py +0 -0
  328. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/lingma/__init__.py +0 -0
  329. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/manifest.py +0 -0
  330. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/omp/__init__.py +0 -0
  331. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/opencode/__init__.py +0 -0
  332. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/pi/__init__.py +0 -0
  333. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/qodercli/__init__.py +0 -0
  334. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/qwen/__init__.py +0 -0
  335. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/rovodev/__init__.py +0 -0
  336. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/shai/__init__.py +0 -0
  337. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/tabnine/__init__.py +0 -0
  338. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/trae/__init__.py +0 -0
  339. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/vibe/__init__.py +0 -0
  340. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/zcode/__init__.py +0 -0
  341. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/integrations/zed/__init__.py +0 -0
  342. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/presets/_commands.py +0 -0
  343. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/shared_infra.py +0 -0
  344. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/__init__.py +0 -0
  345. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/_commands.py +0 -0
  346. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/base.py +0 -0
  347. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/expressions.py +0 -0
  348. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/overlays/__init__.py +0 -0
  349. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/overlays/_commands.py +0 -0
  350. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/overlays/composer.py +0 -0
  351. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/overlays/layer_sources.py +0 -0
  352. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/overlays/merge.py +0 -0
  353. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/overlays/schema.py +0 -0
  354. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/__init__.py +0 -0
  355. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/command/__init__.py +0 -0
  356. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/do_while/__init__.py +0 -0
  357. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/fan_out/__init__.py +0 -0
  358. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/if_then/__init__.py +0 -0
  359. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/prompt/__init__.py +0 -0
  360. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/shell/__init__.py +0 -0
  361. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/switch/__init__.py +0 -0
  362. {specify_cli-0.15.1 → specify_cli-0.15.2}/src/specify_cli/workflows/steps/while_loop/__init__.py +0 -0
  363. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/checklist-template.md +0 -0
  364. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/commands/analyze.md +0 -0
  365. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/commands/checklist.md +0 -0
  366. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/commands/clarify.md +0 -0
  367. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/commands/constitution.md +0 -0
  368. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/commands/converge.md +0 -0
  369. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/commands/implement.md +0 -0
  370. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/commands/plan.md +0 -0
  371. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/commands/specify.md +0 -0
  372. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/commands/tasks.md +0 -0
  373. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/commands/taskstoissues.md +0 -0
  374. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/constitution-template.md +0 -0
  375. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/plan-template.md +0 -0
  376. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/spec-template.md +0 -0
  377. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/tasks-template.md +0 -0
  378. {specify_cli-0.15.1 → specify_cli-0.15.2}/templates/vscode-settings.json +0 -0
  379. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/__init__.py +0 -0
  380. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/auth_helpers.py +0 -0
  381. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/bundler_helpers.py +0 -0
  382. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/conftest.py +0 -0
  383. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/contract/test_bundle_cli.py +0 -0
  384. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/contract/test_catalog_schema.py +0 -0
  385. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/contract/test_manifest_schema.py +0 -0
  386. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/contract/test_wheel_bundled_presets.py +0 -0
  387. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/contract/test_wheel_core_pack_scripts.py +0 -0
  388. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/__init__.py +0 -0
  389. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/assess/__init__.py +0 -0
  390. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/assess/test_assess_extension.py +0 -0
  391. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/bug/__init__.py +0 -0
  392. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/bug/test_bug_extension.py +0 -0
  393. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/git/__init__.py +0 -0
  394. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/git/test_git_extension.py +0 -0
  395. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/git/test_git_extension_python_parity.py +0 -0
  396. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/test_agent_context_cli_free.py +0 -0
  397. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/test_extension_agent_context.py +0 -0
  398. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/test_update_agent_context_feature_json.py +0 -0
  399. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/extensions/test_update_agent_context_python_parity.py +0 -0
  400. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/hooks/TESTING.md +0 -0
  401. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/hooks/plan.md +0 -0
  402. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/hooks/spec.md +0 -0
  403. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/hooks/tasks.md +0 -0
  404. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/http_helpers.py +0 -0
  405. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integration/test_bundler_catalog_stack.py +0 -0
  406. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integration/test_bundler_install_flow.py +0 -0
  407. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integration/test_bundler_local_install.py +0 -0
  408. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integration/test_bundler_offline.py +0 -0
  409. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integration/test_bundler_security_paths.py +0 -0
  410. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/__init__.py +0 -0
  411. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/conftest.py +0 -0
  412. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_base.py +0 -0
  413. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_extra_args.py +0 -0
  414. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_home_isolation.py +0 -0
  415. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_agy.py +0 -0
  416. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_alquimia.py +0 -0
  417. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_amp.py +0 -0
  418. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_auggie.py +0 -0
  419. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_base_markdown.py +0 -0
  420. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_base_skills.py +0 -0
  421. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_base_toml.py +0 -0
  422. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_base_yaml.py +0 -0
  423. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_bob.py +0 -0
  424. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_catalog.py +0 -0
  425. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_claude.py +0 -0
  426. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_cline.py +0 -0
  427. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_codebuddy.py +0 -0
  428. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_codex.py +0 -0
  429. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_copilot.py +0 -0
  430. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_cursor_agent.py +0 -0
  431. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_devin.py +0 -0
  432. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_droid.py +0 -0
  433. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_firebender.py +0 -0
  434. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_forge.py +0 -0
  435. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_gemini.py +0 -0
  436. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_generic.py +0 -0
  437. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_goose.py +0 -0
  438. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_grok.py +0 -0
  439. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_hermes.py +0 -0
  440. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_junie.py +0 -0
  441. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_kilocode.py +0 -0
  442. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_kiro_cli.py +0 -0
  443. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_lingma.py +0 -0
  444. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_omp.py +0 -0
  445. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_opencode.py +0 -0
  446. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_pi.py +0 -0
  447. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_qodercli.py +0 -0
  448. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_qwen.py +0 -0
  449. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_rovodev.py +0 -0
  450. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_scaffold.py +0 -0
  451. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_shai.py +0 -0
  452. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_state.py +0 -0
  453. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_subcommand.py +0 -0
  454. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_tabnine.py +0 -0
  455. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_trae.py +0 -0
  456. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_vibe.py +0 -0
  457. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_zcode.py +0 -0
  458. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_integration_zed.py +0 -0
  459. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_manifest.py +0 -0
  460. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_registry.py +0 -0
  461. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/integrations/test_skill_frontmatter_quoting.py +0 -0
  462. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/parity_helpers.py +0 -0
  463. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/self_upgrade_helpers.py +0 -0
  464. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_agent_config_consistency.py +0 -0
  465. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_authentication.py +0 -0
  466. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_branch_numbering.py +0 -0
  467. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_check_prerequisites_paths_only.py +0 -0
  468. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_check_prerequisites_python_parity.py +0 -0
  469. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_check_tool.py +0 -0
  470. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_cli_version.py +0 -0
  471. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_command_template_py_scripts.py +0 -0
  472. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_console_imports.py +0 -0
  473. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_create_new_feature_python_parity.py +0 -0
  474. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_download_security.py +0 -0
  475. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_extension_add_path_traversal.py +0 -0
  476. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_extension_registration.py +0 -0
  477. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_extension_skills.py +0 -0
  478. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_extension_update_hardening.py +0 -0
  479. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_github_http.py +0 -0
  480. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_github_workflows.py +0 -0
  481. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_init_dir.py +0 -0
  482. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_init_dir_cli.py +0 -0
  483. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_live_transient_windows.py +0 -0
  484. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_merge.py +0 -0
  485. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_ps1_encoding.py +0 -0
  486. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_registrar_path_traversal.py +0 -0
  487. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_security_workflow.py +0 -0
  488. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_self_upgrade_detection.py +0 -0
  489. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_self_upgrade_execution.py +0 -0
  490. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_self_upgrade_guidance.py +0 -0
  491. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_self_upgrade_verification.py +0 -0
  492. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_setup_plan_feature_json.py +0 -0
  493. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_setup_plan_no_overwrite.py +0 -0
  494. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_setup_plan_python_parity.py +0 -0
  495. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_setup_tasks.py +0 -0
  496. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_setup_tasks_python_parity.py +0 -0
  497. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_shared_infra_integrity.py +0 -0
  498. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_skill_placeholder_py.py +0 -0
  499. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_specify_template_numbering.py +0 -0
  500. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_timestamp_branches.py +0 -0
  501. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_upgrade.py +0 -0
  502. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_utils.py +0 -0
  503. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_utils_assets_imports.py +0 -0
  504. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_version_imports.py +0 -0
  505. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/test_workflow_run_without_project.py +0 -0
  506. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundle_download_url.py +0 -0
  507. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_catalog_config.py +0 -0
  508. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_conflict.py +0 -0
  509. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_primitives.py +0 -0
  510. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_records.py +0 -0
  511. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_references.py +0 -0
  512. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_resolver.py +0 -0
  513. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_validator.py +0 -0
  514. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_versioning.py +0 -0
  515. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/unit/test_bundler_yamlio.py +0 -0
  516. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/workflows/conftest.py +0 -0
  517. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/workflows/test_overlay_commands.py +0 -0
  518. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/workflows/test_overlay_composer.py +0 -0
  519. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/workflows/test_overlay_layer_sources.py +0 -0
  520. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/workflows/test_overlay_merge.py +0 -0
  521. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/workflows/test_overlay_schema.py +0 -0
  522. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/workflows/test_overlay_security.py +0 -0
  523. {specify_cli-0.15.1 → specify_cli-0.15.2}/tests/workflows/test_resolver_integration.py +0 -0
  524. {specify_cli-0.15.1 → specify_cli-0.15.2}/workflows/ARCHITECTURE.md +0 -0
  525. {specify_cli-0.15.1 → specify_cli-0.15.2}/workflows/PUBLISHING.md +0 -0
  526. {specify_cli-0.15.1 → specify_cli-0.15.2}/workflows/README.md +0 -0
  527. {specify_cli-0.15.1 → specify_cli-0.15.2}/workflows/catalog.community.json +0 -0
  528. {specify_cli-0.15.1 → specify_cli-0.15.2}/workflows/catalog.json +0 -0
  529. {specify_cli-0.15.1 → specify_cli-0.15.2}/workflows/speckit/workflow.yml +0 -0
  530. {specify_cli-0.15.1 → specify_cli-0.15.2}/workflows/step-catalog.community.json +0 -0
  531. {specify_cli-0.15.1 → specify_cli-0.15.2}/workflows/step-catalog.json +0 -0
@@ -2,6 +2,31 @@
2
2
 
3
3
  <!-- insert new changelog below this comment -->
4
4
 
5
+ ## [0.15.2] - 2026-08-03
6
+
7
+ ### Changed
8
+
9
+ - fix(presets): restore core skills instead of deleting them on preset remove (#3929)
10
+ - fix(manifests): reject non-string metadata instead of crashing on it (#3943)
11
+ - fix: narrow bare except Exception in invoke separator resolution (#3856)
12
+ - fix(workflows): keep the init step's documented ignore_agent_tools default on an explicit null (#3889)
13
+ - fix(kimi): preserve non-UTF-8 user skills (#3895)
14
+ - fix(presets): tolerate non-UTF-8 legacy commands (#3896)
15
+ - feat: allow overriding default init integration via SPECKIT_INTEGRATION_DEFAULT (#3952)
16
+ - Add adrkit extension to community catalog (#3947)
17
+ - feat(extensions): scaffold config templates on extension add/enable (#2000)
18
+ - fix(events): skip non-UTF-8 extension manifests (#3900)
19
+ - fix(workflows): fail a gate whose on_reject is not abort/skip/retry (#3888)
20
+ - fix(presets): validate required manifest mappings (#3898)
21
+ - fix: eliminate TOCTOU race in zip packaging (#3855)
22
+ - fix(workflows): fail a fan-in step whose output is not a mapping (#3887)
23
+ - fix(workflows): refetch non-UTF-8 catalog caches (#3901)
24
+ - fix(bundler): wrap local catalog decode failures (#3902)
25
+ - Add `--extension` flag to `specify init` for opting into extensions at init time (#3914)
26
+ - fix: bound response reads in extension catalog and download (#3775)
27
+ - fix(workflows): reject a retry gate whose verdict enum forbids the reset value (#3912)
28
+ - chore: release 0.15.1, begin 0.15.2.dev0 development (#3913)
29
+
5
30
  ## [0.15.1] - 2026-07-31
6
31
 
7
32
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specify-cli
3
- Version: 0.15.1
3
+ Version: 0.15.2
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
@@ -25,6 +25,7 @@ The following community-contributed extensions are available in [`catalog.commun
25
25
 
26
26
  | Extension | Purpose | Category | Effect | URL |
27
27
  |-----------|---------|----------|--------|-----|
28
+ | adrkit — decision memory for spec-driven development | Pulls the decisions governing this work into agent context, checks produced plans against them, and drafts an ADR from a plan artifact | `process` | Read+Write | [adrkit](https://github.com/mbeacom/adrkit) |
28
29
  | Agent Assign | Assign specialized Claude Code agents to spec-kit tasks for targeted execution | `process` | Read+Write | [spec-kit-agent-assign](https://github.com/xymelon/spec-kit-agent-assign) |
29
30
  | Agent Governance | Generate agent-platform repository governance files from Spec Kit metadata | `process` | Read+Write | [spec-kit-agent-governance](https://github.com/bigsmartben/spec-kit-agent-governance) |
30
31
  | AI-Driven Engineering (AIDE) | A structured 7-step workflow for building new projects from scratch with AI assistants — from vision through implementation | `process` | Read+Write | [aide](https://github.com/mnriem/spec-kit-extensions/tree/main/aide) |
@@ -25,7 +25,7 @@ Creates a new Spec Kit project with the necessary directory structure, templates
25
25
 
26
26
  Use `<project_name>` to create a new directory, or `--here` (or `.`) to initialize in the current directory. If the directory already has files, use `--force` to merge without confirmation.
27
27
 
28
- When `--integration` is omitted, interactive terminals prompt you to choose an integration. Non-interactive sessions, such as CI or piped runs, default to GitHub Copilot; pass `--integration <key>` to choose a different integration explicitly.
28
+ When `--integration` is omitted, interactive terminals prompt you to choose an integration. Non-interactive sessions, such as CI or piped runs, default to GitHub Copilot; pass `--integration <key>` to choose a different integration explicitly, or set `SPECKIT_INTEGRATION_DEFAULT` to change the fallback (see [Environment Variables](#environment-variables)).
29
29
 
30
30
  ### Examples
31
31
 
@@ -50,6 +50,7 @@ specify init my-project --integration copilot --preset compliance
50
50
 
51
51
  | Variable | Description |
52
52
  | ----------------- | ------------------------------------------------------------------------ |
53
+ | `SPECKIT_INTEGRATION_DEFAULT` | Override the fallback integration used by `specify init` when `--integration` is omitted (interactive prompt default and non-interactive fallback). Set it to any registered integration key (e.g. `gemini`, `claude`). An unrecognized value is ignored with a warning and the built-in default (`copilot`) is used. An explicit `--integration <key>` always takes precedence. |
53
54
  | `SPECIFY_INIT_DIR` | Target a member project from outside its directory (e.g. a monorepo root) without `cd`, for non-interactive / CI use. Set it to the **project root** — the directory *containing* `.specify/` (relative paths resolve against the current directory). The path must exist and contain `.specify/`, otherwise the command errors and does **not** fall back to the current directory. Resolved once in the core root helper (`get_repo_root` in Bash, `Get-RepoRoot` in PowerShell), so it is honored by the core feature scripts (`/speckit.plan`, `/speckit.tasks`, …) and the Git extension's feature-branch creation, which inherit it. The `specify` CLI applies the **same** validation rules to every project-scoped subcommand (`specify integration …`, `specify extension …`, `specify workflow …`, `specify preset …`, and the rest that operate on a `.specify/` project), so those can target a member project too. When unset, Bash/PowerShell helpers keep their existing upward search; the `specify` CLI keeps its project-scoped resolver cwd-only unless a command explicitly defines broader detection (for example, bundle commands). |
54
55
  | `SPECIFY_FEATURE_DIRECTORY` | Override the active feature directory *within* the resolved project (takes precedence over `.specify/feature.json`). Relative paths resolve under the project root. Combine with `SPECIFY_INIT_DIR` to pick both the project and the feature non-interactively. |
55
56
  | `SPECIFY_FEATURE` | Override feature detection for non-Git repositories. Set to the feature directory name (e.g., `001-photo-albums`) to work on a specific feature when not using Git branches. Must be set in the context of the agent prior to using `/speckit.plan` or follow-up commands. |
@@ -623,6 +623,19 @@ pauses: the named stored input is reset to `""`. A later resume therefore
623
623
  prompts or pauses again until another verdict is supplied. Approve, abort, and
624
624
  skip outcomes leave the input unchanged.
625
625
 
626
+ Because of that reset, a verdict input used with `on_reject: retry` must accept
627
+ `""`. If it declares an `enum`, include the empty string — otherwise the reset
628
+ value violates the input's own `enum` and the run can no longer be resumed with
629
+ any input. `specify workflow add` reports this as a validation error.
630
+
631
+ ```yaml
632
+ inputs:
633
+ spec_verdict:
634
+ type: string
635
+ enum: ["", approve, reject]
636
+ default: ""
637
+ ```
638
+
626
639
  ## FAQ
627
640
 
628
641
  ### What happens when a workflow hits a gate step?
@@ -1,8 +1,43 @@
1
1
  {
2
2
  "schema_version": "1.0",
3
- "updated_at": "2026-07-29T00:00:00Z",
3
+ "updated_at": "2026-08-03T00:00:00Z",
4
4
  "catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.community.json",
5
5
  "extensions": {
6
+ "adrkit": {
7
+ "name": "adrkit — decision memory for spec-driven development",
8
+ "id": "adrkit",
9
+ "description": "Pulls the decisions governing this work into agent context, checks produced plans against them, and drafts an ADR from a plan artifact.",
10
+ "author": "Mark Beacom (@mbeacom)",
11
+ "version": "0.1.2",
12
+ "download_url": "https://github.com/mbeacom/adrkit/releases/download/spec-kit-v0.1.2/adrkit.zip",
13
+ "repository": "https://github.com/mbeacom/adrkit",
14
+ "homepage": "https://adrkit.dev",
15
+ "documentation": "https://github.com/mbeacom/adrkit/blob/main/packages/adapters/spec-kit/README.md",
16
+ "changelog": "https://github.com/mbeacom/adrkit/blob/main/CHANGELOG.md",
17
+ "license": "Apache-2.0",
18
+ "category": "process",
19
+ "effect": "read-write",
20
+ "requires": {
21
+ "speckit_version": ">=0.13.0,<0.16.0",
22
+ "tools": [{ "name": "adr", "version": ">=0.3.0", "required": true }]
23
+ },
24
+ "provides": {
25
+ "commands": 3,
26
+ "hooks": 1
27
+ },
28
+ "tags": [
29
+ "adr",
30
+ "governance",
31
+ "decision-records",
32
+ "architecture",
33
+ "compliance"
34
+ ],
35
+ "verified": false,
36
+ "downloads": 0,
37
+ "stars": 0,
38
+ "created_at": "2026-08-03T00:00:00Z",
39
+ "updated_at": "2026-08-03T00:00:00Z"
40
+ },
6
41
  "aide": {
7
42
  "name": "AI-Driven Engineering (AIDE)",
8
43
  "id": "aide",
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "specify-cli"
3
- version = "0.15.1"
3
+ version = "0.15.2"
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"
@@ -77,7 +77,9 @@ from ._version import (
77
77
  from ._agent_config import (
78
78
  AGENT_CONFIG as AGENT_CONFIG,
79
79
  DEFAULT_INIT_INTEGRATION as DEFAULT_INIT_INTEGRATION,
80
+ DEFAULT_INIT_INTEGRATION_ENV_VAR as DEFAULT_INIT_INTEGRATION_ENV_VAR,
80
81
  SCRIPT_TYPE_CHOICES as SCRIPT_TYPE_CHOICES,
82
+ resolve_default_init_integration as resolve_default_init_integration,
81
83
  )
82
84
  from ._init_options import (
83
85
  INIT_OPTIONS_FILE as INIT_OPTIONS_FILE,
@@ -0,0 +1,56 @@
1
+ """Agent configuration constants derived from the integration registry."""
2
+ from __future__ import annotations
3
+
4
+ import os
5
+ import sys
6
+ from typing import Any
7
+
8
+
9
+ def _build_agent_config() -> dict[str, dict[str, Any]]:
10
+ from .integrations import INTEGRATION_REGISTRY
11
+ config: dict[str, dict[str, Any]] = {}
12
+ for key, integration in INTEGRATION_REGISTRY.items():
13
+ if integration.config:
14
+ config[key] = dict(integration.config)
15
+ return config
16
+
17
+
18
+ AGENT_CONFIG: dict[str, dict[str, Any]] = _build_agent_config()
19
+
20
+ DEFAULT_INIT_INTEGRATION = "copilot"
21
+
22
+ #: Environment variable used to override the fallback integration that
23
+ #: ``specify init`` selects in non-interactive sessions. Follows the existing
24
+ #: ``SPECKIT_INTEGRATION_*`` namespace (see ``SPECKIT_INTEGRATION_<KEY>_EXECUTABLE``
25
+ #: and ``SPECKIT_INTEGRATION_CATALOG_URL``).
26
+ DEFAULT_INIT_INTEGRATION_ENV_VAR = "SPECKIT_INTEGRATION_DEFAULT"
27
+
28
+
29
+ def resolve_default_init_integration() -> str:
30
+ """Return the default init integration, honoring an env-var override.
31
+
32
+ Reads :data:`DEFAULT_INIT_INTEGRATION_ENV_VAR`
33
+ (``SPECKIT_INTEGRATION_DEFAULT``). When it names a registered integration
34
+ key, that key is returned; otherwise the hardcoded
35
+ :data:`DEFAULT_INIT_INTEGRATION` (``"copilot"``) is used. An invalid value
36
+ emits a warning to stderr rather than silently falling back, so operators
37
+ can tell a typo from an intentional default.
38
+ """
39
+ override = (os.environ.get(DEFAULT_INIT_INTEGRATION_ENV_VAR) or "").strip()
40
+ if not override:
41
+ return DEFAULT_INIT_INTEGRATION
42
+ if override in AGENT_CONFIG:
43
+ return override
44
+ print(
45
+ f"Warning: {DEFAULT_INIT_INTEGRATION_ENV_VAR}='{override}' is not a "
46
+ f"recognized integration; falling back to '{DEFAULT_INIT_INTEGRATION}'. "
47
+ f"Choose from: {', '.join(sorted(AGENT_CONFIG.keys()))}.",
48
+ file=sys.stderr,
49
+ )
50
+ return DEFAULT_INIT_INTEGRATION
51
+
52
+ SCRIPT_TYPE_CHOICES: dict[str, str] = {
53
+ "sh": "POSIX Shell (bash/zsh)",
54
+ "ps": "PowerShell",
55
+ "py": "Python",
56
+ }
@@ -679,7 +679,7 @@ class CommandRegistrar:
679
679
  _integ = get_integration(agent_name)
680
680
  if _integ is not None:
681
681
  _sep = _integ.invoke_separator_for_mode(registrar_writes_skills)
682
- except Exception:
682
+ except (ImportError, ValueError, KeyError):
683
683
  pass
684
684
  _prefix = get_invocation_prefix(agent_name, registrar_writes_skills)
685
685
 
@@ -18,7 +18,7 @@ from urllib.request import url2pathname
18
18
  from ..._assets import _locate_core_pack, _repo_root
19
19
  from ..._download_security import MAX_JSON_CATALOG_BYTES, read_response_limited
20
20
  from .. import BundlerError
21
- from ..lib.yamlio import loads_json
21
+ from ..lib.yamlio import load_json, loads_json
22
22
  from ..models.catalog import CatalogSource
23
23
  from ..models.manifest import ComponentRef
24
24
 
@@ -145,13 +145,13 @@ def make_catalog_fetcher(*, allow_network: bool = True):
145
145
  path = _file_url_to_path(parsed)
146
146
  if not path.exists():
147
147
  raise BundlerError(f"Catalog file not found: {path}")
148
- return loads_json(path.read_text(encoding="utf-8"), origin=str(path))
148
+ return load_json(path)
149
149
 
150
150
  if scheme == "" or _is_windows_drive_path(url):
151
151
  path = Path(url)
152
152
  if not path.exists():
153
153
  raise BundlerError(f"Catalog file not found: {path}")
154
- return loads_json(path.read_text(encoding="utf-8"), origin=str(path))
154
+ return load_json(path)
155
155
 
156
156
  if scheme in ("http", "https"):
157
157
  if not allow_network:
@@ -93,9 +93,11 @@ def build_bundle(
93
93
  # extraction, but collapse to two canonical modes (0755 when any
94
94
  # execute bit is set on the source, otherwise 0644) so identical
95
95
  # inputs yield a byte-for-byte identical artifact.
96
- mode = 0o755 if file_path.stat().st_mode & 0o111 else 0o644
97
- info.external_attr = mode << 16
98
- archive.writestr(info, file_path.read_bytes())
96
+ with file_path.open("rb") as fh:
97
+ st = os.fstat(fh.fileno())
98
+ mode = 0o755 if st.st_mode & 0o111 else 0o644
99
+ info.external_attr = mode << 16
100
+ archive.writestr(info, fh.read())
99
101
 
100
102
  return BuildResult(artifact_path=artifact_path, file_count=len(files))
101
103
 
@@ -119,6 +119,8 @@ def _run_init(integration: str, *, script_type: str, offline: bool = False) -> N
119
119
  preset=None,
120
120
  integration=integration,
121
121
  integration_options=None,
122
+ extensions=None,
123
+ trust_extension_urls=False,
122
124
  )
123
125
  except typer.Exit as exc:
124
126
  if exc.exit_code:
@@ -129,13 +131,13 @@ def _run_init(integration: str, *, script_type: str, offline: bool = False) -> N
129
131
 
130
132
  def _resolve_init_integration(override: str | None, manifest) -> str:
131
133
  """Precedence (FR-013): explicit override → bundle-declared → default."""
132
- from ..._agent_config import DEFAULT_INIT_INTEGRATION
134
+ from ..._agent_config import resolve_default_init_integration
133
135
 
134
136
  if override:
135
137
  return override
136
138
  if manifest is not None and manifest.integration is not None:
137
139
  return manifest.integration.id
138
- return DEFAULT_INIT_INTEGRATION
140
+ return resolve_default_init_integration()
139
141
 
140
142
 
141
143
  # ===== Consume =====
@@ -14,8 +14,8 @@ from rich.panel import Panel
14
14
 
15
15
  from .._agent_config import (
16
16
  AGENT_CONFIG,
17
- DEFAULT_INIT_INTEGRATION,
18
17
  SCRIPT_TYPE_CHOICES,
18
+ resolve_default_init_integration,
19
19
  )
20
20
  from .._assets import (
21
21
  _locate_bundled_preset,
@@ -30,6 +30,145 @@ def _stdin_is_interactive() -> bool:
30
30
  return sys.stdin.isatty()
31
31
 
32
32
 
33
+ def _ext_spec_is_url(ext_spec: str) -> bool:
34
+ """Return True when *ext_spec* is an http(s) URL rather than a name/path."""
35
+ from urllib.parse import urlparse
36
+
37
+ try:
38
+ return urlparse(ext_spec).scheme in ("http", "https")
39
+ except ValueError:
40
+ return False
41
+
42
+
43
+ def _confirm_extension_url_trust(
44
+ url_specs: list[str], *, trust_override: bool
45
+ ) -> dict[str, bool]:
46
+ """Resolve trust for each URL-based extension before the Live display.
47
+
48
+ URL installs pull an arbitrary external extension, so they get the same
49
+ default-deny confirmation as ``extension add --from``. Returns a mapping of
50
+ ``url_spec -> approved``. With *trust_override* every URL is pre-approved.
51
+ In a non-interactive session without the override, every URL is denied
52
+ (the prompt cannot be answered), mirroring the default-deny posture.
53
+ """
54
+ from rich.markup import escape as _escape_markup
55
+ from rich.panel import Panel
56
+
57
+ approvals: dict[str, bool] = {}
58
+ interactive = _stdin_is_interactive()
59
+ for spec in url_specs:
60
+ if trust_override:
61
+ approvals[spec] = True
62
+ continue
63
+ if not interactive:
64
+ approvals[spec] = False
65
+ continue
66
+ console.print()
67
+ console.print(
68
+ Panel(
69
+ "[bold]You are installing an extension from an external URL that is not\n"
70
+ "listed in any of your configured extension catalogs.[/bold]\n\n"
71
+ f"URL: {_escape_markup(spec)}\n\n"
72
+ "Only install extensions from sources you trust.",
73
+ title="[bold yellow]⚠ Untrusted Source[/bold yellow]",
74
+ border_style="yellow",
75
+ padding=(1, 2),
76
+ )
77
+ )
78
+ console.print()
79
+ approvals[spec] = typer.confirm(
80
+ f"Install extension from {spec}?", default=False
81
+ )
82
+ return approvals
83
+
84
+
85
+ def _install_extension_during_init(project_path: Path, ext_spec: str, speckit_version: str) -> str:
86
+ """Install a single extension during ``specify init``.
87
+
88
+ Handles bundled extension names, local directory paths, and HTTPS URLs.
89
+ Returns a short status message on success.
90
+ Raises ``ValueError`` on failure so the caller can convert it to a
91
+ tracker error without aborting the entire init.
92
+ """
93
+ from urllib.parse import urlparse
94
+
95
+ from .._assets import _locate_bundled_extension
96
+ from ..extensions import ExtensionCatalog, ExtensionError, ExtensionManager
97
+ from ..extensions._commands import (
98
+ _resolve_catalog_extension,
99
+ install_extension_from_url,
100
+ )
101
+
102
+ manager = ExtensionManager(project_path)
103
+
104
+ # --- URL ---
105
+ parsed = urlparse(ext_spec)
106
+ if parsed.scheme in ("http", "https"):
107
+ try:
108
+ manifest = install_extension_from_url(
109
+ manager, project_path, ext_spec, speckit_version
110
+ )
111
+ except ExtensionError as exc:
112
+ raise ValueError(str(exc)) from exc
113
+ return f"{manifest.name} v{manifest.version} installed"
114
+
115
+ # --- Local path ---
116
+ if ext_spec.startswith(("./", "../", "/", "~/", ".\\", "..\\")) or Path(ext_spec).is_absolute():
117
+ source_path = Path(ext_spec).expanduser().resolve()
118
+ if not source_path.exists():
119
+ raise ValueError(f"Directory not found: {source_path}")
120
+ if not (source_path / "extension.yml").exists():
121
+ raise ValueError(f"No extension.yml found in {source_path}")
122
+ manifest = manager.install_from_directory(source_path, speckit_version)
123
+ return f"{manifest.name} v{manifest.version} installed"
124
+
125
+ # --- Bundled extension name or catalog ID ---
126
+ bundled_path = _locate_bundled_extension(ext_spec)
127
+ if bundled_path is not None:
128
+ if manager.registry.is_installed(ext_spec):
129
+ return "already installed"
130
+ manifest = manager.install_from_directory(bundled_path, speckit_version)
131
+ return f"{manifest.name} v{manifest.version} installed"
132
+
133
+ # Fall back to catalog
134
+ catalog = ExtensionCatalog(project_path)
135
+ ext_info, catalog_error = _resolve_catalog_extension(ext_spec, catalog, "add")
136
+ if catalog_error:
137
+ raise ValueError(f"Could not query extension catalog: {catalog_error}")
138
+ if not ext_info:
139
+ raise ValueError(f"Extension '{ext_spec}' not found in bundled extensions or catalog")
140
+
141
+ resolved_id = ext_info["id"]
142
+ if resolved_id != ext_spec:
143
+ bundled_path = _locate_bundled_extension(resolved_id)
144
+ if bundled_path is not None:
145
+ if manager.registry.is_installed(resolved_id):
146
+ return "already installed"
147
+ manifest = manager.install_from_directory(bundled_path, speckit_version)
148
+ return f"{manifest.name} v{manifest.version} installed"
149
+
150
+ if ext_info.get("bundled") and not ext_info.get("download_url"):
151
+ from ..extensions import REINSTALL_COMMAND
152
+
153
+ raise ValueError(
154
+ f"Extension '{resolved_id}' is bundled with spec-kit but not found in the installed package. "
155
+ f"Try reinstalling spec-kit: {REINSTALL_COMMAND}"
156
+ )
157
+
158
+ if not ext_info.get("_install_allowed", True):
159
+ catalog_name = ext_info.get("_catalog_name", "community")
160
+ raise ValueError(
161
+ f"Extension '{ext_spec}' is in the '{catalog_name}' catalog but installation is not allowed from that catalog"
162
+ )
163
+
164
+ zip_path = catalog.download_extension(resolved_id)
165
+ try:
166
+ manifest = manager.install_from_zip(zip_path, speckit_version)
167
+ finally:
168
+ zip_path.unlink(missing_ok=True)
169
+ return f"{manifest.name} v{manifest.version} installed"
170
+
171
+
33
172
  def ensure_constitution_from_template(
34
173
  project_path: Path, tracker: StepTracker | None = None
35
174
  ) -> None:
@@ -142,6 +281,16 @@ def register(app: typer.Typer) -> None:
142
281
  "--integration-options",
143
282
  help='Options for the integration (e.g. --integration-options="--commands-dir .myagent/cmds")',
144
283
  ),
284
+ extensions: list[str] | None = typer.Option(
285
+ None,
286
+ "--extension",
287
+ help="Install an extension during initialization (bundled name, local path, or HTTPS URL). Repeatable.",
288
+ ),
289
+ trust_extension_urls: bool = typer.Option(
290
+ False,
291
+ "--trust-extension-urls",
292
+ help="Pre-authorize installing extensions from external URLs without the interactive trust prompt (required for non-interactive URL installs).",
293
+ ),
145
294
  ):
146
295
  """
147
296
  Initialize a new Specify project.
@@ -174,6 +323,10 @@ def register(app: typer.Typer) -> None:
174
323
  specify init --here --integration gemini
175
324
  specify init my-project --integration generic --integration-options="--commands-dir .myagent/commands/" # Bring your own agent; requires --commands-dir
176
325
  specify init my-project --integration claude --preset healthcare-compliance # With preset
326
+ specify init my-project --integration copilot --extension git # With bundled extension
327
+ specify init my-project --extension git --extension selftest # Multiple extensions
328
+ specify init my-project --extension ./my-extensions/custom-ext # Local path extension
329
+ specify init my-project --extension https://example.com/extensions/my-ext.zip --trust-extension-urls # URL extension (non-interactive)
177
330
  """
178
331
  # Lazy imports to avoid circular dependency — __init__.py imports this module
179
332
  from .. import (
@@ -313,17 +466,18 @@ def register(app: typer.Typer) -> None:
313
466
  raise typer.Exit(1)
314
467
  selected_ai = integration
315
468
  elif not _stdin_is_interactive():
469
+ default_integration = resolve_default_init_integration()
316
470
  console.print(
317
- f"[dim]Non-interactive session detected: defaulting to '{DEFAULT_INIT_INTEGRATION}'. "
471
+ f"[dim]Non-interactive session detected: defaulting to '{default_integration}'. "
318
472
  "Use --integration to choose a different agent.[/dim]"
319
473
  )
320
- selected_ai = DEFAULT_INIT_INTEGRATION
474
+ selected_ai = default_integration
321
475
  else:
322
476
  ai_choices = {key: config["name"] for key, config in AGENT_CONFIG.items()}
323
477
  selected_ai = select_with_arrows(
324
478
  ai_choices,
325
479
  "Choose your coding agent integration:",
326
- DEFAULT_INIT_INTEGRATION,
480
+ resolve_default_init_integration(),
327
481
  )
328
482
 
329
483
  if not integration:
@@ -413,10 +567,31 @@ def register(app: typer.Typer) -> None:
413
567
  ("chmod", "Ensure scripts executable"),
414
568
  ("constitution", "Constitution setup"),
415
569
  ("workflow", "Install bundled workflow"),
416
- ("final", "Finalize"),
417
570
  ]:
418
571
  tracker.add(key, label)
419
572
 
573
+ if extensions:
574
+ from rich.markup import escape as _escape_markup
575
+
576
+ for i, ext_spec in enumerate(extensions):
577
+ tracker.add(
578
+ f"extension-{i}", f"Install extension: {_escape_markup(ext_spec)}"
579
+ )
580
+
581
+ tracker.add("final", "Finalize")
582
+
583
+ # Resolve trust for URL-based extensions BEFORE entering the Live
584
+ # display: the confirmation prompt cannot be shown/answered underneath
585
+ # the Rich Live spinner. URL installs are default-deny unless the user
586
+ # confirms interactively or passes --trust-extension-urls.
587
+ extension_url_approvals: dict[str, bool] = {}
588
+ if extensions:
589
+ url_specs = [e for e in extensions if _ext_spec_is_url(e)]
590
+ if url_specs:
591
+ extension_url_approvals = _confirm_extension_url_trust(
592
+ url_specs, trust_override=trust_extension_urls
593
+ )
594
+
420
595
  # Disable transient mode on Windows: PowerShell 5.1's legacy console
421
596
  # hangs when Rich tries to restore cursor state via VT escape sequences.
422
597
  _transient = sys.platform != "win32"
@@ -626,6 +801,46 @@ def register(app: typer.Typer) -> None:
626
801
  continuing="Continuing without the optional preset.",
627
802
  )
628
803
 
804
+ # Install extensions specified via --extension
805
+ if extensions:
806
+ from rich.markup import escape as _escape_markup
807
+
808
+ from ..extensions._commands import _refresh_events_and_warn
809
+
810
+ speckit_ver = get_speckit_version()
811
+ any_extension_installed = False
812
+ for i, ext_spec in enumerate(extensions):
813
+ tracker.start(f"extension-{i}")
814
+ # Skip URL extensions the user did not confirm as trusted
815
+ # (default-deny; resolved before the Live display).
816
+ if _ext_spec_is_url(ext_spec) and not extension_url_approvals.get(
817
+ ext_spec, False
818
+ ):
819
+ tracker.error(
820
+ f"extension-{i}",
821
+ "skipped: untrusted URL not confirmed "
822
+ "(use --trust-extension-urls)",
823
+ )
824
+ continue
825
+ try:
826
+ status_msg = _install_extension_during_init(
827
+ project_path, ext_spec, speckit_ver
828
+ )
829
+ tracker.complete(f"extension-{i}", status_msg)
830
+ any_extension_installed = True
831
+ except Exception as ext_err:
832
+ sanitized_ext = str(ext_err).replace("\n", " ").strip()
833
+ tracker.error(
834
+ f"extension-{i}",
835
+ f"failed: {_escape_markup(sanitized_ext[:120])}",
836
+ )
837
+
838
+ # Refresh native event configuration once after the batch so
839
+ # that an extension declaring ``events:`` has its hooks
840
+ # activated, mirroring the ``extension add`` path.
841
+ if any_extension_installed:
842
+ _refresh_events_and_warn(project_path)
843
+
629
844
  # Seed the constitution AFTER preset installation so that a
630
845
  # preset-provided constitution-template (resolved via the
631
846
  # priority stack) wins over the core template.
@@ -895,7 +895,7 @@ def collect_extension_events(project_root: Path) -> ResolvedEvents:
895
895
  continue
896
896
  try:
897
897
  data = yaml.safe_load(ext_yml.read_text(encoding="utf-8")) or {}
898
- except yaml.YAMLError:
898
+ except (UnicodeDecodeError, yaml.YAMLError):
899
899
  continue
900
900
  if not isinstance(data, dict):
901
901
  continue