specify-cli 0.12.8__tar.gz → 0.12.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/lint.yml +1 -1
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/publish-pypi.yml +2 -2
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/test.yml +2 -2
- {specify_cli-0.12.8 → specify_cli-0.12.10}/CHANGELOG.md +30 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/PKG-INFO +1 -1
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/extensions.md +1 -1
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/friends.md +2 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/commands/speckit.agent-context.update.md +2 -2
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/scripts/bash/update-agent-context.sh +6 -6
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +2 -4
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/catalog.community.json +9 -6
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/powershell/create-new-feature-branch.ps1 +8 -2
- {specify_cli-0.12.8 → specify_cli-0.12.10}/pyproject.toml +1 -1
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/bash/common.sh +66 -11
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/__init__.py +3 -2
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/agents.py +6 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/primitives.py +49 -6
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/base.py +55 -15
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/hermes/__init__.py +9 -11
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/shared_infra.py +10 -3
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/expressions.py +91 -57
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/shell/__init__.py +22 -2
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/analyze.md +1 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/checklist.md +1 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/clarify.md +1 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/converge.md +1 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/implement.md +1 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/plan.md +1 -2
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/taskstoissues.md +1 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/git/test_git_extension.py +32 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/test_extension_agent_context.py +56 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/conftest.py +24 -4
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_base.py +72 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_cli.py +41 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_home_isolation.py +4 -0
- specify_cli-0.12.10/tests/integrations/test_integration_goose.py +85 -0
- specify_cli-0.12.10/tests/integrations/test_skill_frontmatter_quoting.py +111 -0
- specify_cli-0.12.10/tests/test_command_template_py_scripts.py +107 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_setup_tasks.py +62 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_workflows.py +167 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_primitives.py +84 -0
- specify_cli-0.12.8/tests/integrations/test_integration_goose.py +0 -38
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.devcontainer/devcontainer.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.devcontainer/post-create.sh +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.editorconfig +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.gitattributes +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/CODEOWNERS +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/agent_request.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/bundle_submission.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/extension_submission.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/ISSUE_TEMPLATE/preset_submission.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/aw/actions-lock.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/dependabot.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/skills/add-community-extension/SKILL.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/RELEASE-PROCESS.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/add-community-extension.lock.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/add-community-extension.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/add-community-preset.lock.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/add-community-preset.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-assess.lock.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-assess.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-fix.lock.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-fix.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-test.lock.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/bug-test.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/catalog-assign.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/codeql.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/docs.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/release-trigger.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/release.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.github/workflows/stale.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.gitignore +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.markdownlint-cli2.jsonc +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/.zenodo.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/AGENTS.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/CITATION.cff +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/CODE_OF_CONDUCT.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/CONTRIBUTING.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/DEVELOPMENT.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/LICENSE +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/SECURITY.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/SUPPORT.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/.gitignore +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/bundles.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/overview.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/presets.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/community/walkthroughs.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/concepts/complex-features.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/concepts/sdd.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/concepts/spec-persistence.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/docfx.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/guides/evolving-specs.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/guides/monorepo.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/index.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/install/air-gapped.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/install/one-time.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/install/pipx.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/install/uv.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/installation.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/local-development.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/quickstart.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/authentication.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/bundles.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/core.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/extensions.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/integrations.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/overview.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/presets.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/reference/workflows.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/template/public/main.css +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/toc.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/docs/upgrade.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/business-analyst/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/business-analyst/bundle.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/developer/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/developer/bundle.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/product-manager/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/product-manager/bundle.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/security-researcher/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/examples/bundles/security-researcher/bundle.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/EXTENSION-API-REFERENCE.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/EXTENSION-DEVELOPMENT-GUIDE.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/EXTENSION-PUBLISHING-GUIDE.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/EXTENSION-USER-GUIDE.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/RFC-EXTENSION-SYSTEM.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/agent-context-config.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/agent-context-defaults.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/extension.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/agent-context/scripts/python/update_agent_context.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/bug/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/bug/commands/speckit.bug.assess.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/bug/commands/speckit.bug.fix.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/bug/commands/speckit.bug.test.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/bug/extension.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/catalog.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.commit.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.feature.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.initialize.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.remote.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/commands/speckit.git.validate.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/config-template.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/extension.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/git-config.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/bash/auto-commit.sh +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/bash/create-new-feature-branch.sh +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/bash/git-common.sh +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/bash/initialize-repo.sh +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/powershell/git-common.ps1 +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/selftest/commands/selftest.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/selftest/extension.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/.gitignore +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/CHANGELOG.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/EXAMPLE-README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/LICENSE +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/commands/example.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/config-template.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/extensions/template/extension.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/integrations/CONTRIBUTING.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/integrations/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/integrations/catalog.community.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/integrations/catalog.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/media/bootstrap-claude-code.gif +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/media/logo_large.webp +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/media/logo_small.webp +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/media/spec-kit-video-header.jpg +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/media/specify_cli.gif +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/newsletters/2026-April.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/newsletters/2026-February.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/newsletters/2026-June.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/newsletters/2026-March.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/newsletters/2026-May.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/ARCHITECTURE.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/PUBLISHING.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/catalog.community.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/catalog.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/commands/speckit.constitution.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/commands/speckit.implement.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/commands/speckit.plan.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/commands/speckit.specify.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/commands/speckit.tasks.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/lean/preset.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/commands/speckit.myext.myextcmd.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/commands/speckit.specify.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/preset.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/templates/myext-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/scaffold/templates/spec-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/commands/speckit.specify.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/commands/speckit.wrap-test.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/preset.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/agent-file-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/checklist-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/constitution-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/plan-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/spec-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/presets/self-test/templates/tasks-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/bash/check-prerequisites.sh +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/bash/create-new-feature.sh +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/bash/setup-plan.sh +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/bash/setup-tasks.sh +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/powershell/check-prerequisites.ps1 +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/powershell/common.ps1 +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/powershell/create-new-feature.ps1 +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/powershell/setup-plan.ps1 +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/powershell/setup-tasks.ps1 +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/python/check_prerequisites.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/scripts/python/common.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/spec-driven.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/spec-kit.code-workspace +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_agent_config.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_assets.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_console.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_github_http.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_init_options.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_invocation_style.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_project.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_toml_string.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_utils.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/_version.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/azure_devops.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/base.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/config.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/github.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/authentication/http.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/commands_impl/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/commands_impl/catalog_config.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/project.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/versioning.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/lib/yamlio.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/models/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/models/catalog.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/models/manifest.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/models/records.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/adapters.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/catalog_stack.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/conflict.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/installer.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/packager.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/references.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/resolver.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/bundler/services/validator.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/catalogs.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/commands/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/commands/bundle/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/commands/init.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/extensions/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/extensions/_commands.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integration_runtime.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integration_scaffold.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integration_state.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integration_status.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_commands.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_helpers.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_install_commands.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_migrate_commands.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_query_commands.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/_scaffold_commands.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/agy/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/amp/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/auggie/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/bob/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/catalog.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/claude/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/cline/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/codebuddy/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/codex/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/copilot/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/cursor_agent/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/devin/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/firebender/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/forge/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/gemini/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/generic/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/goose/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/junie/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/kilocode/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/kimi/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/kiro_cli/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/lingma/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/manifest.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/omp/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/opencode/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/pi/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/qodercli/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/qwen/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/rovodev/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/shai/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/tabnine/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/trae/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/vibe/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/zcode/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/integrations/zed/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/presets/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/presets/_commands.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/_commands.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/base.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/catalog.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/engine.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/command/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/do_while/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/fan_in/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/fan_out/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/gate/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/if_then/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/init/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/prompt/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/switch/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/src/specify_cli/workflows/steps/while_loop/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/checklist-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/constitution.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/specify.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/commands/tasks.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/constitution-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/plan-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/spec-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/tasks-template.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/templates/vscode-settings.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/auth_helpers.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/bundler_helpers.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/conftest.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/contract/test_bundle_cli.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/contract/test_catalog_schema.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/contract/test_manifest_schema.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/bug/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/bug/test_bug_extension.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/git/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/test_agent_context_cli_free.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/test_update_agent_context_feature_json.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/extensions/test_update_agent_context_python_parity.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/hooks/TESTING.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/hooks/plan.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/hooks/spec.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/hooks/tasks.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/http_helpers.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_catalog_stack.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_init_install.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_install_flow.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_local_install.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_offline.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integration/test_bundler_security_paths.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/__init__.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_extra_args.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_agy.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_amp.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_auggie.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_base_markdown.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_base_skills.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_base_toml.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_base_yaml.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_bob.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_catalog.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_claude.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_cline.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_codebuddy.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_codex.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_copilot.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_cursor_agent.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_devin.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_firebender.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_forge.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_gemini.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_generic.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_hermes.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_junie.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_kilocode.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_kimi.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_kiro_cli.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_lingma.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_omp.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_opencode.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_pi.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_qodercli.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_qwen.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_rovodev.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_scaffold.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_shai.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_state.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_subcommand.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_tabnine.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_trae.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_vibe.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_zcode.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_integration_zed.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_manifest.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/integrations/test_registry.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/self_upgrade_helpers.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_agent_config_consistency.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_authentication.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_branch_numbering.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_check_prerequisites_paths_only.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_check_prerequisites_python_parity.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_check_tool.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_cli_version.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_commands_package.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_console_imports.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_extension_registration.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_extension_skills.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_extension_update_hardening.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_extensions.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_github_http.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_github_workflows.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_init_dir.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_init_dir_cli.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_live_transient_windows.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_merge.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_post_process.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_presets.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_ps1_encoding.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_registrar_path_traversal.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_self_upgrade_detection.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_self_upgrade_execution.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_self_upgrade_guidance.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_self_upgrade_verification.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_setup_plan_feature_json.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_setup_plan_no_overwrite.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_shared_infra_integrity.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_timestamp_branches.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_upgrade.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_utils.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_utils_assets_imports.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_version_imports.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/test_workflow_run_without_project.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_adapters.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_catalog_config.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_conflict.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_packager.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_records.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_references.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_resolver.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_validator.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/tests/unit/test_bundler_versioning.py +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/ARCHITECTURE.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/PUBLISHING.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/README.md +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/catalog.community.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/catalog.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/speckit/workflow.yml +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/step-catalog.community.json +0 -0
- {specify_cli-0.12.8 → specify_cli-0.12.10}/workflows/step-catalog.json +0 -0
|
@@ -37,7 +37,7 @@ jobs:
|
|
|
37
37
|
fi
|
|
38
38
|
|
|
39
39
|
- name: Run markdownlint-cli2
|
|
40
|
-
uses: DavidAnson/markdownlint-cli2-action@
|
|
40
|
+
uses: DavidAnson/markdownlint-cli2-action@8de2aa07cae85fd17c0b35642db70cf5495f1d25 # v24.0.0
|
|
41
41
|
with:
|
|
42
42
|
globs: |
|
|
43
43
|
'**/*.md'
|
|
@@ -32,7 +32,7 @@ jobs:
|
|
|
32
32
|
ref: refs/tags/${{ inputs.tag }}
|
|
33
33
|
|
|
34
34
|
- name: Install uv
|
|
35
|
-
uses: astral-sh/setup-uv@
|
|
35
|
+
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
|
|
36
36
|
|
|
37
37
|
- name: Set up Python
|
|
38
38
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
@@ -74,7 +74,7 @@ jobs:
|
|
|
74
74
|
path: dist/
|
|
75
75
|
|
|
76
76
|
- name: Install uv
|
|
77
|
-
uses: astral-sh/setup-uv@
|
|
77
|
+
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
|
|
78
78
|
|
|
79
79
|
- name: Publish to PyPI
|
|
80
80
|
run: uv publish
|
|
@@ -16,7 +16,7 @@ jobs:
|
|
|
16
16
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
17
17
|
|
|
18
18
|
- name: Install uv
|
|
19
|
-
uses: astral-sh/setup-uv@
|
|
19
|
+
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
|
|
20
20
|
|
|
21
21
|
- name: Set up Python
|
|
22
22
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
@@ -37,7 +37,7 @@ jobs:
|
|
|
37
37
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
38
38
|
|
|
39
39
|
- name: Install uv
|
|
40
|
-
uses: astral-sh/setup-uv@
|
|
40
|
+
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
|
|
41
41
|
|
|
42
42
|
- name: Set up Python ${{ matrix.python-version }}
|
|
43
43
|
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- insert new changelog below this comment -->
|
|
4
4
|
|
|
5
|
+
## [0.12.10] - 2026-07-10
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- chore(deps): bump astral-sh/setup-uv from 8.2.0 to 8.3.2 (#3439)
|
|
10
|
+
- chore(deps): bump DavidAnson/markdownlint-cli2-action (#3438)
|
|
11
|
+
- fix(templates): correct phase numbering in plan.md (#3416)
|
|
12
|
+
- fix(git-ext): honor explicit -Number 0 in PowerShell branch creation (#3412)
|
|
13
|
+
- docs: add 'spectatui' entry to friends.md (#3362)
|
|
14
|
+
- test: pin interpreter probe so py-template render test passes on Windows (#3428)
|
|
15
|
+
- feat(workflows): make shell step timeout configurable (#3404)
|
|
16
|
+
- fix: find plans in nested spec directories (#3405)
|
|
17
|
+
- feat(templates): add py: lines to command templates' scripts frontmatter (#3403)
|
|
18
|
+
- chore: release 0.12.9, begin 0.12.10.dev0 development (#3426)
|
|
19
|
+
|
|
20
|
+
## [0.12.9] - 2026-07-09
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- fix(integrations): skip Windows Store python3 alias stub in resolve_python_interpreter (#3385)
|
|
25
|
+
- fix(integrations): escape control characters in SKILL.md frontmatter (#3399)
|
|
26
|
+
- fix(workflows): apply chained expression filters left-to-right (#3339)
|
|
27
|
+
- fix(scripts): resolve invoke_separator by parse success, not python3 availability (#3304) (#3320)
|
|
28
|
+
- fix(shared-infra): refresh_shared_templates preserves recovered user files (#3378)
|
|
29
|
+
- fix(agents): resolve skill placeholders in Goose (yaml) command output (#3374)
|
|
30
|
+
- fix(bundler): enforce version pin on bundled preset/extension installs (#3377)
|
|
31
|
+
- Update Golden Demo extension to v0.3.0 (#3394)
|
|
32
|
+
- test: isolate integration test home (#3144)
|
|
33
|
+
- chore: release 0.12.8, begin 0.12.9.dev0 development (#3410)
|
|
34
|
+
|
|
5
35
|
## [0.12.8] - 2026-07-08
|
|
6
36
|
|
|
7
37
|
### Changed
|
|
@@ -58,7 +58,7 @@ The following community-contributed extensions are available in [`catalog.commun
|
|
|
58
58
|
| Fleet Orchestrator | Orchestrate a full feature lifecycle with human-in-the-loop gates across all SpecKit phases | `process` | Read+Write | [spec-kit-fleet](https://github.com/sharathsatish/spec-kit-fleet) |
|
|
59
59
|
| GitHub Issues Integration 1 | Generate spec artifacts from GitHub Issues - import issues, sync updates, and maintain bidirectional traceability | `integration` | Read+Write | [spec-kit-github-issues](https://github.com/Fatima367/spec-kit-github-issues) |
|
|
60
60
|
| GitHub Issues Integration 2 | Creates and syncs local specs from an existing GitHub issue | `integration` | Read+Write | [spec-kit-issue](https://github.com/aaronrsun/spec-kit-issue) |
|
|
61
|
-
| Golden Demo | Extracts acceptance criteria
|
|
61
|
+
| Golden Demo | Deterministic behavioral drift oracle. Extracts acceptance criteria, generates fuzz test vectors (seed=42), compares golden Python implementations against real code in any language. CI/CD gatekeeper with warn/strict modes. | `docs` | Read+Write | [spec-kit-golden-demo](https://github.com/jasstt/spec-kit-golden-demo) |
|
|
62
62
|
| Improve Extension | Audits any codebase as a senior advisor and writes prioritized, self-contained spec prompts under specs/ that the spec-kit lifecycle can process | `process` | Read+Write | [spec-kit-improve](https://github.com/d0whc3r/spec-kit-improve) |
|
|
63
63
|
| Intake | Normalize PRD, design, HTML SSOT, and test-case evidence into SDD-ready intake artifacts. | `docs` | Read+Write | [spec-kit-intake](https://github.com/bigsmartben/spec-kit-intake) |
|
|
64
64
|
| Intelligent Agent Orchestrator | Cross-catalog agent discovery and intelligent prompt-to-command routing | `process` | Read+Write | [spec-kit-orchestrator](https://github.com/pragya247/spec-kit-orchestrator) |
|
|
@@ -14,3 +14,5 @@ Community projects that extend, visualize, or build on Spec Kit:
|
|
|
14
14
|
- **[SpecKit Companion](https://marketplace.visualstudio.com/items?itemName=alfredoperez.speckit-companion)** — A VS Code extension that brings a visual GUI to Spec Kit. Browse specs in a rich markdown viewer with clickable file references, create specifications with image attachments, comment and refine each step inline (GitHub-style review), track your progress through the SDD workflow with a visual phase stepper, and manage steering documents like constitutions and templates.
|
|
15
15
|
|
|
16
16
|
- **[cc-spec-kit](https://github.com/speckit-community/cc-spec-kit)** — Community-maintained plugin for Claude Code and GitHub Copilot CLI that installs Spec Kit skills via the plugin marketplace.
|
|
17
|
+
|
|
18
|
+
- **[spectatui](https://github.com/tinesoft/spectatui)** — A terminal UI (TUI) dashboard for Spec Kit that lets you track features, manage specifications, integrations, presets, workflows, and extensions, and monitor AI agent workflows. Attach to existing AI sessions or launch new ones from your terminal. Keyboard and mouse support. Light/dark theme support. Customizable and performance-oriented. Requires the `specify` CLI in your PATH.
|
|
@@ -15,7 +15,7 @@ The script reads the agent-context extension config at
|
|
|
15
15
|
- `context_files` — optional project-relative paths for multiple coding agent context files. When non-empty, the script updates each listed file and the list takes precedence over `context_file`.
|
|
16
16
|
- `context_markers.start` / `.end` — the delimiters surrounding the managed section. Defaults to `<!-- SPECKIT START -->` and `<!-- SPECKIT END -->` when the field is missing.
|
|
17
17
|
|
|
18
|
-
It then creates, replaces, or appends the managed block so that the section points at the most recent plan path when one can be discovered (`specs
|
|
18
|
+
It then creates, replaces, or appends the managed block so that the section points at the most recent plan path when one can be discovered (`specs/**/plan.md`, any depth).
|
|
19
19
|
|
|
20
20
|
If `context_files` and `context_file` are empty, the command reports nothing to do and exits successfully. Context file paths must stay project-relative; absolute paths, Windows drive paths, backslash separators, and `..` path segments are rejected.
|
|
21
21
|
|
|
@@ -24,4 +24,4 @@ If `context_files` and `context_file` are empty, the command reports nothing to
|
|
|
24
24
|
- **Bash**: `.specify/extensions/agent-context/scripts/bash/update-agent-context.sh [plan_path]`
|
|
25
25
|
- **PowerShell**: `.specify/extensions/agent-context/scripts/powershell/update-agent-context.ps1 [plan_path]`
|
|
26
26
|
|
|
27
|
-
When `plan_path` is omitted, the script auto-detects the most recently modified `specs
|
|
27
|
+
When `plan_path` is omitted, the script auto-detects the most recently modified `specs/**/plan.md` (any depth, so scoped layouts like `specs/<scope>/<feature>/plan.md` are found).
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
#
|
|
13
13
|
# When `plan_path` is omitted, the script derives it from `.specify/feature.json`
|
|
14
14
|
# (written by /speckit-specify). Falls back to the most recently modified
|
|
15
|
-
# `specs
|
|
15
|
+
# `specs/**/plan.md` only when feature.json is absent or its plan does not exist yet.
|
|
16
16
|
|
|
17
17
|
set -euo pipefail
|
|
18
18
|
|
|
@@ -307,14 +307,14 @@ import sys
|
|
|
307
307
|
from pathlib import Path
|
|
308
308
|
root = Path(sys.argv[1]).resolve()
|
|
309
309
|
specs = root / "specs"
|
|
310
|
-
|
|
311
|
-
specs.glob("
|
|
310
|
+
plan = max(
|
|
311
|
+
specs.glob("**/plan.md"),
|
|
312
312
|
key=lambda p: p.stat().st_mtime,
|
|
313
|
-
|
|
313
|
+
default=None,
|
|
314
314
|
)
|
|
315
|
-
if
|
|
315
|
+
if plan:
|
|
316
316
|
try:
|
|
317
|
-
print(
|
|
317
|
+
print(plan.relative_to(root).as_posix())
|
|
318
318
|
except ValueError:
|
|
319
319
|
print("")
|
|
320
320
|
else:
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
#
|
|
13
13
|
# When `plan_path` is omitted, the script derives it from `.specify/feature.json`
|
|
14
14
|
# (written by /speckit-specify). Falls back to the most recently modified
|
|
15
|
-
# `specs
|
|
15
|
+
# `specs/**/plan.md` only when feature.json is absent or its plan does not exist yet.
|
|
16
16
|
|
|
17
17
|
[CmdletBinding()]
|
|
18
18
|
param(
|
|
@@ -426,9 +426,7 @@ if (-not $PlanPath) {
|
|
|
426
426
|
if (-not $PlanPath) {
|
|
427
427
|
try {
|
|
428
428
|
$specsDir = Join-Path $ProjectRoot 'specs'
|
|
429
|
-
$candidate = Get-ChildItem -Path $specsDir -
|
|
430
|
-
ForEach-Object { Get-Item -LiteralPath (Join-Path $_.FullName 'plan.md') -ErrorAction SilentlyContinue } |
|
|
431
|
-
Where-Object { $_ } |
|
|
429
|
+
$candidate = Get-ChildItem -Path $specsDir -Recurse -File -Filter 'plan.md' -ErrorAction SilentlyContinue |
|
|
432
430
|
Sort-Object LastWriteTime -Descending |
|
|
433
431
|
Select-Object -First 1
|
|
434
432
|
if ($candidate) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": "1.0",
|
|
3
|
-
"updated_at": "2026-07-
|
|
3
|
+
"updated_at": "2026-07-07T00:00:00Z",
|
|
4
4
|
"catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.community.json",
|
|
5
5
|
"extensions": {
|
|
6
6
|
"aide": {
|
|
@@ -1398,10 +1398,10 @@
|
|
|
1398
1398
|
"golden-demo": {
|
|
1399
1399
|
"name": "Golden Demo",
|
|
1400
1400
|
"id": "golden-demo",
|
|
1401
|
-
"description": "Extracts acceptance criteria
|
|
1401
|
+
"description": "Deterministic behavioral drift oracle. Extracts acceptance criteria, generates fuzz test vectors (seed=42), compares golden Python implementations against real code in any language. CI/CD gatekeeper with warn/strict modes.",
|
|
1402
1402
|
"author": "jasstt",
|
|
1403
|
-
"version": "0.
|
|
1404
|
-
"download_url": "https://github.com/jasstt/spec-kit-golden-demo/archive/refs/tags/v0.
|
|
1403
|
+
"version": "0.3.0",
|
|
1404
|
+
"download_url": "https://github.com/jasstt/spec-kit-golden-demo/archive/refs/tags/v0.3.0.zip",
|
|
1405
1405
|
"repository": "https://github.com/jasstt/spec-kit-golden-demo",
|
|
1406
1406
|
"homepage": "https://github.com/jasstt/spec-kit-golden-demo",
|
|
1407
1407
|
"documentation": "https://github.com/jasstt/spec-kit-golden-demo",
|
|
@@ -1412,13 +1412,16 @@
|
|
|
1412
1412
|
"speckit_version": ">=0.1.0"
|
|
1413
1413
|
},
|
|
1414
1414
|
"provides": {
|
|
1415
|
-
"commands":
|
|
1415
|
+
"commands": 3,
|
|
1416
1416
|
"hooks": 2
|
|
1417
1417
|
},
|
|
1418
1418
|
"tags": [
|
|
1419
1419
|
"testing",
|
|
1420
1420
|
"drift-detection",
|
|
1421
1421
|
"behavioral-oracle",
|
|
1422
|
+
"fuzzing",
|
|
1423
|
+
"ci-cd",
|
|
1424
|
+
"cross-language",
|
|
1422
1425
|
"tdd",
|
|
1423
1426
|
"quality"
|
|
1424
1427
|
],
|
|
@@ -1426,7 +1429,7 @@
|
|
|
1426
1429
|
"downloads": 0,
|
|
1427
1430
|
"stars": 0,
|
|
1428
1431
|
"created_at": "2026-06-24T00:00:00Z",
|
|
1429
|
-
"updated_at": "2026-
|
|
1432
|
+
"updated_at": "2026-07-07T00:00:00Z"
|
|
1430
1433
|
},
|
|
1431
1434
|
"harness": {
|
|
1432
1435
|
"name": "Research Harness",
|
|
@@ -446,7 +446,10 @@ if ($env:GIT_BRANCH_NAME) {
|
|
|
446
446
|
$branchSuffix = Get-BranchName -Description $featureDesc
|
|
447
447
|
}
|
|
448
448
|
|
|
449
|
-
if
|
|
449
|
+
# Warn if -Number and -Timestamp are both specified. Use ContainsKey (not
|
|
450
|
+
# `-ne 0`) so an explicit `-Number 0` is also detected, matching the bash twin's
|
|
451
|
+
# `[ -n "$BRANCH_NUMBER" ]` check.
|
|
452
|
+
if ($Timestamp -and $PSBoundParameters.ContainsKey('Number')) {
|
|
450
453
|
Write-Warning "[specify] Warning: -Number is ignored when -Timestamp is used"
|
|
451
454
|
$Number = 0
|
|
452
455
|
}
|
|
@@ -456,7 +459,10 @@ if ($env:GIT_BRANCH_NAME) {
|
|
|
456
459
|
$branchName = New-BranchName -FeatureNum $featureNum -BranchSuffix $branchSuffix
|
|
457
460
|
} else {
|
|
458
461
|
$branchScopePrefix = Get-BranchScopePrefix -Template $branchTemplate -BranchSuffix $branchSuffix
|
|
459
|
-
|
|
462
|
+
# Auto-detect the next number only when -Number was not supplied; an
|
|
463
|
+
# explicit value (including 0) is honored, matching the bash twin's
|
|
464
|
+
# `[ -z "$BRANCH_NUMBER" ]` check.
|
|
465
|
+
if (-not $PSBoundParameters.ContainsKey('Number')) {
|
|
460
466
|
if ($DryRun -and $hasGit) {
|
|
461
467
|
$Number = Get-NextBranchNumber -SpecsDir $specsDir -SkipFetch -ScopePrefix $branchScopePrefix
|
|
462
468
|
} elseif ($DryRun) {
|
|
@@ -244,21 +244,29 @@ get_invoke_separator() {
|
|
|
244
244
|
|
|
245
245
|
local integration_json="$repo_root/.specify/integration.json"
|
|
246
246
|
local separator="."
|
|
247
|
-
local
|
|
247
|
+
local parsed=0
|
|
248
248
|
|
|
249
249
|
if [[ -f "$integration_json" ]]; then
|
|
250
|
+
# Try parsers in order (jq -> python3 -> awk), falling through on
|
|
251
|
+
# failure. Selection is by *parse success*, not mere availability: on
|
|
252
|
+
# Windows `python3` commonly resolves to the Microsoft Store App
|
|
253
|
+
# Execution Alias stub, which passes `command -v` but fails at runtime
|
|
254
|
+
# (exit 49). An availability-gated branch would pick python3, swallow
|
|
255
|
+
# its failure, and — because this function historically had no text
|
|
256
|
+
# fallback — silently return "." even for `-`-separator integrations
|
|
257
|
+
# (e.g. forge, cline), yielding wrong command hints (issue #3304).
|
|
250
258
|
if command -v jq >/dev/null 2>&1; then
|
|
251
259
|
local jq_separator
|
|
252
260
|
if jq_separator=$(jq -r '(.default_integration // .integration // "") as $k | if $k == "" then "." else (.integration_settings[$k].invoke_separator // ".") end' "$integration_json" 2>/dev/null); then
|
|
253
|
-
parsed_with_jq=1
|
|
254
261
|
case "$jq_separator" in
|
|
255
|
-
"."|"-") separator="$jq_separator" ;;
|
|
262
|
+
"."|"-") separator="$jq_separator"; parsed=1 ;;
|
|
256
263
|
esac
|
|
257
264
|
fi
|
|
258
265
|
fi
|
|
259
266
|
|
|
260
|
-
if [[ "$
|
|
261
|
-
|
|
267
|
+
if [[ "$parsed" -eq 0 ]] && command -v python3 >/dev/null 2>&1; then
|
|
268
|
+
local py_separator
|
|
269
|
+
if py_separator=$(python3 - "$integration_json" <<'PY' 2>/dev/null
|
|
262
270
|
import json
|
|
263
271
|
import sys
|
|
264
272
|
|
|
@@ -274,17 +282,64 @@ try:
|
|
|
274
282
|
separator = entry["invoke_separator"]
|
|
275
283
|
print(separator)
|
|
276
284
|
except Exception:
|
|
277
|
-
|
|
285
|
+
sys.exit(1)
|
|
278
286
|
PY
|
|
279
287
|
); then
|
|
280
|
-
case "$
|
|
281
|
-
"."|"-") ;;
|
|
282
|
-
*) separator="." ;;
|
|
288
|
+
case "$py_separator" in
|
|
289
|
+
"."|"-") separator="$py_separator"; parsed=1 ;;
|
|
283
290
|
esac
|
|
284
|
-
else
|
|
285
|
-
separator="."
|
|
286
291
|
fi
|
|
287
292
|
fi
|
|
293
|
+
|
|
294
|
+
if [[ "$parsed" -eq 0 ]]; then
|
|
295
|
+
# Last-resort text fallback for environments with neither jq nor a
|
|
296
|
+
# working python3 (e.g. stock Windows + Git Bash). Reads the active
|
|
297
|
+
# integration key (default_integration, else integration) and its
|
|
298
|
+
# invoke_separator from within the integration_settings object.
|
|
299
|
+
# Handles both pretty-printed (the written form) and compact JSON.
|
|
300
|
+
# Accumulate all lines into one buffer in END rather than using
|
|
301
|
+
# gawk-only whole-file slurp (RS="^$"), so this stays portable to
|
|
302
|
+
# the BSD awk on macOS.
|
|
303
|
+
local awk_separator
|
|
304
|
+
awk_separator=$(awk '
|
|
305
|
+
function keyval(d, name, v) {
|
|
306
|
+
if (match(d, "\"" name "\"[ \t\r\n]*:[ \t\r\n]*\"[^\"]*\"")) {
|
|
307
|
+
v=substr(d,RSTART,RLENGTH); sub(/^.*:[ \t\r\n]*"/,"",v); sub(/"$/,"",v); return v
|
|
308
|
+
}
|
|
309
|
+
return ""
|
|
310
|
+
}
|
|
311
|
+
{ doc = doc $0 "\n" }
|
|
312
|
+
END {
|
|
313
|
+
key=keyval(doc,"default_integration"); if (key=="") key=keyval(doc,"integration")
|
|
314
|
+
sep="."
|
|
315
|
+
if (key!="") {
|
|
316
|
+
settings=doc
|
|
317
|
+
if (match(doc, /"integration_settings"[ \t\r\n]*:[ \t\r\n]*[{]/)) {
|
|
318
|
+
settings=substr(doc, RSTART+RLENGTH-1)
|
|
319
|
+
}
|
|
320
|
+
if (match(settings, "\"" key "\"[ \t\r\n]*:[ \t\r\n]*[{]")) {
|
|
321
|
+
start=RSTART+RLENGTH-1
|
|
322
|
+
depth=0
|
|
323
|
+
obj=""
|
|
324
|
+
for (i=start; i<=length(settings); i++) {
|
|
325
|
+
c=substr(settings,i,1)
|
|
326
|
+
obj=obj c
|
|
327
|
+
if (c=="{") depth++
|
|
328
|
+
else if (c=="}") { depth--; if (depth==0) break }
|
|
329
|
+
}
|
|
330
|
+
if (match(obj, /"invoke_separator"[ \t\r\n]*:[ \t\r\n]*"[-.]"/)) {
|
|
331
|
+
tok=substr(obj,RSTART,RLENGTH); s=substr(tok,length(tok)-1,1)
|
|
332
|
+
if (s=="." || s=="-") sep=s
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
print sep
|
|
337
|
+
}
|
|
338
|
+
' "$integration_json" 2>/dev/null)
|
|
339
|
+
case "$awk_separator" in
|
|
340
|
+
"."|"-") separator="$awk_separator" ;;
|
|
341
|
+
esac
|
|
342
|
+
fi
|
|
288
343
|
fi
|
|
289
344
|
|
|
290
345
|
_SPECIFY_INVOKE_SEPARATOR_CACHE_REPO_ROOT="$repo_root"
|
|
@@ -141,8 +141,9 @@ def _install_shared_infra(
|
|
|
141
141
|
|
|
142
142
|
Copies ``.specify/scripts/<variant>/`` and ``.specify/templates/`` from
|
|
143
143
|
the bundled core_pack or source checkout, where ``<variant>`` is
|
|
144
|
-
``bash`` when *script_type* is ``"sh"
|
|
145
|
-
``"ps"``. Tracks all installed files in
|
|
144
|
+
``bash`` when *script_type* is ``"sh"``, ``python`` when it is ``"py"``,
|
|
145
|
+
and ``powershell`` when it is ``"ps"``. Tracks all installed files in
|
|
146
|
+
``speckit.manifest.json``.
|
|
146
147
|
|
|
147
148
|
Shared scripts and page templates are processed to resolve
|
|
148
149
|
``__SPECKIT_COMMAND_<NAME>__`` placeholders using *invoke_separator*
|
|
@@ -701,6 +701,12 @@ class CommandRegistrar:
|
|
|
701
701
|
)
|
|
702
702
|
output = self.render_toml_command(frontmatter, body, source_id)
|
|
703
703
|
elif agent_config["format"] == "yaml":
|
|
704
|
+
body = self.resolve_skill_placeholders(
|
|
705
|
+
agent_name, frontmatter, body, project_root
|
|
706
|
+
)
|
|
707
|
+
body = self._convert_argument_placeholder(
|
|
708
|
+
body, "$ARGUMENTS", agent_config["args"]
|
|
709
|
+
)
|
|
704
710
|
output = self.render_yaml_command(
|
|
705
711
|
frontmatter, body, source_id, cmd_name
|
|
706
712
|
)
|
|
@@ -33,12 +33,13 @@ DEFAULT_PRIORITY = 10
|
|
|
33
33
|
def _assert_pinned_version(
|
|
34
34
|
kind: str, component_id: str, pinned: str | None, advertised: object
|
|
35
35
|
) -> None:
|
|
36
|
-
"""Refuse to install when the
|
|
36
|
+
"""Refuse to install when the resolved version differs from the manifest pin.
|
|
37
37
|
|
|
38
38
|
Bundle manifests pin component versions for reproducibility; installing
|
|
39
|
-
whatever the
|
|
40
|
-
pin. When the
|
|
41
|
-
installation proceeds (the
|
|
39
|
+
whatever the resolved source (catalog *or* bundled asset) provides would
|
|
40
|
+
silently violate the pin. When the source advertises no version we cannot
|
|
41
|
+
enforce the pin, so installation proceeds (the source, not the bundler,
|
|
42
|
+
owns that gap).
|
|
42
43
|
"""
|
|
43
44
|
if not pinned or advertised is None:
|
|
44
45
|
return
|
|
@@ -54,11 +55,35 @@ def _assert_pinned_version(
|
|
|
54
55
|
if not matches:
|
|
55
56
|
raise BundlerError(
|
|
56
57
|
f"{kind} '{component_id}' is pinned to version {pinned} in the bundle "
|
|
57
|
-
f"manifest, but the
|
|
58
|
-
"pinned version or the
|
|
58
|
+
f"manifest, but the resolved version is {actual}. Update the bundle's "
|
|
59
|
+
"pinned version or the source before installing."
|
|
59
60
|
)
|
|
60
61
|
|
|
61
62
|
|
|
63
|
+
def _bundled_manifest_version(manifest_path: Path, root_key: str) -> str | None:
|
|
64
|
+
"""Best-effort read of a bundled asset's declared version from its manifest.
|
|
65
|
+
|
|
66
|
+
Returns ``None`` when the manifest is missing/unreadable/invalid, which
|
|
67
|
+
``_assert_pinned_version`` treats as "cannot enforce" (proceed) — matching
|
|
68
|
+
the catalog "advertises no version" escape hatch.
|
|
69
|
+
"""
|
|
70
|
+
try:
|
|
71
|
+
import yaml
|
|
72
|
+
|
|
73
|
+
data = yaml.safe_load(manifest_path.read_text(encoding="utf-8"))
|
|
74
|
+
if isinstance(data, dict):
|
|
75
|
+
section = data.get(root_key)
|
|
76
|
+
if isinstance(section, dict):
|
|
77
|
+
version = section.get("version")
|
|
78
|
+
# Only a non-empty string is a usable version; anything else
|
|
79
|
+
# (missing / non-string / whitespace) means "cannot enforce".
|
|
80
|
+
if isinstance(version, str) and version.strip():
|
|
81
|
+
return version
|
|
82
|
+
except Exception: # noqa: BLE001 - unreadable/invalid manifest: skip pin
|
|
83
|
+
return None
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
|
|
62
87
|
class _KindManager(Protocol):
|
|
63
88
|
def is_installed(self, component: ComponentRef) -> bool: ...
|
|
64
89
|
|
|
@@ -134,6 +159,15 @@ class _PresetKindManager:
|
|
|
134
159
|
|
|
135
160
|
bundled = _locate_bundled_preset(component.id)
|
|
136
161
|
if bundled is not None:
|
|
162
|
+
# Enforce the manifest pin against the bundled asset's own version,
|
|
163
|
+
# mirroring the catalog path below (the bundled path previously
|
|
164
|
+
# skipped the pin entirely).
|
|
165
|
+
_assert_pinned_version(
|
|
166
|
+
"Preset",
|
|
167
|
+
component.id,
|
|
168
|
+
component.version,
|
|
169
|
+
_bundled_manifest_version(bundled / "preset.yml", "preset"),
|
|
170
|
+
)
|
|
137
171
|
self._manager.install_from_directory(bundled, speckit_version, priority)
|
|
138
172
|
return
|
|
139
173
|
|
|
@@ -198,6 +232,15 @@ class _ExtensionKindManager:
|
|
|
198
232
|
|
|
199
233
|
bundled = _locate_bundled_extension(component.id)
|
|
200
234
|
if bundled is not None:
|
|
235
|
+
# Enforce the manifest pin against the bundled asset's own version,
|
|
236
|
+
# mirroring the catalog path below (the bundled path previously
|
|
237
|
+
# skipped the pin entirely).
|
|
238
|
+
_assert_pinned_version(
|
|
239
|
+
"Extension",
|
|
240
|
+
component.id,
|
|
241
|
+
component.version,
|
|
242
|
+
_bundled_manifest_version(bundled / "extension.yml", "extension"),
|
|
243
|
+
)
|
|
201
244
|
self._manager.install_from_directory(
|
|
202
245
|
bundled, speckit_version, priority=priority
|
|
203
246
|
)
|
|
@@ -17,6 +17,7 @@ import os
|
|
|
17
17
|
import re
|
|
18
18
|
import shlex
|
|
19
19
|
import shutil
|
|
20
|
+
import subprocess
|
|
20
21
|
import sys
|
|
21
22
|
from abc import ABC
|
|
22
23
|
from dataclasses import dataclass
|
|
@@ -54,6 +55,18 @@ _CORE_COMMAND_TEMPLATE_RANK = {
|
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
|
|
58
|
+
def yaml_quote(value: str) -> str:
|
|
59
|
+
"""Emit *value* as a double-quoted YAML scalar on a single line.
|
|
60
|
+
|
|
61
|
+
A hand-rolled quote cannot carry raw newlines (YAML folds them to
|
|
62
|
+
spaces) or control characters (the reader rejects them), so let the
|
|
63
|
+
YAML emitter produce the escapes.
|
|
64
|
+
"""
|
|
65
|
+
return yaml.safe_dump(
|
|
66
|
+
str(value), default_style='"', allow_unicode=True, width=sys.maxsize
|
|
67
|
+
).strip()
|
|
68
|
+
|
|
69
|
+
|
|
57
70
|
# ---------------------------------------------------------------------------
|
|
58
71
|
# IntegrationOption
|
|
59
72
|
# ---------------------------------------------------------------------------
|
|
@@ -592,10 +605,42 @@ class IntegrationBase(ABC):
|
|
|
592
605
|
if candidate.exists():
|
|
593
606
|
return relative
|
|
594
607
|
for name in ("python3", "python"):
|
|
595
|
-
|
|
596
|
-
|
|
608
|
+
found = shutil.which(name)
|
|
609
|
+
if not found:
|
|
610
|
+
continue
|
|
611
|
+
# On Windows, python3/python on PATH may be the Microsoft
|
|
612
|
+
# Store App Execution Alias stub: it exists but only prints
|
|
613
|
+
# an installer hint and exits non-zero, so existence is not
|
|
614
|
+
# enough (see #3304 for the same defect in the sh scripts).
|
|
615
|
+
if sys.platform == "win32" and not IntegrationBase._interpreter_runs(
|
|
616
|
+
found
|
|
617
|
+
):
|
|
618
|
+
continue
|
|
619
|
+
return name
|
|
597
620
|
return sys.executable or "python3"
|
|
598
621
|
|
|
622
|
+
@staticmethod
|
|
623
|
+
def _interpreter_runs(path: str) -> bool:
|
|
624
|
+
"""Return True when *path* executes as a Python interpreter.
|
|
625
|
+
|
|
626
|
+
Runs isolated (``-I``) without ``site`` (``-S``) and discards
|
|
627
|
+
I/O so the probe is a fast liveness check that cannot trigger
|
|
628
|
+
``sitecustomize``/user startup hooks.
|
|
629
|
+
"""
|
|
630
|
+
try:
|
|
631
|
+
return (
|
|
632
|
+
subprocess.run(
|
|
633
|
+
[path, "-I", "-S", "-c", ""],
|
|
634
|
+
stdin=subprocess.DEVNULL,
|
|
635
|
+
stdout=subprocess.DEVNULL,
|
|
636
|
+
stderr=subprocess.DEVNULL,
|
|
637
|
+
timeout=15,
|
|
638
|
+
).returncode
|
|
639
|
+
== 0
|
|
640
|
+
)
|
|
641
|
+
except (OSError, subprocess.SubprocessError):
|
|
642
|
+
return False
|
|
643
|
+
|
|
599
644
|
@staticmethod
|
|
600
645
|
def process_template(
|
|
601
646
|
content: str,
|
|
@@ -1077,7 +1122,6 @@ class TomlIntegration(IntegrationBase):
|
|
|
1077
1122
|
# YamlIntegration — YAML-format agents (Goose)
|
|
1078
1123
|
# ---------------------------------------------------------------------------
|
|
1079
1124
|
|
|
1080
|
-
|
|
1081
1125
|
class YamlIntegration(IntegrationBase):
|
|
1082
1126
|
"""Concrete base for integrations that use YAML recipe format.
|
|
1083
1127
|
|
|
@@ -1480,21 +1524,17 @@ class SkillsIntegration(IntegrationBase):
|
|
|
1480
1524
|
if not description:
|
|
1481
1525
|
description = f"Spec Kit: {command_name} workflow"
|
|
1482
1526
|
|
|
1483
|
-
# Build SKILL.md with manually formatted frontmatter
|
|
1484
|
-
#
|
|
1485
|
-
#
|
|
1486
|
-
def _quote(v: str) -> str:
|
|
1487
|
-
escaped = v.replace("\\", "\\\\").replace('"', '\\"')
|
|
1488
|
-
return f'"{escaped}"'
|
|
1489
|
-
|
|
1527
|
+
# Build SKILL.md with manually formatted frontmatter (stable
|
|
1528
|
+
# double-quoted values). yaml_quote escapes newlines and control
|
|
1529
|
+
# characters that a plain quoted f-string cannot carry.
|
|
1490
1530
|
skill_content = (
|
|
1491
1531
|
f"---\n"
|
|
1492
|
-
f"name: {
|
|
1493
|
-
f"description: {
|
|
1494
|
-
f"compatibility: {
|
|
1532
|
+
f"name: {yaml_quote(skill_name)}\n"
|
|
1533
|
+
f"description: {yaml_quote(description)}\n"
|
|
1534
|
+
f"compatibility: {yaml_quote('Requires spec-kit project structure with .specify/ directory')}\n"
|
|
1495
1535
|
f"metadata:\n"
|
|
1496
|
-
f" author: {
|
|
1497
|
-
f" source: {
|
|
1536
|
+
f" author: {yaml_quote('github-spec-kit')}\n"
|
|
1537
|
+
f" source: {yaml_quote('templates/commands/' + src_file.name)}\n"
|
|
1498
1538
|
f"---\n"
|
|
1499
1539
|
f"{processed_body}"
|
|
1500
1540
|
)
|
|
@@ -18,7 +18,7 @@ from typing import Any
|
|
|
18
18
|
|
|
19
19
|
import yaml
|
|
20
20
|
|
|
21
|
-
from ..base import IntegrationOption, SkillsIntegration
|
|
21
|
+
from ..base import IntegrationOption, SkillsIntegration, yaml_quote
|
|
22
22
|
from ..manifest import IntegrationManifest
|
|
23
23
|
|
|
24
24
|
|
|
@@ -153,20 +153,18 @@ class HermesIntegration(SkillsIntegration):
|
|
|
153
153
|
if not description:
|
|
154
154
|
description = f"Spec Kit: {command_name} workflow"
|
|
155
155
|
|
|
156
|
-
# Build SKILL.md with manually formatted frontmatter
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return f'"{escaped}"'
|
|
160
|
-
|
|
156
|
+
# Build SKILL.md with manually formatted frontmatter. yaml_quote
|
|
157
|
+
# escapes newlines and control characters that a plain quoted
|
|
158
|
+
# f-string cannot carry.
|
|
161
159
|
skill_content = (
|
|
162
160
|
f"---\n"
|
|
163
|
-
f"name: {
|
|
164
|
-
f"description: {
|
|
161
|
+
f"name: {yaml_quote(skill_name)}\n"
|
|
162
|
+
f"description: {yaml_quote(description)}\n"
|
|
165
163
|
f"compatibility: "
|
|
166
|
-
f"{
|
|
164
|
+
f"{yaml_quote('Requires spec-kit project structure with .specify/ directory')}\n"
|
|
167
165
|
f"metadata:\n"
|
|
168
|
-
f" author: {
|
|
169
|
-
f" source: {
|
|
166
|
+
f" author: {yaml_quote('github-spec-kit')}\n"
|
|
167
|
+
f" source: {yaml_quote('templates/commands/' + src_file.name)}\n"
|
|
170
168
|
f"---\n"
|
|
171
169
|
f"{processed_body}"
|
|
172
170
|
)
|