specify-cli 0.12.5__tar.gz → 0.12.6__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.5 → specify_cli-0.12.6}/CHANGELOG.md +15 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/PKG-INFO +1 -1
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/extensions.md +1 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/catalog.community.json +45 -6
- {specify_cli-0.12.5 → specify_cli-0.12.6}/pyproject.toml +1 -1
- specify_cli-0.12.6/scripts/python/check_prerequisites.py +207 -0
- specify_cli-0.12.6/scripts/python/common.py +210 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/agents.py +47 -12
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/commands_impl/catalog_config.py +23 -2
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/extensions/__init__.py +12 -3
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/base.py +8 -2
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/hermes/__init__.py +5 -0
- specify_cli-0.12.6/tests/integrations/conftest.py +38 -0
- specify_cli-0.12.6/tests/integrations/test_home_isolation.py +21 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_base_yaml.py +17 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_hermes.py +35 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_registry.py +81 -54
- specify_cli-0.12.6/tests/test_check_prerequisites_python_parity.py +339 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_extension_skills.py +61 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_extensions.py +94 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_catalog_config.py +36 -0
- specify_cli-0.12.5/tests/integrations/conftest.py +0 -22
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.devcontainer/devcontainer.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.devcontainer/post-create.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.editorconfig +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.gitattributes +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/CODEOWNERS +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/agent_request.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/bundle_submission.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/extension_submission.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/ISSUE_TEMPLATE/preset_submission.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/aw/actions-lock.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/dependabot.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/skills/add-community-extension/SKILL.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/RELEASE-PROCESS.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/add-community-extension.lock.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/add-community-extension.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/add-community-preset.lock.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/add-community-preset.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-assess.lock.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-assess.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-fix.lock.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-fix.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-test.lock.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/bug-test.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/catalog-assign.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/codeql.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/docs.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/lint.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/publish-pypi.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/release-trigger.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/release.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/stale.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.github/workflows/test.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.gitignore +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.markdownlint-cli2.jsonc +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/.zenodo.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/AGENTS.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/CITATION.cff +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/CODE_OF_CONDUCT.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/CONTRIBUTING.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/DEVELOPMENT.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/LICENSE +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/SECURITY.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/SUPPORT.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/.gitignore +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/bundles.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/friends.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/overview.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/presets.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/community/walkthroughs.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/concepts/complex-features.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/concepts/sdd.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/concepts/spec-persistence.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/docfx.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/guides/evolving-specs.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/guides/monorepo.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/index.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/install/air-gapped.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/install/one-time.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/install/pipx.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/install/uv.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/installation.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/local-development.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/quickstart.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/authentication.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/bundles.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/core.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/extensions.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/integrations.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/overview.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/presets.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/reference/workflows.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/template/public/main.css +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/toc.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/docs/upgrade.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/business-analyst/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/business-analyst/bundle.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/developer/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/developer/bundle.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/product-manager/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/product-manager/bundle.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/security-researcher/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/examples/bundles/security-researcher/bundle.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/EXTENSION-API-REFERENCE.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/EXTENSION-DEVELOPMENT-GUIDE.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/EXTENSION-PUBLISHING-GUIDE.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/EXTENSION-USER-GUIDE.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/RFC-EXTENSION-SYSTEM.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/agent-context-config.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/agent-context-defaults.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/commands/speckit.agent-context.update.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/extension.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/scripts/bash/update-agent-context.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/bug/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/bug/commands/speckit.bug.assess.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/bug/commands/speckit.bug.fix.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/bug/commands/speckit.bug.test.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/bug/extension.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/catalog.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/commands/speckit.git.commit.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/commands/speckit.git.feature.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/commands/speckit.git.initialize.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/commands/speckit.git.remote.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/commands/speckit.git.validate.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/config-template.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/extension.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/git-config.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/bash/auto-commit.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/bash/create-new-feature-branch.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/bash/git-common.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/bash/initialize-repo.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/powershell/create-new-feature-branch.ps1 +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/powershell/git-common.ps1 +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/selftest/commands/selftest.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/selftest/extension.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/.gitignore +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/CHANGELOG.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/EXAMPLE-README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/LICENSE +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/commands/example.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/config-template.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/extensions/template/extension.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/integrations/CONTRIBUTING.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/integrations/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/integrations/catalog.community.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/integrations/catalog.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/media/bootstrap-claude-code.gif +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/media/logo_large.webp +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/media/logo_small.webp +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/media/spec-kit-video-header.jpg +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/media/specify_cli.gif +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/newsletters/2026-April.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/newsletters/2026-February.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/newsletters/2026-June.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/newsletters/2026-March.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/newsletters/2026-May.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/ARCHITECTURE.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/PUBLISHING.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/catalog.community.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/catalog.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/commands/speckit.constitution.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/commands/speckit.implement.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/commands/speckit.plan.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/commands/speckit.specify.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/commands/speckit.tasks.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/lean/preset.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/commands/speckit.myext.myextcmd.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/commands/speckit.specify.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/preset.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/templates/myext-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/scaffold/templates/spec-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/commands/speckit.specify.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/commands/speckit.wrap-test.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/preset.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/agent-file-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/checklist-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/constitution-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/plan-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/spec-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/presets/self-test/templates/tasks-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/bash/check-prerequisites.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/bash/common.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/bash/create-new-feature.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/bash/setup-plan.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/bash/setup-tasks.sh +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/powershell/check-prerequisites.ps1 +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/powershell/common.ps1 +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/powershell/create-new-feature.ps1 +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/powershell/setup-plan.ps1 +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/scripts/powershell/setup-tasks.ps1 +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/spec-driven.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/spec-kit.code-workspace +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_agent_config.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_assets.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_console.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_github_http.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_init_options.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_invocation_style.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_project.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_utils.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/_version.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/azure_devops.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/base.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/config.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/github.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/authentication/http.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/commands_impl/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/lib/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/lib/project.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/lib/versioning.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/lib/yamlio.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/models/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/models/catalog.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/models/manifest.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/models/records.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/adapters.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/catalog_stack.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/conflict.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/installer.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/packager.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/primitives.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/references.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/resolver.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/bundler/services/validator.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/catalogs.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/commands/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/commands/bundle/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/commands/init.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/extensions/_commands.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integration_runtime.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integration_scaffold.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integration_state.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integration_status.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_commands.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_helpers.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_install_commands.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_migrate_commands.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_query_commands.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/_scaffold_commands.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/agy/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/amp/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/auggie/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/bob/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/catalog.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/claude/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/cline/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/codebuddy/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/codex/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/copilot/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/cursor_agent/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/devin/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/firebender/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/forge/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/gemini/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/generic/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/goose/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/junie/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/kilocode/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/kimi/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/kiro_cli/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/lingma/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/manifest.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/omp/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/opencode/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/pi/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/qodercli/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/qwen/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/rovodev/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/shai/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/tabnine/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/trae/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/vibe/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/zcode/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/integrations/zed/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/presets/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/presets/_commands.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/shared_infra.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/_commands.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/base.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/catalog.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/engine.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/expressions.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/command/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/do_while/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/fan_in/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/fan_out/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/gate/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/if_then/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/init/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/prompt/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/shell/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/switch/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/src/specify_cli/workflows/steps/while_loop/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/checklist-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/analyze.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/checklist.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/clarify.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/constitution.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/converge.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/implement.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/plan.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/specify.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/tasks.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/commands/taskstoissues.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/constitution-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/plan-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/spec-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/tasks-template.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/templates/vscode-settings.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/auth_helpers.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/bundler_helpers.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/conftest.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/contract/test_bundle_cli.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/contract/test_catalog_schema.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/contract/test_manifest_schema.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/bug/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/bug/test_bug_extension.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/git/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/git/test_git_extension.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/test_agent_context_cli_free.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/test_extension_agent_context.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/extensions/test_update_agent_context_feature_json.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/hooks/TESTING.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/hooks/plan.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/hooks/spec.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/hooks/tasks.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/http_helpers.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_catalog_stack.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_init_install.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_install_flow.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_local_install.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_offline.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integration/test_bundler_security_paths.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/__init__.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_base.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_cli.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_extra_args.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_agy.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_amp.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_auggie.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_base_markdown.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_base_skills.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_base_toml.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_bob.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_catalog.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_claude.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_cline.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_codebuddy.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_codex.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_copilot.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_cursor_agent.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_devin.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_firebender.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_forge.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_gemini.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_generic.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_goose.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_junie.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_kilocode.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_kimi.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_kiro_cli.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_lingma.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_omp.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_opencode.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_pi.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_qodercli.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_qwen.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_rovodev.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_scaffold.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_shai.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_state.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_subcommand.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_tabnine.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_trae.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_vibe.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_zcode.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_integration_zed.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/integrations/test_manifest.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/self_upgrade_helpers.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_agent_config_consistency.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_authentication.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_branch_numbering.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_check_prerequisites_paths_only.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_check_tool.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_cli_version.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_commands_package.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_console_imports.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_extension_registration.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_extension_update_hardening.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_github_http.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_github_workflows.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_init_dir.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_init_dir_cli.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_live_transient_windows.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_merge.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_presets.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_ps1_encoding.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_registrar_path_traversal.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_self_upgrade_detection.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_self_upgrade_execution.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_self_upgrade_guidance.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_self_upgrade_verification.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_setup_plan_feature_json.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_setup_plan_no_overwrite.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_setup_tasks.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_shared_infra_integrity.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_timestamp_branches.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_upgrade.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_utils.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_utils_assets_imports.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_version_imports.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_workflow_run_without_project.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/test_workflows.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_adapters.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_conflict.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_packager.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_primitives.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_records.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_references.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_resolver.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_validator.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/tests/unit/test_bundler_versioning.py +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/ARCHITECTURE.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/PUBLISHING.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/README.md +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/catalog.community.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/catalog.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/speckit/workflow.yml +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/workflows/step-catalog.community.json +0 -0
- {specify_cli-0.12.5 → specify_cli-0.12.6}/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.6] - 2026-07-07
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- fix(bundler): validate catalog URLs in `catalog add` (HTTPS-only, require host) (#3367)
|
|
10
|
+
- Update Ralph Loop extension to v1.2.1 (#3365)
|
|
11
|
+
- fix extension-local script path rewriting (#3364)
|
|
12
|
+
- Add Charter extension to community catalog (#3363)
|
|
13
|
+
- feat(scripts): add Python check-prerequisites PoC (#3302)
|
|
14
|
+
- test: reduce registry manifest test repetition (#3146)
|
|
15
|
+
- fix(integrations): hermes honors SPECKIT_INTEGRATION_HERMES_EXTRA_ARGS (#3346)
|
|
16
|
+
- fix(extensions): coerce non-mapping YAML config roots to {} in ConfigManager (#3345)
|
|
17
|
+
- fix(yaml): pin goose recipe prompt block-scalar indentation (#3343)
|
|
18
|
+
- chore: release 0.12.5, begin 0.12.6.dev0 development (#3381)
|
|
19
|
+
|
|
5
20
|
## [0.12.5] - 2026-07-06
|
|
6
21
|
|
|
7
22
|
### Changed
|
|
@@ -42,6 +42,7 @@ The following community-contributed extensions are available in [`catalog.commun
|
|
|
42
42
|
| Bugfix Workflow | Structured bugfix workflow — capture bugs, trace to spec artifacts, and patch specs surgically | `process` | Read+Write | [spec-kit-bugfix](https://github.com/Quratulain-bilal/spec-kit-bugfix) |
|
|
43
43
|
| Canon | Adds canon-driven (baseline-driven) workflows: spec-first, code-first, spec-drift. Requires Canon Core preset installation. | `process` | Read+Write | [spec-kit-canon](https://github.com/maximiliamus/spec-kit-canon/tree/master/extension) |
|
|
44
44
|
| Catalog CI | Automated validation for spec-kit community catalog entries — structure, URLs, diffs, and linting | `process` | Read-only | [spec-kit-catalog-ci](https://github.com/Quratulain-bilal/spec-kit-catalog-ci) |
|
|
45
|
+
| Charter | Compose modular project constitutions from shared fragment registries. Centralize governance rules, select per-project fragments, track upstream changes, and keep multi-project setups consistent. | `process` | Read+Write | [spec-kit-charter](https://github.com/Fyloss/spec-kit-charter) |
|
|
45
46
|
| CI Guard | Spec compliance gates for CI/CD — verify specs exist, check drift, and block merges on gaps | `process` | Read-only | [spec-kit-ci-guard](https://github.com/Quratulain-bilal/spec-kit-ci-guard) |
|
|
46
47
|
| Checkpoint Extension | Commit the changes made during the middle of the implementation, so you don't end up with just one very large commit at the end | `code` | Read+Write | [spec-kit-checkpoint](https://github.com/aaronrsun/spec-kit-checkpoint) |
|
|
47
48
|
| Cleanup Extension | Post-implementation quality gate that reviews changes, fixes small issues (scout rule), creates tasks for medium issues, and generates analysis for large issues | `code` | Read+Write | [spec-kit-cleanup](https://github.com/dsrednicki/spec-kit-cleanup) |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": "1.0",
|
|
3
|
-
"updated_at": "2026-07-
|
|
3
|
+
"updated_at": "2026-07-06T00:00:00Z",
|
|
4
4
|
"catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.community.json",
|
|
5
5
|
"extensions": {
|
|
6
6
|
"aide": {
|
|
@@ -670,6 +670,40 @@
|
|
|
670
670
|
"created_at": "2026-04-11T18:00:00Z",
|
|
671
671
|
"updated_at": "2026-04-11T18:00:00Z"
|
|
672
672
|
},
|
|
673
|
+
"charter": {
|
|
674
|
+
"name": "Charter",
|
|
675
|
+
"id": "charter",
|
|
676
|
+
"description": "Compose modular project constitutions from shared fragment registries. Centralize governance rules, select per-project fragments, track upstream changes, and keep multi-project setups consistent.",
|
|
677
|
+
"author": "Fyloss",
|
|
678
|
+
"version": "0.3.1",
|
|
679
|
+
"download_url": "https://github.com/Fyloss/spec-kit-charter/archive/refs/tags/v0.3.1.zip",
|
|
680
|
+
"repository": "https://github.com/Fyloss/spec-kit-charter",
|
|
681
|
+
"homepage": "https://github.com/Fyloss/spec-kit-charter",
|
|
682
|
+
"documentation": "https://github.com/Fyloss/spec-kit-charter/tree/master/docs",
|
|
683
|
+
"changelog": "https://github.com/Fyloss/spec-kit-charter/blob/master/CHANGELOG.md",
|
|
684
|
+
"license": "MIT",
|
|
685
|
+
"category": "process",
|
|
686
|
+
"effect": "read-write",
|
|
687
|
+
"requires": {
|
|
688
|
+
"speckit_version": ">=0.11.9"
|
|
689
|
+
},
|
|
690
|
+
"provides": {
|
|
691
|
+
"commands": 5,
|
|
692
|
+
"hooks": 1
|
|
693
|
+
},
|
|
694
|
+
"tags": [
|
|
695
|
+
"constitution",
|
|
696
|
+
"governance",
|
|
697
|
+
"modular",
|
|
698
|
+
"fragments",
|
|
699
|
+
"registry"
|
|
700
|
+
],
|
|
701
|
+
"verified": false,
|
|
702
|
+
"downloads": 0,
|
|
703
|
+
"stars": 0,
|
|
704
|
+
"created_at": "2026-07-06T00:00:00Z",
|
|
705
|
+
"updated_at": "2026-07-06T00:00:00Z"
|
|
706
|
+
},
|
|
673
707
|
"ci-guard": {
|
|
674
708
|
"name": "CI Guard",
|
|
675
709
|
"id": "ci-guard",
|
|
@@ -2679,8 +2713,8 @@
|
|
|
2679
2713
|
"id": "ralph",
|
|
2680
2714
|
"description": "Autonomous implementation loop using AI agent CLI",
|
|
2681
2715
|
"author": "Rubiss",
|
|
2682
|
-
"version": "1.
|
|
2683
|
-
"download_url": "https://github.com/Rubiss-Projects/spec-kit-ralph/archive/refs/tags/v1.
|
|
2716
|
+
"version": "1.2.1",
|
|
2717
|
+
"download_url": "https://github.com/Rubiss-Projects/spec-kit-ralph/archive/refs/tags/v1.2.1.zip",
|
|
2684
2718
|
"repository": "https://github.com/Rubiss-Projects/spec-kit-ralph",
|
|
2685
2719
|
"homepage": "https://github.com/Rubiss-Projects/spec-kit-ralph",
|
|
2686
2720
|
"documentation": "https://github.com/Rubiss-Projects/spec-kit-ralph/blob/main/README.md",
|
|
@@ -2689,7 +2723,7 @@
|
|
|
2689
2723
|
"category": "code",
|
|
2690
2724
|
"effect": "read-write",
|
|
2691
2725
|
"requires": {
|
|
2692
|
-
"speckit_version": ">=0.
|
|
2726
|
+
"speckit_version": ">=0.8.5",
|
|
2693
2727
|
"tools": [
|
|
2694
2728
|
{
|
|
2695
2729
|
"name": "copilot",
|
|
@@ -2699,6 +2733,10 @@
|
|
|
2699
2733
|
"name": "codex",
|
|
2700
2734
|
"required": false
|
|
2701
2735
|
},
|
|
2736
|
+
{
|
|
2737
|
+
"name": "claude",
|
|
2738
|
+
"required": false
|
|
2739
|
+
},
|
|
2702
2740
|
{
|
|
2703
2741
|
"name": "git",
|
|
2704
2742
|
"required": true
|
|
@@ -2714,13 +2752,14 @@
|
|
|
2714
2752
|
"automation",
|
|
2715
2753
|
"loop",
|
|
2716
2754
|
"copilot",
|
|
2717
|
-
"codex"
|
|
2755
|
+
"codex",
|
|
2756
|
+
"claude"
|
|
2718
2757
|
],
|
|
2719
2758
|
"verified": false,
|
|
2720
2759
|
"downloads": 0,
|
|
2721
2760
|
"stars": 0,
|
|
2722
2761
|
"created_at": "2026-03-09T00:00:00Z",
|
|
2723
|
-
"updated_at": "2026-
|
|
2762
|
+
"updated_at": "2026-07-06T00:00:00Z"
|
|
2724
2763
|
},
|
|
2725
2764
|
"reconcile": {
|
|
2726
2765
|
"name": "Reconcile Extension",
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Consolidated prerequisite checking script."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import sys
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
from common import FeaturePaths, format_speckit_command, get_feature_paths
|
|
13
|
+
except ImportError: # pragma: no cover - direct execution from unusual cwd
|
|
14
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
15
|
+
from common import FeaturePaths, format_speckit_command, get_feature_paths
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _json_line(payload: object) -> str:
|
|
19
|
+
return json.dumps(payload, ensure_ascii=False, separators=(",", ":")) + "\n"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
HELP_TEXT = """Usage: check_prerequisites.py [OPTIONS]
|
|
23
|
+
|
|
24
|
+
Consolidated prerequisite checking for Spec-Driven Development workflow.
|
|
25
|
+
|
|
26
|
+
OPTIONS:
|
|
27
|
+
--json Output in JSON format
|
|
28
|
+
--require-tasks Require tasks.md to exist (for implementation phase)
|
|
29
|
+
--include-tasks Include tasks.md in AVAILABLE_DOCS list
|
|
30
|
+
--paths-only Only output path variables (no prerequisite validation)
|
|
31
|
+
--help, -h Show this help message
|
|
32
|
+
|
|
33
|
+
EXAMPLES:
|
|
34
|
+
# Check task prerequisites (plan.md required)
|
|
35
|
+
./check_prerequisites.py --json
|
|
36
|
+
|
|
37
|
+
# Check implementation prerequisites (plan.md + tasks.md required)
|
|
38
|
+
./check_prerequisites.py --json --require-tasks --include-tasks
|
|
39
|
+
|
|
40
|
+
# Get feature paths only (no validation)
|
|
41
|
+
./check_prerequisites.py --paths-only
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass(frozen=True)
|
|
47
|
+
class Args:
|
|
48
|
+
json_mode: bool = False
|
|
49
|
+
require_tasks: bool = False
|
|
50
|
+
include_tasks: bool = False
|
|
51
|
+
paths_only: bool = False
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _parse_args(argv: list[str]) -> Args:
|
|
55
|
+
json_mode = False
|
|
56
|
+
require_tasks = False
|
|
57
|
+
include_tasks = False
|
|
58
|
+
paths_only = False
|
|
59
|
+
|
|
60
|
+
for arg in argv:
|
|
61
|
+
if arg == "--json":
|
|
62
|
+
json_mode = True
|
|
63
|
+
elif arg == "--require-tasks":
|
|
64
|
+
require_tasks = True
|
|
65
|
+
elif arg == "--include-tasks":
|
|
66
|
+
include_tasks = True
|
|
67
|
+
elif arg == "--paths-only":
|
|
68
|
+
paths_only = True
|
|
69
|
+
elif arg in {"--help", "-h"}:
|
|
70
|
+
sys.stdout.write(HELP_TEXT)
|
|
71
|
+
raise SystemExit(0)
|
|
72
|
+
else:
|
|
73
|
+
print(
|
|
74
|
+
f"ERROR: Unknown option '{arg}'. Use --help for usage information.",
|
|
75
|
+
file=sys.stderr,
|
|
76
|
+
)
|
|
77
|
+
raise SystemExit(1)
|
|
78
|
+
|
|
79
|
+
return Args(
|
|
80
|
+
json_mode=json_mode,
|
|
81
|
+
require_tasks=require_tasks,
|
|
82
|
+
include_tasks=include_tasks,
|
|
83
|
+
paths_only=paths_only,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _dir_has_entries(path: Path) -> bool:
|
|
88
|
+
try:
|
|
89
|
+
return path.is_dir() and any(path.iterdir())
|
|
90
|
+
except OSError:
|
|
91
|
+
return False
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _available_docs(paths: FeaturePaths, include_tasks: bool) -> list[str]:
|
|
95
|
+
docs: list[str] = []
|
|
96
|
+
if paths.research.is_file():
|
|
97
|
+
docs.append("research.md")
|
|
98
|
+
if paths.data_model.is_file():
|
|
99
|
+
docs.append("data-model.md")
|
|
100
|
+
if _dir_has_entries(paths.contracts_dir):
|
|
101
|
+
docs.append("contracts/")
|
|
102
|
+
if paths.quickstart.is_file():
|
|
103
|
+
docs.append("quickstart.md")
|
|
104
|
+
if include_tasks and paths.tasks.is_file():
|
|
105
|
+
docs.append("tasks.md")
|
|
106
|
+
return docs
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _print_paths_only(paths: FeaturePaths, json_mode: bool) -> None:
|
|
110
|
+
if json_mode:
|
|
111
|
+
sys.stdout.write(
|
|
112
|
+
_json_line(
|
|
113
|
+
{
|
|
114
|
+
"REPO_ROOT": str(paths.repo_root),
|
|
115
|
+
"BRANCH": paths.current_branch,
|
|
116
|
+
"FEATURE_DIR": str(paths.feature_dir),
|
|
117
|
+
"FEATURE_SPEC": str(paths.feature_spec),
|
|
118
|
+
"IMPL_PLAN": str(paths.impl_plan),
|
|
119
|
+
"TASKS": str(paths.tasks),
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
print(f"REPO_ROOT: {paths.repo_root}")
|
|
126
|
+
print(f"BRANCH: {paths.current_branch}")
|
|
127
|
+
print(f"FEATURE_DIR: {paths.feature_dir}")
|
|
128
|
+
print(f"FEATURE_SPEC: {paths.feature_spec}")
|
|
129
|
+
print(f"IMPL_PLAN: {paths.impl_plan}")
|
|
130
|
+
print(f"TASKS: {paths.tasks}")
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _check_file(path: Path, description: str) -> None:
|
|
134
|
+
marker = "✓" if path.is_file() else "✗"
|
|
135
|
+
print(f" {marker} {description}")
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _check_dir(path: Path, description: str) -> None:
|
|
139
|
+
marker = "✓" if _dir_has_entries(path) else "✗"
|
|
140
|
+
print(f" {marker} {description}")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _print_text_results(paths: FeaturePaths, include_tasks: bool) -> None:
|
|
144
|
+
print(f"FEATURE_DIR:{paths.feature_dir}")
|
|
145
|
+
print("AVAILABLE_DOCS:")
|
|
146
|
+
_check_file(paths.research, "research.md")
|
|
147
|
+
_check_file(paths.data_model, "data-model.md")
|
|
148
|
+
_check_dir(paths.contracts_dir, "contracts/")
|
|
149
|
+
_check_file(paths.quickstart, "quickstart.md")
|
|
150
|
+
if include_tasks:
|
|
151
|
+
_check_file(paths.tasks, "tasks.md")
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def main(argv: list[str] | None = None) -> int:
|
|
155
|
+
args = _parse_args(list(argv if argv is not None else sys.argv[1:]))
|
|
156
|
+
|
|
157
|
+
try:
|
|
158
|
+
paths = get_feature_paths(
|
|
159
|
+
no_persist=args.paths_only,
|
|
160
|
+
script_file=Path(__file__),
|
|
161
|
+
)
|
|
162
|
+
except SystemExit as exc:
|
|
163
|
+
if exc.code == 0:
|
|
164
|
+
return 0
|
|
165
|
+
print("ERROR: Failed to resolve feature paths", file=sys.stderr)
|
|
166
|
+
return int(exc.code) if isinstance(exc.code, int) else 1
|
|
167
|
+
|
|
168
|
+
if args.paths_only:
|
|
169
|
+
_print_paths_only(paths, args.json_mode)
|
|
170
|
+
return 0
|
|
171
|
+
|
|
172
|
+
if not paths.feature_dir.is_dir():
|
|
173
|
+
print(f"ERROR: Feature directory not found: {paths.feature_dir}", file=sys.stderr)
|
|
174
|
+
print(
|
|
175
|
+
f"Run {format_speckit_command('specify', paths.repo_root)} first to create the feature structure.",
|
|
176
|
+
file=sys.stderr,
|
|
177
|
+
)
|
|
178
|
+
return 1
|
|
179
|
+
|
|
180
|
+
if not paths.impl_plan.is_file():
|
|
181
|
+
print(f"ERROR: plan.md not found in {paths.feature_dir}", file=sys.stderr)
|
|
182
|
+
print(
|
|
183
|
+
f"Run {format_speckit_command('plan', paths.repo_root)} first to create the implementation plan.",
|
|
184
|
+
file=sys.stderr,
|
|
185
|
+
)
|
|
186
|
+
return 1
|
|
187
|
+
|
|
188
|
+
if args.require_tasks and not paths.tasks.is_file():
|
|
189
|
+
print(f"ERROR: tasks.md not found in {paths.feature_dir}", file=sys.stderr)
|
|
190
|
+
print(
|
|
191
|
+
f"Run {format_speckit_command('tasks', paths.repo_root)} first to create the task list.",
|
|
192
|
+
file=sys.stderr,
|
|
193
|
+
)
|
|
194
|
+
return 1
|
|
195
|
+
|
|
196
|
+
docs = _available_docs(paths, args.include_tasks)
|
|
197
|
+
if args.json_mode:
|
|
198
|
+
sys.stdout.write(
|
|
199
|
+
_json_line({"FEATURE_DIR": str(paths.feature_dir), "AVAILABLE_DOCS": docs})
|
|
200
|
+
)
|
|
201
|
+
else:
|
|
202
|
+
_print_text_results(paths, args.include_tasks)
|
|
203
|
+
return 0
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
if __name__ == "__main__":
|
|
207
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""Shared helpers for Spec Kit Python scripts."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _trim_trailing_separators(value: Path) -> str:
|
|
13
|
+
text = str(value)
|
|
14
|
+
while len(text) > 1 and text.endswith((os.sep, "/")):
|
|
15
|
+
text = text[:-1]
|
|
16
|
+
return text
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def find_specify_root(start_dir: Path | None = None) -> Path | None:
|
|
20
|
+
current = (start_dir or Path.cwd()).resolve()
|
|
21
|
+
while True:
|
|
22
|
+
if (current / ".specify").is_dir():
|
|
23
|
+
return current
|
|
24
|
+
parent = current.parent
|
|
25
|
+
if parent == current:
|
|
26
|
+
return None
|
|
27
|
+
current = parent
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def resolve_specify_init_dir() -> Path:
|
|
31
|
+
raw = os.environ.get("SPECIFY_INIT_DIR", "")
|
|
32
|
+
candidate = Path(raw)
|
|
33
|
+
if not candidate.is_absolute():
|
|
34
|
+
candidate = Path.cwd() / candidate
|
|
35
|
+
try:
|
|
36
|
+
init_root = candidate.resolve(strict=True)
|
|
37
|
+
except OSError:
|
|
38
|
+
print(
|
|
39
|
+
f"ERROR: SPECIFY_INIT_DIR does not point to an existing directory: {raw}",
|
|
40
|
+
file=sys.stderr,
|
|
41
|
+
)
|
|
42
|
+
raise SystemExit(1)
|
|
43
|
+
if not init_root.is_dir():
|
|
44
|
+
print(
|
|
45
|
+
f"ERROR: SPECIFY_INIT_DIR does not point to an existing directory: {raw}",
|
|
46
|
+
file=sys.stderr,
|
|
47
|
+
)
|
|
48
|
+
raise SystemExit(1)
|
|
49
|
+
if not (init_root / ".specify").is_dir():
|
|
50
|
+
print(
|
|
51
|
+
"ERROR: SPECIFY_INIT_DIR is not a Spec Kit project "
|
|
52
|
+
f"(no .specify/ directory): {init_root}",
|
|
53
|
+
file=sys.stderr,
|
|
54
|
+
)
|
|
55
|
+
raise SystemExit(1)
|
|
56
|
+
return init_root
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_repo_root(script_file: Path | None = None) -> Path:
|
|
60
|
+
if os.environ.get("SPECIFY_INIT_DIR"):
|
|
61
|
+
return resolve_specify_init_dir()
|
|
62
|
+
|
|
63
|
+
specify_root = find_specify_root()
|
|
64
|
+
if specify_root is not None:
|
|
65
|
+
return specify_root
|
|
66
|
+
|
|
67
|
+
if script_file is not None:
|
|
68
|
+
script_root = find_specify_root(script_file.resolve().parent)
|
|
69
|
+
if script_root is not None:
|
|
70
|
+
return script_root
|
|
71
|
+
|
|
72
|
+
# Installed scripts live at .specify/scripts/python/<script>.py.
|
|
73
|
+
return script_file.resolve().parents[3]
|
|
74
|
+
return Path.cwd().resolve()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_current_branch() -> str:
|
|
78
|
+
return os.environ.get("SPECIFY_FEATURE", "")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def read_feature_json_feature_directory(repo_root: Path) -> str:
|
|
82
|
+
feature_json = repo_root / ".specify" / "feature.json"
|
|
83
|
+
if not feature_json.is_file():
|
|
84
|
+
return ""
|
|
85
|
+
try:
|
|
86
|
+
data = json.loads(feature_json.read_text(encoding="utf-8"))
|
|
87
|
+
except (OSError, json.JSONDecodeError):
|
|
88
|
+
return ""
|
|
89
|
+
value = data.get("feature_directory") if isinstance(data, dict) else None
|
|
90
|
+
return value if isinstance(value, str) else ""
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _json_dump(data: dict[str, str]) -> str:
|
|
94
|
+
return json.dumps(data, ensure_ascii=False, separators=(",", ":")) + "\n"
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def persist_feature_json(repo_root: Path, feature_dir_value: str) -> None:
|
|
98
|
+
value = feature_dir_value
|
|
99
|
+
try:
|
|
100
|
+
relative = Path(value)
|
|
101
|
+
if relative.is_absolute():
|
|
102
|
+
try:
|
|
103
|
+
value = relative.resolve().relative_to(repo_root.resolve()).as_posix()
|
|
104
|
+
except ValueError:
|
|
105
|
+
value = str(relative)
|
|
106
|
+
except OSError:
|
|
107
|
+
pass
|
|
108
|
+
|
|
109
|
+
current = read_feature_json_feature_directory(repo_root)
|
|
110
|
+
if current == value:
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
specify_dir = repo_root / ".specify"
|
|
114
|
+
specify_dir.mkdir(parents=True, exist_ok=True)
|
|
115
|
+
(specify_dir / "feature.json").write_text(
|
|
116
|
+
_json_dump({"feature_directory": value}),
|
|
117
|
+
encoding="utf-8",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@dataclass(frozen=True)
|
|
122
|
+
class FeaturePaths:
|
|
123
|
+
repo_root: Path
|
|
124
|
+
current_branch: str
|
|
125
|
+
feature_dir: Path
|
|
126
|
+
feature_spec: Path
|
|
127
|
+
impl_plan: Path
|
|
128
|
+
tasks: Path
|
|
129
|
+
research: Path
|
|
130
|
+
data_model: Path
|
|
131
|
+
quickstart: Path
|
|
132
|
+
contracts_dir: Path
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def get_feature_paths(
|
|
136
|
+
*, no_persist: bool = False, script_file: Path | None = None
|
|
137
|
+
) -> FeaturePaths:
|
|
138
|
+
repo_root = get_repo_root(script_file)
|
|
139
|
+
current_branch = get_current_branch()
|
|
140
|
+
|
|
141
|
+
feature_dir_raw = os.environ.get("SPECIFY_FEATURE_DIRECTORY", "")
|
|
142
|
+
if feature_dir_raw:
|
|
143
|
+
feature_dir = Path(feature_dir_raw)
|
|
144
|
+
if not feature_dir.is_absolute():
|
|
145
|
+
feature_dir = repo_root / feature_dir
|
|
146
|
+
if not no_persist:
|
|
147
|
+
persist_feature_json(repo_root, feature_dir_raw)
|
|
148
|
+
elif (repo_root / ".specify" / "feature.json").is_file():
|
|
149
|
+
stored = read_feature_json_feature_directory(repo_root)
|
|
150
|
+
if not stored:
|
|
151
|
+
print(
|
|
152
|
+
"ERROR: Feature directory not found. Set SPECIFY_FEATURE_DIRECTORY "
|
|
153
|
+
"or ensure .specify/feature.json contains feature_directory.",
|
|
154
|
+
file=sys.stderr,
|
|
155
|
+
)
|
|
156
|
+
raise SystemExit(1)
|
|
157
|
+
feature_dir = Path(stored)
|
|
158
|
+
if not feature_dir.is_absolute():
|
|
159
|
+
feature_dir = repo_root / feature_dir
|
|
160
|
+
else:
|
|
161
|
+
print(
|
|
162
|
+
"ERROR: Feature directory not found. Set SPECIFY_FEATURE_DIRECTORY "
|
|
163
|
+
"or run the specify command to create .specify/feature.json.",
|
|
164
|
+
file=sys.stderr,
|
|
165
|
+
)
|
|
166
|
+
raise SystemExit(1)
|
|
167
|
+
|
|
168
|
+
if not current_branch:
|
|
169
|
+
current_branch = Path(_trim_trailing_separators(feature_dir)).name
|
|
170
|
+
|
|
171
|
+
return FeaturePaths(
|
|
172
|
+
repo_root=repo_root,
|
|
173
|
+
current_branch=current_branch,
|
|
174
|
+
feature_dir=feature_dir,
|
|
175
|
+
feature_spec=feature_dir / "spec.md",
|
|
176
|
+
impl_plan=feature_dir / "plan.md",
|
|
177
|
+
tasks=feature_dir / "tasks.md",
|
|
178
|
+
research=feature_dir / "research.md",
|
|
179
|
+
data_model=feature_dir / "data-model.md",
|
|
180
|
+
quickstart=feature_dir / "quickstart.md",
|
|
181
|
+
contracts_dir=feature_dir / "contracts",
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def get_invoke_separator(repo_root: Path) -> str:
|
|
186
|
+
integration_json = repo_root / ".specify" / "integration.json"
|
|
187
|
+
if not integration_json.is_file():
|
|
188
|
+
return "."
|
|
189
|
+
try:
|
|
190
|
+
state = json.loads(integration_json.read_text(encoding="utf-8"))
|
|
191
|
+
key = state.get("default_integration") or state.get("integration") or ""
|
|
192
|
+
settings = state.get("integration_settings")
|
|
193
|
+
if isinstance(key, str) and isinstance(settings, dict):
|
|
194
|
+
entry = settings.get(key)
|
|
195
|
+
if isinstance(entry, dict) and entry.get("invoke_separator") in {".", "-"}:
|
|
196
|
+
return entry["invoke_separator"]
|
|
197
|
+
except (OSError, json.JSONDecodeError):
|
|
198
|
+
pass
|
|
199
|
+
return "."
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def format_speckit_command(command_name: str, repo_root: Path) -> str:
|
|
203
|
+
separator = get_invoke_separator(repo_root)
|
|
204
|
+
name = command_name.lstrip("/")
|
|
205
|
+
if name.startswith("speckit."):
|
|
206
|
+
name = name[len("speckit.") :]
|
|
207
|
+
elif name.startswith("speckit-"):
|
|
208
|
+
name = name[len("speckit-") :]
|
|
209
|
+
name = name.replace(".", separator)
|
|
210
|
+
return f"/speckit{separator}{name}"
|