specify-cli 0.12.12__tar.gz → 0.12.13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {specify_cli-0.12.12 → specify_cli-0.12.13}/CHANGELOG.md +15 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/PKG-INFO +2 -2
- {specify_cli-0.12.12 → specify_cli-0.12.13}/README.md +1 -1
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/install/one-time.md +2 -1
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/install/pipx.md +2 -1
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/installation.md +1 -1
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/ARCHITECTURE.md +1 -2
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/self-test/preset.yml +0 -6
- {specify_cli-0.12.12 → specify_cli-0.12.13}/pyproject.toml +1 -1
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/agents.py +49 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/extensions/__init__.py +5 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/kiro_cli/__init__.py +1 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/presets/__init__.py +40 -2
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/expressions.py +22 -2
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/if_then/__init__.py +2 -2
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/shell/__init__.py +43 -20
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/switch/__init__.py +14 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/commands/constitution.md +1 -1
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_kiro_cli.py +3 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_extension_skills.py +59 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_extensions.py +179 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_presets.py +334 -1
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_workflows.py +221 -101
- {specify_cli-0.12.12 → specify_cli-0.12.13}/workflows/README.md +6 -0
- specify_cli-0.12.12/presets/self-test/templates/agent-file-template.md +0 -9
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.devcontainer/devcontainer.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.devcontainer/post-create.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.editorconfig +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.gitattributes +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/CODEOWNERS +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/agent_request.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/bundle_submission.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/extension_submission.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/ISSUE_TEMPLATE/preset_submission.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/aw/actions-lock.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/dependabot.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/skills/add-community-extension/SKILL.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/RELEASE-PROCESS.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/add-community-extension.lock.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/add-community-extension.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/add-community-preset.lock.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/add-community-preset.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/bug-assess.lock.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/bug-assess.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/bug-fix.lock.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/bug-fix.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/bug-test.lock.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/bug-test.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/catalog-assign.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/codeql.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/docs.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/lint.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/publish-pypi.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/release-trigger.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/release.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/stale.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.github/workflows/test.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.gitignore +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.markdownlint-cli2.jsonc +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.pre-commit-config.yaml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/.zenodo.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/AGENTS.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/CITATION.cff +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/CODE_OF_CONDUCT.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/CONTRIBUTING.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/DEVELOPMENT.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/LICENSE +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/SECURITY.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/SUPPORT.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/.gitignore +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/community/bundles.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/community/extensions.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/community/friends.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/community/overview.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/community/presets.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/community/walkthroughs.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/concepts/complex-features.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/concepts/sdd.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/concepts/spec-persistence.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/docfx.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/guides/evolving-specs.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/guides/monorepo.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/index.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/install/air-gapped.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/install/uv.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/local-development.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/quickstart.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/reference/authentication.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/reference/bundles.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/reference/core.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/reference/extensions.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/reference/integrations.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/reference/overview.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/reference/presets.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/reference/workflows.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/template/public/main.css +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/toc.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/docs/upgrade.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/examples/bundles/business-analyst/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/examples/bundles/business-analyst/bundle.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/examples/bundles/developer/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/examples/bundles/developer/bundle.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/examples/bundles/product-manager/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/examples/bundles/product-manager/bundle.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/examples/bundles/security-researcher/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/examples/bundles/security-researcher/bundle.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/EXTENSION-API-REFERENCE.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/EXTENSION-DEVELOPMENT-GUIDE.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/EXTENSION-PUBLISHING-GUIDE.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/EXTENSION-USER-GUIDE.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/RFC-EXTENSION-SYSTEM.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/agent-context/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/agent-context/agent-context-config.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/agent-context/agent-context-defaults.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/agent-context/commands/speckit.agent-context.update.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/agent-context/extension.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/agent-context/scripts/bash/update-agent-context.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/agent-context/scripts/python/update_agent_context.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/bug/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/bug/commands/speckit.bug.assess.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/bug/commands/speckit.bug.fix.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/bug/commands/speckit.bug.test.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/bug/extension.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/catalog.community.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/catalog.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/commands/speckit.git.commit.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/commands/speckit.git.feature.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/commands/speckit.git.initialize.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/commands/speckit.git.remote.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/commands/speckit.git.validate.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/config-template.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/extension.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/git-config.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/scripts/bash/auto-commit.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/scripts/bash/create-new-feature-branch.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/scripts/bash/git-common.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/scripts/bash/initialize-repo.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/scripts/powershell/create-new-feature-branch.ps1 +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/scripts/powershell/git-common.ps1 +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/selftest/commands/selftest.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/selftest/extension.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/template/.gitignore +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/template/CHANGELOG.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/template/EXAMPLE-README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/template/LICENSE +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/template/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/template/commands/example.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/template/config-template.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/extensions/template/extension.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/integrations/CONTRIBUTING.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/integrations/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/integrations/catalog.community.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/integrations/catalog.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/media/bootstrap-claude-code.gif +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/media/logo_large.webp +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/media/logo_small.webp +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/media/spec-kit-video-header.jpg +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/media/specify_cli.gif +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/newsletters/2026-April.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/newsletters/2026-February.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/newsletters/2026-June.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/newsletters/2026-March.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/newsletters/2026-May.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/PUBLISHING.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/catalog.community.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/catalog.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/lean/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/lean/commands/speckit.constitution.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/lean/commands/speckit.implement.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/lean/commands/speckit.plan.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/lean/commands/speckit.specify.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/lean/commands/speckit.tasks.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/lean/preset.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/scaffold/README.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/scaffold/commands/speckit.myext.myextcmd.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/scaffold/commands/speckit.specify.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/scaffold/preset.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/scaffold/templates/myext-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/scaffold/templates/spec-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/self-test/commands/speckit.specify.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/self-test/commands/speckit.wrap-test.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/self-test/templates/checklist-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/self-test/templates/constitution-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/self-test/templates/plan-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/self-test/templates/spec-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/presets/self-test/templates/tasks-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/bash/check-prerequisites.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/bash/common.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/bash/create-new-feature.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/bash/setup-plan.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/bash/setup-tasks.sh +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/powershell/check-prerequisites.ps1 +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/powershell/common.ps1 +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/powershell/create-new-feature.ps1 +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/powershell/setup-plan.ps1 +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/powershell/setup-tasks.ps1 +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/python/check_prerequisites.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/scripts/python/common.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/spec-driven.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/spec-kit.code-workspace +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/_agent_config.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/_assets.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/_console.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/_github_http.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/_init_options.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/_invocation_style.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/_project.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/_toml_string.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/_utils.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/_version.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/authentication/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/authentication/azure_devops.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/authentication/base.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/authentication/config.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/authentication/github.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/authentication/http.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/commands_impl/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/commands_impl/catalog_config.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/lib/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/lib/project.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/lib/versioning.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/lib/yamlio.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/models/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/models/catalog.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/models/manifest.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/models/records.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/services/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/services/adapters.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/services/catalog_stack.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/services/conflict.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/services/installer.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/services/packager.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/services/primitives.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/services/references.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/services/resolver.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/bundler/services/validator.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/catalogs.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/commands/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/commands/bundle/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/commands/init.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/extensions/_commands.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integration_runtime.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integration_scaffold.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integration_state.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integration_status.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/_commands.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/_helpers.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/_install_commands.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/_migrate_commands.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/_query_commands.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/_scaffold_commands.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/agy/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/amp/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/auggie/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/base.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/bob/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/catalog.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/claude/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/cline/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/codebuddy/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/codex/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/copilot/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/cursor_agent/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/devin/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/firebender/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/forge/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/gemini/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/generic/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/goose/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/hermes/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/junie/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/kilocode/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/kimi/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/lingma/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/manifest.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/omp/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/opencode/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/pi/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/qodercli/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/qwen/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/rovodev/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/shai/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/tabnine/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/trae/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/vibe/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/zcode/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/integrations/zed/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/presets/_commands.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/shared_infra.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/_commands.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/base.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/catalog.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/engine.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/command/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/do_while/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/fan_in/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/fan_out/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/gate/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/init/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/prompt/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/while_loop/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/checklist-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/commands/analyze.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/commands/checklist.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/commands/clarify.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/commands/converge.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/commands/implement.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/commands/plan.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/commands/specify.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/commands/tasks.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/commands/taskstoissues.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/constitution-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/plan-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/spec-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/tasks-template.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/templates/vscode-settings.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/auth_helpers.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/bundler_helpers.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/conftest.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/contract/test_bundle_cli.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/contract/test_catalog_schema.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/contract/test_manifest_schema.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/extensions/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/extensions/bug/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/extensions/bug/test_bug_extension.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/extensions/git/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/extensions/git/test_git_extension.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/extensions/test_agent_context_cli_free.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/extensions/test_extension_agent_context.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/extensions/test_update_agent_context_feature_json.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/extensions/test_update_agent_context_python_parity.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/hooks/TESTING.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/hooks/plan.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/hooks/spec.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/hooks/tasks.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/http_helpers.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integration/test_bundler_catalog_stack.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integration/test_bundler_init_install.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integration/test_bundler_install_flow.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integration/test_bundler_local_install.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integration/test_bundler_offline.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integration/test_bundler_security_paths.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/__init__.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/conftest.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_base.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_cli.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_extra_args.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_home_isolation.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_agy.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_amp.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_auggie.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_base_markdown.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_base_skills.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_base_toml.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_base_yaml.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_bob.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_catalog.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_claude.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_cline.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_codebuddy.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_codex.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_copilot.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_cursor_agent.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_devin.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_firebender.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_forge.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_gemini.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_generic.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_goose.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_hermes.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_junie.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_kilocode.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_kimi.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_lingma.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_omp.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_opencode.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_pi.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_qodercli.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_qwen.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_rovodev.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_scaffold.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_shai.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_state.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_subcommand.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_tabnine.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_trae.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_vibe.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_zcode.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_integration_zed.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_manifest.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_registry.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/integrations/test_skill_frontmatter_quoting.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/self_upgrade_helpers.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_agent_config_consistency.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_authentication.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_branch_numbering.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_check_prerequisites_paths_only.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_check_prerequisites_python_parity.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_check_tool.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_cli_version.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_command_template_py_scripts.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_commands_package.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_console_imports.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_extension_registration.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_extension_update_hardening.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_github_http.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_github_workflows.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_init_dir.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_init_dir_cli.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_live_transient_windows.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_merge.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_post_process.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_ps1_encoding.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_registrar_path_traversal.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_self_upgrade_detection.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_self_upgrade_execution.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_self_upgrade_guidance.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_self_upgrade_verification.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_setup_plan_feature_json.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_setup_plan_no_overwrite.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_setup_tasks.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_shared_infra_integrity.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_timestamp_branches.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_upgrade.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_utils.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_utils_assets_imports.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_version_imports.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/test_workflow_run_without_project.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/unit/test_bundler_adapters.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/unit/test_bundler_catalog_config.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/unit/test_bundler_conflict.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/unit/test_bundler_packager.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/unit/test_bundler_primitives.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/unit/test_bundler_records.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/unit/test_bundler_references.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/unit/test_bundler_resolver.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/unit/test_bundler_validator.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/tests/unit/test_bundler_versioning.py +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/workflows/ARCHITECTURE.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/workflows/PUBLISHING.md +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/workflows/catalog.community.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/workflows/catalog.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/workflows/speckit/workflow.yml +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/workflows/step-catalog.community.json +0 -0
- {specify_cli-0.12.12 → specify_cli-0.12.13}/workflows/step-catalog.json +0 -0
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- insert new changelog below this comment -->
|
|
4
4
|
|
|
5
|
+
## [0.12.13] - 2026-07-13
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- fix(workflows): fail switch step on non-mapping cases instead of crashing (#3481)
|
|
10
|
+
- Cleanup agent-file-template.md (#2579)
|
|
11
|
+
- fix: mark Kiro integration as multi-install safe (#3472)
|
|
12
|
+
- fix: rewrite extension-relative subdir paths in generated command bodies (#3444)
|
|
13
|
+
- fix(templates): point constitution sync checklist at installed command files (#3418)
|
|
14
|
+
- feat(workflows): make shell step timeout configurable (#3327) (#3328)
|
|
15
|
+
- docs: clarify that release tags keep the leading v prefix (#3463)
|
|
16
|
+
- fix(workflows): don't crash on membership test against a non-iterable (#3448)
|
|
17
|
+
- fix(workflows): if-step validate accepts falsy non-list else (#3264)
|
|
18
|
+
- chore: release 0.12.12, begin 0.12.13.dev0 development (#3490)
|
|
19
|
+
|
|
5
20
|
## [0.12.12] - 2026-07-13
|
|
6
21
|
|
|
7
22
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specify-cli
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.13
|
|
4
4
|
Summary: Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD).
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -65,7 +65,7 @@ Spec-Driven Development **flips the script** on traditional software development
|
|
|
65
65
|
|
|
66
66
|
### 1. Install Specify CLI
|
|
67
67
|
|
|
68
|
-
Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](./docs/install/uv.md)). Replace `vX.Y.Z` with the latest tag from [Releases](https://github.com/github/spec-kit/releases):
|
|
68
|
+
Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](./docs/install/uv.md)). Replace `vX.Y.Z` with the latest release tag from [Releases](https://github.com/github/spec-kit/releases) — keep the leading `v` (for example, `v0.12.11`, not `0.12.11`):
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z
|
|
@@ -45,7 +45,7 @@ Spec-Driven Development **flips the script** on traditional software development
|
|
|
45
45
|
|
|
46
46
|
### 1. Install Specify CLI
|
|
47
47
|
|
|
48
|
-
Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](./docs/install/uv.md)). Replace `vX.Y.Z` with the latest tag from [Releases](https://github.com/github/spec-kit/releases):
|
|
48
|
+
Requires **[uv](https://docs.astral.sh/uv/)** ([install uv](./docs/install/uv.md)). Replace `vX.Y.Z` with the latest release tag from [Releases](https://github.com/github/spec-kit/releases) — keep the leading `v` (for example, `v0.12.11`, not `0.12.11`):
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z
|
|
@@ -11,7 +11,8 @@ If you want to try Spec Kit without installing it permanently, use `uvx` to run
|
|
|
11
11
|
# Create a new project (latest from main)
|
|
12
12
|
uvx --from git+https://github.com/github/spec-kit.git specify init <PROJECT_NAME>
|
|
13
13
|
|
|
14
|
-
# Or target a specific release (replace vX.Y.Z with a tag from Releases
|
|
14
|
+
# Or target a specific release (replace vX.Y.Z with a tag from Releases;
|
|
15
|
+
# keep the leading v, e.g. v0.12.11 not 0.12.11)
|
|
15
16
|
uvx --from git+https://github.com/github/spec-kit.git@vX.Y.Z specify init <PROJECT_NAME>
|
|
16
17
|
|
|
17
18
|
# Initialize in the current directory
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
Pin a specific release tag for stability (check [Releases](https://github.com/github/spec-kit/releases) for the latest):
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
# Install a specific stable release (recommended — replace vX.Y.Z with the
|
|
10
|
+
# Install a specific stable release (recommended — replace vX.Y.Z with the
|
|
11
|
+
# latest tag, keeping the leading v, e.g. v0.12.11 not 0.12.11)
|
|
11
12
|
pipx install git+https://github.com/github/spec-kit.git@vX.Y.Z
|
|
12
13
|
|
|
13
14
|
# Or install latest from main (may include unreleased changes)
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
### Persistent Installation (Recommended)
|
|
17
17
|
|
|
18
|
-
Install once and use everywhere. Replace `vX.Y.Z` with a tag from [Releases](https://github.com/github/spec-kit/releases):
|
|
18
|
+
Install once and use everywhere. Replace `vX.Y.Z` with a release tag from [Releases](https://github.com/github/spec-kit/releases) — keep the leading `v` (for example, `v0.12.11`, not `0.12.11`):
|
|
19
19
|
|
|
20
20
|
> [!NOTE]
|
|
21
21
|
> The command below requires **[uv](https://docs.astral.sh/uv/)**. If you see `command not found: uv`, [install uv first](./install/uv.md).
|
|
@@ -44,12 +44,6 @@ provides:
|
|
|
44
44
|
description: "Self-test constitution template"
|
|
45
45
|
replaces: "constitution-template"
|
|
46
46
|
|
|
47
|
-
- type: "template"
|
|
48
|
-
name: "agent-file-template"
|
|
49
|
-
file: "templates/agent-file-template.md"
|
|
50
|
-
description: "Self-test agent file template"
|
|
51
|
-
replaces: "agent-file-template"
|
|
52
|
-
|
|
53
47
|
- type: "command"
|
|
54
48
|
name: "speckit.specify"
|
|
55
49
|
file: "commands/speckit.specify.md"
|
|
@@ -213,6 +213,52 @@ class CommandRegistrar:
|
|
|
213
213
|
".specify.specify/", ".specify/"
|
|
214
214
|
)
|
|
215
215
|
|
|
216
|
+
@staticmethod
|
|
217
|
+
def rewrite_extension_paths(
|
|
218
|
+
text: str, extension_id: str, extension_dir: Path
|
|
219
|
+
) -> str:
|
|
220
|
+
"""Rewrite extension-relative paths to their installed locations.
|
|
221
|
+
|
|
222
|
+
Extension command bodies reference bundled files relative to the
|
|
223
|
+
extension root (e.g. ``agents/control/commander.md``). After install
|
|
224
|
+
those files live under ``.specify/extensions/<id>/``, so bare
|
|
225
|
+
references would resolve against the workspace root and never be
|
|
226
|
+
found (#2101).
|
|
227
|
+
|
|
228
|
+
Only directories that actually exist inside *extension_dir* are
|
|
229
|
+
rewritten, keeping the behaviour conservative and avoiding false
|
|
230
|
+
positives on prose. ``commands`` (slash-command sources), ``specs``
|
|
231
|
+
(user project artifacts) and dot-directories are never rewritten.
|
|
232
|
+
"""
|
|
233
|
+
if not isinstance(text, str) or not text:
|
|
234
|
+
return text
|
|
235
|
+
|
|
236
|
+
skip = {"commands", ".git", "specs"}
|
|
237
|
+
try:
|
|
238
|
+
subdirs = [
|
|
239
|
+
entry.name
|
|
240
|
+
for entry in extension_dir.iterdir()
|
|
241
|
+
if entry.is_dir()
|
|
242
|
+
and entry.name not in skip
|
|
243
|
+
and not entry.name.startswith(".")
|
|
244
|
+
]
|
|
245
|
+
except OSError:
|
|
246
|
+
return text
|
|
247
|
+
|
|
248
|
+
for subdir in subdirs:
|
|
249
|
+
# Only rewrite relative references (subdir/... or ./subdir/...);
|
|
250
|
+
# absolute paths like /subdir/... keep their meaning. Use a
|
|
251
|
+
# callable replacement: subdir/extension_id come from the
|
|
252
|
+
# filesystem and could contain backslashes or "\1"-like
|
|
253
|
+
# sequences, which would corrupt a string replacement template.
|
|
254
|
+
replacement = f".specify/extensions/{extension_id}/{subdir}/"
|
|
255
|
+
text = re.sub(
|
|
256
|
+
r'(^|[\s`"\'(])(?:\./)?' + re.escape(subdir) + "/",
|
|
257
|
+
lambda m: m.group(1) + replacement,
|
|
258
|
+
text,
|
|
259
|
+
)
|
|
260
|
+
return text
|
|
261
|
+
|
|
216
262
|
def render_markdown_command(
|
|
217
263
|
self, frontmatter: dict, body: str, source_id: str, context_note: str = None
|
|
218
264
|
) -> str:
|
|
@@ -639,6 +685,9 @@ class CommandRegistrar:
|
|
|
639
685
|
frontmatter[key] = core_frontmatter[key]
|
|
640
686
|
frontmatter.pop("strategy", None)
|
|
641
687
|
|
|
688
|
+
if extension_id:
|
|
689
|
+
body = self.rewrite_extension_paths(body, extension_id, source_root)
|
|
690
|
+
|
|
642
691
|
frontmatter = self._adjust_script_paths(
|
|
643
692
|
frontmatter, extension_id=extension_id
|
|
644
693
|
)
|
|
@@ -1078,6 +1078,11 @@ class ExtensionManager:
|
|
|
1078
1078
|
frontmatter = registrar._adjust_script_paths(
|
|
1079
1079
|
frontmatter, extension_id=manifest.id
|
|
1080
1080
|
)
|
|
1081
|
+
# Mirror the register_commands() rewrite (#2101): resolve
|
|
1082
|
+
# extension-relative subdir references (agents/, knowledge-base/,
|
|
1083
|
+
# etc.) to their installed .specify/extensions/<id>/ location
|
|
1084
|
+
# before the generic placeholder/path resolution below.
|
|
1085
|
+
body = registrar.rewrite_extension_paths(body, manifest.id, extension_dir)
|
|
1081
1086
|
body = registrar.resolve_skill_placeholders(
|
|
1082
1087
|
selected_ai, frontmatter, body, self.project_root, extension_id=manifest.id
|
|
1083
1088
|
)
|
|
@@ -778,6 +778,7 @@ class PresetManager:
|
|
|
778
778
|
matching_cmds, ext_id, ext_dir,
|
|
779
779
|
self.project_root,
|
|
780
780
|
context_note=f"\n<!-- Extension: {ext_id} -->\n<!-- Config: .specify/extensions/{ext_id}/ -->\n",
|
|
781
|
+
extension_id=ext_id,
|
|
781
782
|
)
|
|
782
783
|
registered = True
|
|
783
784
|
except Exception:
|
|
@@ -1199,6 +1200,8 @@ class PresetManager:
|
|
|
1199
1200
|
"command_name": cmd_name,
|
|
1200
1201
|
"source_file": source_file,
|
|
1201
1202
|
"source": f"extension:{manifest.id}",
|
|
1203
|
+
"extension_id": manifest.id,
|
|
1204
|
+
"extension_dir": ext_root,
|
|
1202
1205
|
}
|
|
1203
1206
|
modern_skill_name, legacy_skill_name = self._skill_names_for_command(cmd_name)
|
|
1204
1207
|
restore_index.setdefault(modern_skill_name, restore_info)
|
|
@@ -1463,6 +1466,17 @@ class PresetManager:
|
|
|
1463
1466
|
if extension_restore:
|
|
1464
1467
|
content = extension_restore["source_file"].read_text(encoding="utf-8")
|
|
1465
1468
|
frontmatter, body = registrar.parse_frontmatter(content)
|
|
1469
|
+
# Mirror the register-time rewrite (#2101): resolve
|
|
1470
|
+
# extension-relative subdir references (agents/,
|
|
1471
|
+
# knowledge-base/, etc.) to their installed location before
|
|
1472
|
+
# the generic placeholder resolution below, otherwise
|
|
1473
|
+
# restoring after a preset override removal would leave
|
|
1474
|
+
# bare, unresolvable paths in the skill body.
|
|
1475
|
+
body = registrar.rewrite_extension_paths(
|
|
1476
|
+
body,
|
|
1477
|
+
extension_restore["extension_id"],
|
|
1478
|
+
extension_restore["extension_dir"],
|
|
1479
|
+
)
|
|
1466
1480
|
if isinstance(selected_ai, str):
|
|
1467
1481
|
body = registrar.resolve_skill_placeholders(
|
|
1468
1482
|
selected_ai, frontmatter, body, self.project_root
|
|
@@ -3038,6 +3052,8 @@ class PresetResolver:
|
|
|
3038
3052
|
"path": candidate,
|
|
3039
3053
|
"source": source,
|
|
3040
3054
|
"strategy": "replace",
|
|
3055
|
+
"extension_id": ext_id,
|
|
3056
|
+
"extension_dir": ext_dir,
|
|
3041
3057
|
})
|
|
3042
3058
|
|
|
3043
3059
|
# Priority 4: Core templates (always "replace")
|
|
@@ -3157,10 +3173,32 @@ class PresetResolver:
|
|
|
3157
3173
|
if not layers:
|
|
3158
3174
|
return None
|
|
3159
3175
|
|
|
3176
|
+
def _read_layer_content(layer: Dict[str, Any]) -> str:
|
|
3177
|
+
"""Read a layer's raw text, rewriting extension-relative subdir
|
|
3178
|
+
references (agents/, knowledge-base/, etc.) to their installed
|
|
3179
|
+
location when the layer is extension-provided (#2101).
|
|
3180
|
+
|
|
3181
|
+
Extension layers are always inserted with strategy "replace"
|
|
3182
|
+
(see collect_all_layers), so a layer only ever needs this
|
|
3183
|
+
rewrite when it wins outright above or serves as the
|
|
3184
|
+
composition base below — never as a mid-stack composing
|
|
3185
|
+
(append/prepend/wrap) layer.
|
|
3186
|
+
"""
|
|
3187
|
+
text = layer["path"].read_text(encoding="utf-8")
|
|
3188
|
+
extension_id = layer.get("extension_id")
|
|
3189
|
+
extension_dir = layer.get("extension_dir")
|
|
3190
|
+
if extension_id and extension_dir:
|
|
3191
|
+
from ..agents import CommandRegistrar
|
|
3192
|
+
|
|
3193
|
+
text = CommandRegistrar.rewrite_extension_paths(
|
|
3194
|
+
text, extension_id, extension_dir
|
|
3195
|
+
)
|
|
3196
|
+
return text
|
|
3197
|
+
|
|
3160
3198
|
# If the top (highest-priority) layer is replace, it wins entirely —
|
|
3161
3199
|
# lower layers are irrelevant regardless of their strategies.
|
|
3162
3200
|
if layers[0]["strategy"] == "replace":
|
|
3163
|
-
return layers[0]
|
|
3201
|
+
return _read_layer_content(layers[0])
|
|
3164
3202
|
|
|
3165
3203
|
# Composition: build content bottom-up from the effective base.
|
|
3166
3204
|
# The base is the nearest replace layer scanning from highest priority
|
|
@@ -3183,7 +3221,7 @@ class PresetResolver:
|
|
|
3183
3221
|
|
|
3184
3222
|
# Convert to reversed_layers index
|
|
3185
3223
|
base_reversed_idx = len(layers) - 1 - base_layer_idx
|
|
3186
|
-
content = layers[base_layer_idx]
|
|
3224
|
+
content = _read_layer_content(layers[base_layer_idx])
|
|
3187
3225
|
# Compose only the layers above the base (higher priority = lower index in layers,
|
|
3188
3226
|
# higher index in reversed_layers). Process bottom-up from base+1.
|
|
3189
3227
|
start_idx = base_reversed_idx + 1
|
|
@@ -464,9 +464,9 @@ def _evaluate_simple_expression(expr: str, namespace: dict[str, Any]) -> Any:
|
|
|
464
464
|
if op == "<=":
|
|
465
465
|
return _safe_compare(left, right, "<=")
|
|
466
466
|
if op == " in ":
|
|
467
|
-
return left
|
|
467
|
+
return _safe_membership(left, right, negate=False)
|
|
468
468
|
if op == " not in ":
|
|
469
|
-
return left
|
|
469
|
+
return _safe_membership(left, right, negate=True)
|
|
470
470
|
|
|
471
471
|
# Numeric literal
|
|
472
472
|
try:
|
|
@@ -511,6 +511,26 @@ def _coerce_number(value: Any) -> Any:
|
|
|
511
511
|
return value
|
|
512
512
|
|
|
513
513
|
|
|
514
|
+
def _safe_membership(left: Any, right: Any, *, negate: bool) -> bool:
|
|
515
|
+
"""Safely evaluate ``left in right`` (or ``not in``) without crashing.
|
|
516
|
+
|
|
517
|
+
``left in right`` raises ``TypeError`` whenever the operands don't support
|
|
518
|
+
membership testing — most commonly a non-iterable right operand (``None``,
|
|
519
|
+
an int, a bool), but also cases like an unhashable ``left`` against a set.
|
|
520
|
+
In every such case the membership relation is undefined, so treat it as
|
|
521
|
+
``False`` (``not in`` as ``True``) rather than leaking the error out of the
|
|
522
|
+
evaluator and crashing the whole workflow. Mirrors the graceful
|
|
523
|
+
``TypeError`` handling in ``_safe_compare`` for the ordering operators, and
|
|
524
|
+
generalizes the previous ``right is not None`` guard to any operand pair
|
|
525
|
+
that can't be membership-tested.
|
|
526
|
+
"""
|
|
527
|
+
try:
|
|
528
|
+
contained = left in right
|
|
529
|
+
except TypeError:
|
|
530
|
+
contained = False
|
|
531
|
+
return not contained if negate else contained
|
|
532
|
+
|
|
533
|
+
|
|
514
534
|
def _safe_compare(left: Any, right: Any, op: str) -> bool:
|
|
515
535
|
"""Compare two values for ordering, coercing numeric strings when possible.
|
|
516
536
|
|
{specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/if_then/__init__.py
RENAMED
|
@@ -47,8 +47,8 @@ class IfThenStep(StepBase):
|
|
|
47
47
|
errors.append(
|
|
48
48
|
f"If step {config.get('id', '?')!r}: 'then' must be a list of steps."
|
|
49
49
|
)
|
|
50
|
-
else_branch = config.get("else"
|
|
51
|
-
if else_branch and not isinstance(else_branch, list):
|
|
50
|
+
else_branch = config.get("else")
|
|
51
|
+
if else_branch is not None and not isinstance(else_branch, list):
|
|
52
52
|
errors.append(
|
|
53
53
|
f"If step {config.get('id', '?')!r}: 'else' must be a list of steps."
|
|
54
54
|
)
|
{specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/shell/__init__.py
RENAMED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import json
|
|
6
|
+
import math
|
|
6
7
|
import subprocess
|
|
7
8
|
from typing import Any
|
|
8
9
|
|
|
@@ -25,15 +26,20 @@ class ShellStep(StepBase):
|
|
|
25
26
|
run_cmd = str(run_cmd)
|
|
26
27
|
|
|
27
28
|
cwd = context.project_root or "."
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# the
|
|
32
|
-
#
|
|
29
|
+
# Per-step execution timeout in seconds; defaults to 300 for backward
|
|
30
|
+
# compatibility. The engine does not auto-validate step config, so
|
|
31
|
+
# validate here as well — a caller that skips WorkflowEngine.validate()
|
|
32
|
+
# must fail the step cleanly rather than crash subprocess.run() with a
|
|
33
|
+
# TypeError (or silently coerce ``timeout: true`` to a 1s duration,
|
|
34
|
+
# since bool is an int subclass).
|
|
33
35
|
timeout = config.get("timeout", 300)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
timeout_error = self._timeout_error(config)
|
|
37
|
+
if timeout_error is not None:
|
|
38
|
+
return StepResult(
|
|
39
|
+
status=StepStatus.FAILED,
|
|
40
|
+
error=timeout_error,
|
|
41
|
+
output={"exit_code": -1, "stdout": "", "stderr": "invalid timeout"},
|
|
42
|
+
)
|
|
37
43
|
# NOTE: shell=True is required to support pipes, redirects, and
|
|
38
44
|
# multi-command expressions in workflow YAML. Workflow authors
|
|
39
45
|
# control commands; catalog-installed workflows should be reviewed
|
|
@@ -92,6 +98,32 @@ class ShellStep(StepBase):
|
|
|
92
98
|
output={"exit_code": -1, "stdout": "", "stderr": str(exc)},
|
|
93
99
|
)
|
|
94
100
|
|
|
101
|
+
@staticmethod
|
|
102
|
+
def _timeout_error(config: dict[str, Any]) -> str | None:
|
|
103
|
+
"""Return an error message if ``config['timeout']`` is invalid, else None.
|
|
104
|
+
|
|
105
|
+
Shared by execute() and validate() so both paths reject the same
|
|
106
|
+
values with the same message. An absent ``timeout`` is valid (the
|
|
107
|
+
default is used). bool is a subclass of int, but ``timeout: true`` is a
|
|
108
|
+
config error rather than a duration, so it is rejected explicitly.
|
|
109
|
+
Non-finite floats (YAML ``.inf``/``.nan``) pass a plain ``> 0`` check
|
|
110
|
+
but would raise in subprocess.run(), so they are rejected too.
|
|
111
|
+
"""
|
|
112
|
+
if "timeout" not in config:
|
|
113
|
+
return None
|
|
114
|
+
timeout = config["timeout"]
|
|
115
|
+
if (
|
|
116
|
+
isinstance(timeout, bool)
|
|
117
|
+
or not isinstance(timeout, (int, float))
|
|
118
|
+
or not math.isfinite(timeout)
|
|
119
|
+
or timeout <= 0
|
|
120
|
+
):
|
|
121
|
+
return (
|
|
122
|
+
f"Shell step {config.get('id', '?')!r}: 'timeout' must be a "
|
|
123
|
+
f"positive number of seconds, got {timeout!r}."
|
|
124
|
+
)
|
|
125
|
+
return None
|
|
126
|
+
|
|
95
127
|
def validate(self, config: dict[str, Any]) -> list[str]:
|
|
96
128
|
errors = super().validate(config)
|
|
97
129
|
if "run" not in config:
|
|
@@ -114,16 +146,7 @@ class ShellStep(StepBase):
|
|
|
114
146
|
f"Shell step {config.get('id', '?')!r}: 'output_format' must "
|
|
115
147
|
f"be 'json' when present, got {output_format!r}."
|
|
116
148
|
)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (
|
|
121
|
-
isinstance(timeout, bool)
|
|
122
|
-
or not isinstance(timeout, int)
|
|
123
|
-
or timeout <= 0
|
|
124
|
-
):
|
|
125
|
-
errors.append(
|
|
126
|
-
f"Shell step {config.get('id', '?')!r}: 'timeout' must be a "
|
|
127
|
-
f"positive integer (seconds) when present, got {timeout!r}."
|
|
128
|
-
)
|
|
149
|
+
timeout_error = self._timeout_error(config)
|
|
150
|
+
if timeout_error is not None:
|
|
151
|
+
errors.append(timeout_error)
|
|
129
152
|
return errors
|
{specify_cli-0.12.12 → specify_cli-0.12.13}/src/specify_cli/workflows/steps/switch/__init__.py
RENAMED
|
@@ -26,6 +26,20 @@ class SwitchStep(StepBase):
|
|
|
26
26
|
str_value = str(value) if value is not None else ""
|
|
27
27
|
|
|
28
28
|
cases = config.get("cases", {})
|
|
29
|
+
if not isinstance(cases, dict):
|
|
30
|
+
# The engine does not auto-validate step config, so an unvalidated
|
|
31
|
+
# run with a non-mapping ``cases`` (a list/scalar authoring mistake)
|
|
32
|
+
# would otherwise raise AttributeError from ``.items()`` below and
|
|
33
|
+
# crash the whole run. Fail this step loudly instead, mirroring the
|
|
34
|
+
# fan-out step's non-list ``items`` handling.
|
|
35
|
+
return StepResult(
|
|
36
|
+
status=StepStatus.FAILED,
|
|
37
|
+
error=(
|
|
38
|
+
f"Switch step {config.get('id', '?')!r}: 'cases' must be a "
|
|
39
|
+
f"mapping, got {type(cases).__name__}."
|
|
40
|
+
),
|
|
41
|
+
output={"matched_case": None, "expression_value": value},
|
|
42
|
+
)
|
|
29
43
|
for case_key, case_steps in cases.items():
|
|
30
44
|
if str(case_key) == str_value:
|
|
31
45
|
return StepResult(
|
|
@@ -81,7 +81,7 @@ Follow this execution flow:
|
|
|
81
81
|
- Read `.specify/templates/plan-template.md` and ensure any "Constitution Check" or rules align with updated principles.
|
|
82
82
|
- Read `.specify/templates/spec-template.md` for scope/requirements alignment—update if constitution adds/removes mandatory sections or constraints.
|
|
83
83
|
- Read `.specify/templates/tasks-template.md` and ensure task categorization reflects new or removed principle-driven task types (e.g., observability, versioning, testing discipline).
|
|
84
|
-
- Read each command file
|
|
84
|
+
- Read each installed Spec Kit command file for your agent (including this one) — named `speckit.*` or `speckit-*` (dot or hyphen depending on the agent), or laid out as `speckit-<name>/SKILL.md` for skills-based integrations, e.g. in `.github/agents/`, `.github/skills/`, `.claude/skills/`, or your agent's equivalent commands directory — to verify no outdated references (CLAUDE-only or other agent-specific names) remain when generic guidance is required.
|
|
85
85
|
- Read any runtime guidance docs (e.g., `README.md`, `docs/quickstart.md`, or agent-specific guidance files if present). Update references to principles changed.
|
|
86
86
|
|
|
87
87
|
5. Produce a Sync Impact Report (prepend as an HTML comment at top of the constitution file after update):
|
|
@@ -42,6 +42,9 @@ class TestKiroCliIntegration(MarkdownIntegrationTests):
|
|
|
42
42
|
COMMANDS_SUBDIR = "prompts"
|
|
43
43
|
REGISTRAR_DIR = ".kiro/prompts"
|
|
44
44
|
|
|
45
|
+
def test_declares_multi_install_safe(self):
|
|
46
|
+
assert get_integration(self.KEY).multi_install_safe is True
|
|
47
|
+
|
|
45
48
|
def test_registrar_config(self):
|
|
46
49
|
"""Override base assertion: kiro-cli uses a prose fallback for args
|
|
47
50
|
because Kiro CLI file-based prompts do not natively substitute
|
|
@@ -911,6 +911,65 @@ class TestExtensionSkillRegistration:
|
|
|
911
911
|
assert ".specify/scripts/bash/resolve-skill.sh" not in content
|
|
912
912
|
assert ".specify/scripts/bash/ensure-skills.sh" not in content
|
|
913
913
|
|
|
914
|
+
def test_skill_registration_rewrites_extension_subdir_paths(self, project_dir, temp_dir):
|
|
915
|
+
"""Auto-registered skills should resolve extension-relative subdir
|
|
916
|
+
references (agents/, knowledge-base/) to their installed location,
|
|
917
|
+
matching the rewrite already applied by register_commands() (#2101)."""
|
|
918
|
+
_create_init_options(project_dir, ai="claude", ai_skills=True)
|
|
919
|
+
skills_dir = _create_skills_dir(project_dir, ai="claude")
|
|
920
|
+
|
|
921
|
+
ext_dir = temp_dir / "path-ext"
|
|
922
|
+
ext_dir.mkdir()
|
|
923
|
+
manifest_data = {
|
|
924
|
+
"schema_version": "1.0",
|
|
925
|
+
"extension": {
|
|
926
|
+
"id": "path-ext",
|
|
927
|
+
"name": "Path Extension",
|
|
928
|
+
"version": "1.0.0",
|
|
929
|
+
"description": "Test",
|
|
930
|
+
},
|
|
931
|
+
"requires": {"speckit_version": ">=0.1.0"},
|
|
932
|
+
"provides": {
|
|
933
|
+
"commands": [
|
|
934
|
+
{
|
|
935
|
+
"name": "speckit.path-ext.run",
|
|
936
|
+
"file": "commands/run.md",
|
|
937
|
+
"description": "Run command",
|
|
938
|
+
}
|
|
939
|
+
]
|
|
940
|
+
},
|
|
941
|
+
}
|
|
942
|
+
with open(ext_dir / "extension.yml", "w") as f:
|
|
943
|
+
yaml.safe_dump(manifest_data, f)
|
|
944
|
+
|
|
945
|
+
(ext_dir / "commands").mkdir()
|
|
946
|
+
(ext_dir / "agents" / "control").mkdir(parents=True)
|
|
947
|
+
(ext_dir / "agents" / "control" / "commander.md").write_text("# Commander\n")
|
|
948
|
+
(ext_dir / "knowledge-base").mkdir()
|
|
949
|
+
(ext_dir / "knowledge-base" / "agent-scores.yaml").write_text("scores: {}\n")
|
|
950
|
+
(ext_dir / "templates").mkdir()
|
|
951
|
+
(ext_dir / "templates" / "kill-report.md").write_text("# Kill Report\n")
|
|
952
|
+
|
|
953
|
+
(ext_dir / "commands" / "run.md").write_text(
|
|
954
|
+
"---\n"
|
|
955
|
+
"description: Run command\n"
|
|
956
|
+
"---\n\n"
|
|
957
|
+
"Read agents/control/commander.md and knowledge-base/agent-scores.yaml.\n"
|
|
958
|
+
"Use templates/kill-report.md as the report template.\n"
|
|
959
|
+
)
|
|
960
|
+
|
|
961
|
+
manager = ExtensionManager(project_dir)
|
|
962
|
+
manager.install_from_directory(ext_dir, "0.1.0", register_commands=False)
|
|
963
|
+
|
|
964
|
+
content = (skills_dir / "speckit-path-ext-run" / "SKILL.md").read_text()
|
|
965
|
+
assert ".specify/extensions/path-ext/agents/control/commander.md" in content
|
|
966
|
+
assert ".specify/extensions/path-ext/knowledge-base/agent-scores.yaml" in content
|
|
967
|
+
# extension's own templates/ dir must resolve under the extension,
|
|
968
|
+
# not the project-level .specify/templates/
|
|
969
|
+
assert ".specify/extensions/path-ext/templates/kill-report.md" in content
|
|
970
|
+
assert "Read agents/control" not in content
|
|
971
|
+
assert "and knowledge-base/" not in content
|
|
972
|
+
|
|
914
973
|
def test_missing_command_file_skipped(self, skills_project, temp_dir):
|
|
915
974
|
"""Commands with missing source files should be skipped gracefully."""
|
|
916
975
|
project_dir, skills_dir = skills_project
|