specify-cli 1.0.13__tar.gz → 1.1.1__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-1.0.13 → specify_cli-1.1.1}/.github/ISSUE_TEMPLATE/extension_submission.yml +2 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/ISSUE_TEMPLATE/preset_submission.yml +2 -2
- specify_cli-1.1.1/.github/scripts/validate_community_preset.py +532 -0
- specify_cli-1.1.1/.github/security-audit-requirements.txt +832 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/add-community-bundle.lock.yml +3 -3
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/add-community-bundle.md +12 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/add-community-extension.lock.yml +3 -3
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/add-community-extension.md +12 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/add-community-preset.lock.yml +14 -4
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/add-community-preset.md +106 -24
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/bug-assess.lock.yml +3 -3
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/bug-assess.md +9 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/bug-fix.lock.yml +3 -3
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/bug-fix.md +9 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/bug-test.lock.yml +3 -3
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/bug-test.md +9 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/codeql.yml +2 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/feature-assess.lock.yml +3 -3
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/feature-assess.md +10 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/CHANGELOG.md +50 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/PKG-INFO +3 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/bundles/catalog.community.json +4 -4
- {specify_cli-1.0.13 → specify_cli-1.1.1}/design/integration.md +3 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/community/extensions.md +3 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/community/friends.md +1 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/community/presets.md +1 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/installation.md +6 -3
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/agentic-sdd.md +1 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/authentication.md +25 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/bundles.md +6 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/core.md +38 -10
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/extensions.md +54 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/integrations.md +70 -2
- specify_cli-1.1.1/docs/reference/mcp.md +50 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/overview.md +8 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/presets.md +80 -7
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/workflows.md +263 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/toc.yml +2 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/EXTENSION-PUBLISHING-GUIDE.md +5 -4
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/catalog.community.json +106 -13
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/catalog.json +1 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/github/README.md +8 -10
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/github/extension.yml +1 -1
- specify_cli-1.1.1/newsletters/2026-September.md +118 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/PUBLISHING.md +8 -6
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/catalog.community.json +35 -6
- {specify_cli-1.0.13 → specify_cli-1.1.1}/pyproject.toml +3 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/bash/common.sh +1 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/bash/create-new-feature.sh +98 -21
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/powershell/create-new-feature.ps1 +40 -18
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/python/create_new_feature.py +23 -8
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/__init__.py +10 -9
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/agents.py +43 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/authentication/github_http.py +107 -45
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/authentication/http.py +3 -3
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/adapters.py +6 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/catalog_config.py +8 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/installer.py +44 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/primitives.py +78 -12
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/versioning.py +14 -1
- specify_cli-1.1.1/src/specify_cli/command_mcp.py +17 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/command_version.py +56 -17
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/events/__init__.py +15 -3
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/__init__.py +827 -74
- specify_cli-1.1.1/src/specify_cli/extensions/_catalog_versions.py +153 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/_command_update_transaction.py +42 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/command_add.py +70 -3
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/command_disable.py +12 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/command_enable.py +39 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/command_info.py +33 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/__init__.py +24 -3
- specify_cli-1.1.1/src/specify_cli/integrations/_catalog_versions.py +149 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_info.py +31 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/generic/__init__.py +32 -0
- specify_cli-1.1.1/src/specify_cli/integrations/shai/__init__.py +50 -0
- specify_cli-1.1.1/src/specify_cli/mcp_server/__init__.py +5 -0
- specify_cli-1.1.1/src/specify_cli/mcp_server/_worker.py +6 -0
- specify_cli-1.1.1/src/specify_cli/mcp_server/catalog.py +134 -0
- specify_cli-1.1.1/src/specify_cli/mcp_server/executor.py +115 -0
- specify_cli-1.1.1/src/specify_cli/mcp_server/server.py +86 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/_catalog.py +145 -43
- specify_cli-1.1.1/src/specify_cli/presets/_catalog_versions.py +152 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/_manager.py +27 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/_manager_skills.py +3 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/command_add.py +68 -4
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/command_info.py +27 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/shared_infra.py +55 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/__init__.py +20 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/_commands.py +63 -59
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/catalog/_domain.py +28 -5
- specify_cli-1.1.1/src/specify_cli/workflows/catalog/_versions.py +129 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_add.py +18 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_info.py +29 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/engine.py +9 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/expressions.py +215 -14
- specify_cli-1.1.1/src/specify_cli/workflows/step/_helpers.py +49 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/catalog/_domain.py +115 -20
- specify_cli-1.1.1/src/specify_cli/workflows/step/catalog/_versions.py +178 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/command/__init__.py +6 -2
- specify_cli-1.1.1/src/specify_cli/workflows/step/command_add.py +591 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/command_info.py +61 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/command_remove.py +53 -21
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/init/__init__.py +26 -1
- specify_cli-1.1.1/src/specify_cli/workflows/step/installer.py +852 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/prompt/__init__.py +5 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/switch/__init__.py +2 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/github/test_github_extension.py +22 -13
- specify_cli-1.1.1/tests/integrations/test_integration_generic.py +2780 -0
- specify_cli-1.1.1/tests/integrations/test_integration_shai.py +59 -0
- specify_cli-1.1.1/tests/lock_helpers.py +67 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/parity_helpers.py +2 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/authentication/test_github_http.py +145 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/helpers.py +6 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_catalog_config.py +36 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_command_info.py +54 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_command_install.py +44 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_command_validate.py +23 -2
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_installer.py +105 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_primitives.py +231 -6
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_versioning.py +9 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/events/test_events.py +34 -0
- specify_cli-1.1.1/tests/specify_cli/extensions/test_catalog_versions.py +639 -0
- specify_cli-1.1.1/tests/specify_cli/integrations/test_catalog_versions.py +239 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_info.py +61 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_install.py +7 -0
- specify_cli-1.1.1/tests/specify_cli/mcp_server/__init__.py +1 -0
- specify_cli-1.1.1/tests/specify_cli/mcp_server/test_catalog.py +43 -0
- specify_cli-1.1.1/tests/specify_cli/mcp_server/test_executor.py +210 -0
- specify_cli-1.1.1/tests/specify_cli/mcp_server/test_server.py +106 -0
- specify_cli-1.1.1/tests/specify_cli/mcp_server/test_stdio.py +78 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_catalog.py +12 -4
- specify_cli-1.1.1/tests/specify_cli/presets/test_catalog_versions.py +981 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_command_add.py +75 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_command_init.py +2 -2
- specify_cli-1.1.1/tests/specify_cli/test_command_mcp.py +35 -0
- specify_cli-1.1.1/tests/specify_cli/test_command_version.py +187 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/step/catalog/test_command_list.py +1 -3
- specify_cli-1.1.1/tests/specify_cli/workflows/step/catalog/test_registry.py +33 -0
- specify_cli-1.1.1/tests/specify_cli/workflows/step/test_catalog_versions.py +218 -0
- specify_cli-1.1.1/tests/specify_cli/workflows/step/test_command_add.py +1867 -0
- specify_cli-1.1.1/tests/specify_cli/workflows/step/test_command_info.py +144 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/step/test_command_list.py +3 -5
- specify_cli-1.1.1/tests/specify_cli/workflows/step/test_command_remove.py +427 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/step/test_command_search.py +3 -5
- specify_cli-1.1.1/tests/specify_cli/workflows/step/test_installer.py +1196 -0
- specify_cli-1.1.1/tests/specify_cli/workflows/test_catalog_versions.py +472 -0
- specify_cli-1.1.1/tests/specify_cli/workflows/test_custom_steps.py +49 -0
- specify_cli-1.1.1/tests/test_community_preset_validation.py +735 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_create_new_feature_python_parity.py +532 -54
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_github_workflows.py +92 -7
- specify_cli-1.1.1/tests/test_shared_infra_lock.py +118 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_workflows.py +644 -5
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/unit/test_condition_expression_block.py +32 -7
- {specify_cli-1.0.13 → specify_cli-1.1.1}/workflows/ARCHITECTURE.md +18 -1
- {specify_cli-1.0.13 → specify_cli-1.1.1}/workflows/README.md +18 -1
- specify_cli-1.0.13/.github/security-audit-requirements.txt +0 -249
- specify_cli-1.0.13/src/specify_cli/integrations/shai/__init__.py +0 -21
- specify_cli-1.0.13/src/specify_cli/workflows/step/_helpers.py +0 -107
- specify_cli-1.0.13/src/specify_cli/workflows/step/command_add.py +0 -376
- specify_cli-1.0.13/tests/integrations/test_integration_generic.py +0 -615
- specify_cli-1.0.13/tests/integrations/test_integration_shai.py +0 -10
- specify_cli-1.0.13/tests/specify_cli/test_command_version.py +0 -113
- specify_cli-1.0.13/tests/specify_cli/workflows/step/test_command_add.py +0 -606
- specify_cli-1.0.13/tests/specify_cli/workflows/step/test_command_info.py +0 -63
- specify_cli-1.0.13/tests/specify_cli/workflows/step/test_command_remove.py +0 -94
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.devcontainer/devcontainer.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.devcontainer/post-create.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.editorconfig +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.gitattributes +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/CODEOWNERS +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/ISSUE_TEMPLATE/agent_request.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/ISSUE_TEMPLATE/bundle_submission.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/aw/actions-lock.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/dependabot.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/scripts/check_extension_version_bump.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/scripts/check_security_requirements.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/skills/add-community-extension/SKILL.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/skills/code-review/SKILL.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/RELEASE-PROCESS.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/catalog-assign.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/docs.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/extension-version-guard.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/lint.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/publish-pypi.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/release-trigger.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/release.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/security.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/stale.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.github/workflows/test.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.gitignore +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.markdownlint-cli2.jsonc +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.pre-commit-config.yaml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/.zenodo.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/AGENTS.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/CITATION.cff +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/CODE_OF_CONDUCT.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/CONTRIBUTING.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/DEVELOPMENT.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/LICENSE +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/README.ja.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/README.zh-CN.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/SECURITY.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/SUPPORT.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/bundles/assess/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/bundles/assess/bundle.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/bundles/bugfix/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/bundles/bugfix/bundle.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/bundles/catalog.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/design/cli.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/design/workflow-step.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/.gitignore +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/community/bundles.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/community/overview.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/community/walkthroughs.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/concepts/complex-features.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/concepts/sdd.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/concepts/spec-of-specs.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/concepts/spec-persistence.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/docfx.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/guides/agentic-sdlc.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/guides/assessment.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/guides/bugfix.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/guides/contract-driven-development.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/guides/customization.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/guides/evolving-specs.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/guides/existing-projects.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/guides/monorepo.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/history.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/images/spec-kit-logo.webp +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/index.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/install/air-gapped.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/install/one-time.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/install/pipx.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/install/pypi.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/install/uv.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/local-development.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/quickstart.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/agentic-assessment.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/agentic-bugfix.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/reference/artifacts.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/template/public/main.css +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/docs/upgrade.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/examples/bundles/business-analyst/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/examples/bundles/business-analyst/bundle.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/examples/bundles/developer/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/examples/bundles/developer/bundle.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/examples/bundles/product-manager/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/examples/bundles/product-manager/bundle.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/examples/bundles/security-researcher/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/examples/bundles/security-researcher/bundle.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/EXTENSION-API-REFERENCE.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/EXTENSION-DEVELOPMENT-GUIDE.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/EXTENSION-USER-GUIDE.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/RFC-EXTENSION-SYSTEM.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/agent-context/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/agent-context/agent-context-config.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/agent-context/agent-context-defaults.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/agent-context/commands/speckit.agent-context.update.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/agent-context/extension.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/agent-context/scripts/bash/update-agent-context.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/agent-context/scripts/python/update_agent_context.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/assess/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/assess/commands/speckit.assess.decide.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/assess/commands/speckit.assess.define.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/assess/commands/speckit.assess.intake.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/assess/commands/speckit.assess.research.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/assess/commands/speckit.assess.shape.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/assess/extension.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/bug/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/bug/commands/speckit.bug.assess.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/bug/commands/speckit.bug.fix.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/bug/commands/speckit.bug.test.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/bug/extension.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/commands/speckit.git.commit.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/commands/speckit.git.feature.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/commands/speckit.git.initialize.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/commands/speckit.git.remote.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/commands/speckit.git.validate.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/config-template.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/extension.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/git-config.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/bash/auto-commit.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/bash/create-new-feature-branch.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/bash/git-common.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/bash/initialize-repo.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/powershell/auto-commit.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/powershell/create-new-feature-branch.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/powershell/git-common.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/powershell/initialize-repo.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/python/auto_commit.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/python/create_new_feature_branch.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/python/git_common.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/git/scripts/python/initialize_repo.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/github/commands/speckit.github.taskstoissues.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/github/scripts/bash/resolve-tasks.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/github/scripts/powershell/resolve-tasks.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/github/scripts/python/resolve_tasks.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/selftest/commands/selftest.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/selftest/extension.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/template/.gitignore +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/template/CHANGELOG.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/template/EXAMPLE-README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/template/LICENSE +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/template/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/template/commands/example.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/template/config-template.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/extensions/template/extension.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/integrations/CONTRIBUTING.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/integrations/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/integrations/catalog.community.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/integrations/catalog.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/media/bootstrap-claude-code.gif +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/media/logo_large.webp +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/media/logo_small.webp +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/media/spec-kit-video-header.jpg +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/media/specify_cli.gif +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/newsletters/2026-April.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/newsletters/2026-August.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/newsletters/2026-February.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/newsletters/2026-July.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/newsletters/2026-June.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/newsletters/2026-March.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/newsletters/2026-May.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/ARCHITECTURE.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/catalog.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/constitution-sync/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/constitution-sync/commands/speckit.constitution.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/constitution-sync/preset.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/lean/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/lean/commands/speckit.constitution.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/lean/commands/speckit.implement.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/lean/commands/speckit.plan.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/lean/commands/speckit.specify.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/lean/commands/speckit.tasks.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/lean/preset.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/scaffold/README.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/scaffold/commands/speckit.myext.myextcmd.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/scaffold/commands/speckit.specify.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/scaffold/preset.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/scaffold/templates/myext-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/scaffold/templates/spec-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/self-test/commands/speckit.specify.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/self-test/commands/speckit.wrap-test.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/self-test/preset.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/self-test/templates/checklist-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/self-test/templates/constitution-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/self-test/templates/plan-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/self-test/templates/spec-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/presets/self-test/templates/tasks-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/bash/check-prerequisites.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/bash/resolve-template.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/bash/setup-plan.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/bash/setup-tasks.sh +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/powershell/check-prerequisites.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/powershell/common.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/powershell/resolve-template.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/powershell/setup-plan.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/powershell/setup-tasks.ps1 +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/python/check_prerequisites.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/python/common.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/python/resolve_template.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/python/setup_plan.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/scripts/python/setup_tasks.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/spec-driven.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/spec-kit.code-workspace +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_agent_config.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_assets.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_console.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_download_security.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_init_options.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_installed_list_json.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_invocation_style.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_project.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_toml_string.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_utils.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/_version.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/artifacts/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/artifacts/_commands.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/artifacts/_identifiers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/artifacts/catalog.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/artifacts/command_info.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/artifacts/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/artifacts/command_lookup.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/artifacts/models.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/artifacts/resolution.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/authentication/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/authentication/azure_devops.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/authentication/base.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/authentication/bitbucket.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/authentication/config.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/authentication/github.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundler.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/_commands.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/catalog/command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/catalog/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/catalog/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/catalog_stack.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/catalogs.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/command_build.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/command_info.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/command_init.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/command_install.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/command_update.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/command_validate.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/conflict.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/manifest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/packager.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/project.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/records.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/references.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/resolver.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/sources.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/validator.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/bundles/yamlio.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/catalogs.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/command_check.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/command_init.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/events/command_run.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/_command_update_artifacts.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/_command_update_discovery.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/_commands.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/catalog/_helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/catalog/command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/catalog/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/catalog/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/command_set_priority.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/extensions/command_update.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integration_runtime.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integration_state.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integration_status.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/_command_scaffold_generation.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/_command_upgrade_layout.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/_commands.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/_helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/agy/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/alquimia/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/amp/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/auggie/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/base.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/bob/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/catalog/command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/catalog/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/catalog/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/claude/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/cline/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/codebuddy/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/codex/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_code/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_install.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_scaffold.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_status.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_switch.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_uninstall.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_upgrade.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/command_use.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/copilot/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/cursor_agent/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/devin/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/docker_agent/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/droid/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/dsh/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/firebender/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/forge/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/gemini/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/goose/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/grok/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/hermes/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/junie/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/kilocode/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/kimi/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/kiro_cli/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/lingma/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/manifest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/mcode/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/muse/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/omp/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/opencode/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/pi/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/qodercli/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/qwen/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/rovodev/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/tabnine/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/trae/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/vibe/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/zcode/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/integrations/zed/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/_commands.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/_manager_commands.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/_manifest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/_registry.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/_resolver.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/catalog/command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/catalog/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/catalog/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/command_disable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/command_enable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/command_resolve.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/command_set_priority.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/presets/command_update.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/selfs/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/selfs/command_check.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/selfs/command_upgrade.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/_command_resume_state.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/_command_run_ownership.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/base.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/catalog/command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/catalog/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/catalog/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_disable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_enable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_resolve.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_resume.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_run.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_status.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/command_update.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/command_disable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/command_enable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/command_set_priority.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/composer.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/layer_sources.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/merge.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/operations.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/resolver.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/overlay/schema.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/catalog/command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/catalog/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/catalog/command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/do_while/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/fan_in/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/fan_out/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/gate/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/if_then/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/shell/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/slot/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/src/specify_cli/workflows/step/while_loop/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/checklist-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/commands/analyze.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/commands/checklist.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/commands/clarify.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/commands/constitution.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/commands/converge.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/commands/implement.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/commands/plan.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/commands/specify.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/commands/tasks.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/commands/taskstoissues.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/constitution-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/plan-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/spec-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/tasks-template.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/templates/vscode-settings.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/conftest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/contract/test_bundled_extension_update_delivery.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/contract/test_bundled_extension_versions.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/contract/test_catalog_schema.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/contract/test_extension_version_guard_script.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/contract/test_firstparty_bundle_catalog_consistency.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/contract/test_manifest_schema.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/contract/test_wheel_bundled_presets.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/contract/test_wheel_bundled_workflows.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/contract/test_wheel_core_pack_scripts.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/assess/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/assess/test_assess_extension.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/bug/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/bug/test_bug_extension.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/git/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/git/test_git_extension.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/git/test_git_extension_python_parity.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/github/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/test_agent_context_cli_free.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/test_extension_agent_context.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/test_update_agent_context_feature_json.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/extensions/test_update_agent_context_python_parity.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/hooks/TESTING.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/hooks/plan.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/hooks/spec.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/hooks/tasks.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/http_helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integration/test_preset_update_workflow.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/conftest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_base.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_cli.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_extra_args.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_home_isolation.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_agy.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_alquimia.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_amp.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_auggie.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_base_markdown.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_base_skills.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_base_toml.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_base_yaml.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_bob.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_claude.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_cline.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_codebuddy.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_codex.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_command_code.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_copilot.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_cursor_agent.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_devin.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_docker_agent.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_droid.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_dsh.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_firebender.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_forge.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_gemini.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_goose.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_grok.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_hermes.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_junie.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_kilocode.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_kimi.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_kiro_cli.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_lingma.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_mcode.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_muse.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_omp.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_opencode.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_pi.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_qodercli.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_qwen.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_rovodev.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_state.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_tabnine.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_trae.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_vibe.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_zcode.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_integration_zed.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_manifest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_registry.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/integrations/test_skill_frontmatter_quoting.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/artifacts/conftest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/artifacts/helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/artifacts/test_catalog.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/artifacts/test_catalog_parity.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/artifacts/test_command_info.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/artifacts/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/artifacts/test_command_lookup.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/artifacts/test_registration.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/authentication/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/authentication/helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/authentication/test_authentication.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/_command_helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/catalog/test_command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/catalog/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/catalog/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/conftest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_adapters.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_bundles.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_catalog_stack.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_command_build.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_command_init.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_command_update.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_commands.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_conflict.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_offline.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_packager.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_records.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_references.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_resolver.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_security_paths.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_sources.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_validator.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/bundles/test_yamlio.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/events/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/events/test_command_run.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/_helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/catalog/test_command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/catalog/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/catalog/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/conftest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_add_path_traversal.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_disable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_enable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_info.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_set_priority.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_update.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_update_artifacts.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_update_discovery.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/extensions/test_command_update_transaction.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/_catalog_helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/_helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/_scaffold_helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/catalog/test_command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/catalog/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/catalog/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/conftest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_catalog.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_scaffold.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_scaffold_generation.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_status.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_switch.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_uninstall.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_upgrade.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_upgrade_layout.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_command_use.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_lifecycle.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/integrations/test_registration.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/_fixtures.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/_helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/catalog/test_command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/catalog/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/catalog/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/conftest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_command_disable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_command_enable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_command_info.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_command_resolve.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_command_set_priority.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_command_update.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_domain_exports.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_manager.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_manager_commands.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_manager_skills.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_manifest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_registration.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_registry.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/presets/test_resolver.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/self_upgrade_helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/selfs/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/selfs/test_command_check.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/selfs/test_command_upgrade.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_agent_config.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_check_tool.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_command_check.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_root_version_callback.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_version_detection.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_version_execution.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_version_guidance.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_version_imports.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_version_release.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/test_version_verification.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/catalog/test_command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/catalog/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/catalog/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/conftest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/helpers.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/overlay/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/overlay/test_command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/overlay/test_command_disable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/overlay/test_command_enable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/overlay/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/overlay/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/overlay/test_command_set_priority.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/step/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/step/catalog/__init__.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/step/catalog/test_command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/step/catalog/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_add.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_disable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_enable.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_info.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_list.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_remove.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_resolve.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_resume.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_resume_state.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_run.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_run_ownership.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_search.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_status.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/specify_cli/workflows/test_command_update.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_agent_config_consistency.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_branch_numbering.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_bug_fix_workflow.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_catalog_trust_docs.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_check_prerequisites_paths_only.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_check_prerequisites_python_parity.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_clarify_stage_gate.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_command_template_hooks.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_command_template_py_scripts.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_console_imports.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_constitution_template_sync_report.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_converge_template_scaffold.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_download_security.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_extension_registration.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_extension_skills.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_extensions.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_init_dir.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_init_dir_cli.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_installed_list_json.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_live_transient_windows.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_merge.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_post_process.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_presets.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_ps1_encoding.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_registrar_path_traversal.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_resolve_template_python_parity.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_security_workflow.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_setup_plan_feature_json.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_setup_plan_no_overwrite.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_setup_plan_python_parity.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_setup_tasks.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_setup_tasks_python_parity.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_shared_infra_gitignore.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_shared_infra_integrity.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_skill_placeholder_py.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_specify_no_persist.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_specify_template_numbering.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_tasks_template_constraints.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_timestamp_branches.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_utils.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/test_utils_assets_imports.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/workflows/conftest.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/workflows/test_bundled_bugfix_assess_workflows.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/workflows/test_bundled_speckit_workflow.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/workflows/test_overlay_composer.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/workflows/test_overlay_layer_sources.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/workflows/test_overlay_merge.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/workflows/test_overlay_schema.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/workflows/test_resolver_integration.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/tests/workflows/test_slot_step.py +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/workflows/PUBLISHING.md +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/workflows/assess/workflow.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/workflows/bugfix/workflow.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/workflows/catalog.community.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/workflows/catalog.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/workflows/speckit/workflow.yml +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/workflows/step-catalog.community.json +0 -0
- {specify_cli-1.0.13 → specify_cli-1.1.1}/workflows/step-catalog.json +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
name: Extension Submission
|
|
2
2
|
description: Submit your extension to the Spec Kit catalog
|
|
3
3
|
title: "[Extension]: Add "
|
|
4
|
-
labels: ["
|
|
4
|
+
labels: ["triage-must-have"]
|
|
5
5
|
body:
|
|
6
6
|
- type: markdown
|
|
7
7
|
attributes:
|
|
@@ -14,7 +14,7 @@ body:
|
|
|
14
14
|
- Create a GitHub release with a version tag (e.g., v1.0.0)
|
|
15
15
|
- Test installation: `specify extension add <extension-name> --from <your-release-url>`
|
|
16
16
|
|
|
17
|
-
**After submitting:**
|
|
17
|
+
**After submitting:** GitHub automatically applies the `triage-must-have` intake verdict. A maintainer separately applies the `extension-submission` label during issue triage, which starts the automated catalog validation. You don't need to apply any label or ask for one.
|
|
18
18
|
|
|
19
19
|
- type: input
|
|
20
20
|
id: extension-id
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
name: Preset Submission
|
|
2
2
|
description: Submit your preset to the Spec Kit preset catalog
|
|
3
3
|
title: "[Preset]: Add "
|
|
4
|
-
labels: ["
|
|
4
|
+
labels: ["triage-must-have"]
|
|
5
5
|
body:
|
|
6
6
|
- type: markdown
|
|
7
7
|
attributes:
|
|
@@ -14,7 +14,7 @@ body:
|
|
|
14
14
|
- Create a GitHub release with a version tag (e.g., v1.0.0)
|
|
15
15
|
- Test installation from the release archive: `specify preset add --from <download-url>`
|
|
16
16
|
|
|
17
|
-
**After submitting:**
|
|
17
|
+
**After submitting:** GitHub automatically applies the `triage-must-have` intake verdict. A maintainer separately applies the `preset-submission` label during issue triage, which starts the automated catalog validation. You don't need to apply any label or ask for one.
|
|
18
18
|
|
|
19
19
|
- type: input
|
|
20
20
|
id: preset-id
|
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
"""Verify a community preset submission and its generated catalog changes.
|
|
2
|
+
|
|
3
|
+
Exit 1: confirmed submission mismatch; 2: check blocked; 3: generated files
|
|
4
|
+
need repair. The workflow decides labels and PR creation from these outcomes.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import argparse
|
|
8
|
+
import hashlib
|
|
9
|
+
import json
|
|
10
|
+
import re
|
|
11
|
+
import sys
|
|
12
|
+
import zipfile
|
|
13
|
+
from datetime import datetime, timezone
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from urllib.parse import urlsplit
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
import yaml
|
|
19
|
+
except ImportError:
|
|
20
|
+
print("BLOCKED: PyYAML is unavailable; cannot inspect published preset.yml")
|
|
21
|
+
sys.exit(2)
|
|
22
|
+
|
|
23
|
+
MAX_MANIFEST_COUNT = 100
|
|
24
|
+
MAX_MANIFEST_SIZE = 1024 * 1024
|
|
25
|
+
MAX_TOTAL_MANIFEST_SIZE = 10 * 1024 * 1024
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SubmissionMismatch(Exception):
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Blocked(Exception):
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class GeneratedError(Exception):
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def read_text(
|
|
41
|
+
path: Path, context: str, error_type: type[Exception] = Blocked
|
|
42
|
+
) -> str:
|
|
43
|
+
try:
|
|
44
|
+
return path.read_text(encoding="utf-8")
|
|
45
|
+
except (OSError, UnicodeError) as exc:
|
|
46
|
+
raise error_type(f"cannot read {context} ({path}): {exc}") from exc
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def read_json(path: Path, context: str, error_type: type[Exception]) -> dict:
|
|
50
|
+
try:
|
|
51
|
+
value = json.loads(read_text(path, context, error_type))
|
|
52
|
+
except json.JSONDecodeError as exc:
|
|
53
|
+
raise error_type(f"{context} is invalid JSON: {exc}") from exc
|
|
54
|
+
if not isinstance(value, dict):
|
|
55
|
+
raise error_type(f"{context} must be a JSON object")
|
|
56
|
+
return value
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def field(issue: dict, key: str) -> str:
|
|
60
|
+
value = issue.get(key)
|
|
61
|
+
if not isinstance(value, str) or not value.strip():
|
|
62
|
+
raise SubmissionMismatch(f"missing or invalid issue field: {key}")
|
|
63
|
+
return value.strip()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def csv_values(value: str) -> list[str]:
|
|
67
|
+
return [part.strip() for part in value.split(",") if part.strip()]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def repository_parts(url: str) -> tuple[str, str]:
|
|
71
|
+
parsed = urlsplit(url)
|
|
72
|
+
match = re.fullmatch(r"/([^/]+)/([^/]+)/?", parsed.path)
|
|
73
|
+
if parsed.scheme != "https" or parsed.netloc.lower() != "github.com" or not match:
|
|
74
|
+
raise SubmissionMismatch(f"invalid GitHub repository URL: {url}")
|
|
75
|
+
return match[1].lower(), match[2].lower()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def release_tag(issue: dict) -> str:
|
|
79
|
+
owner, repo = repository_parts(field(issue, "repository"))
|
|
80
|
+
url = field(issue, "download_url")
|
|
81
|
+
parsed = urlsplit(url)
|
|
82
|
+
prefix = f"/{owner}/{repo}/"
|
|
83
|
+
path = parsed.path
|
|
84
|
+
if parsed.scheme != "https" or parsed.netloc.lower() != "github.com":
|
|
85
|
+
raise SubmissionMismatch(f"download URL is not a GitHub URL: {url}")
|
|
86
|
+
if not path.lower().startswith(prefix):
|
|
87
|
+
raise SubmissionMismatch("download URL does not belong to the submitted repository")
|
|
88
|
+
suffix = path[len(prefix):]
|
|
89
|
+
archive = re.fullmatch(r"archive/refs/tags/([^/]+)\.zip", suffix)
|
|
90
|
+
release = re.fullmatch(r"releases/download/([^/]+)/[^/]+\.zip", suffix)
|
|
91
|
+
if not (archive or release) or parsed.query or parsed.fragment:
|
|
92
|
+
raise SubmissionMismatch(f"download URL is not a pinned ZIP release: {url}")
|
|
93
|
+
tag = (archive or release)[1]
|
|
94
|
+
version = field(issue, "version")
|
|
95
|
+
if not re.fullmatch(r"\d+\.\d+\.\d+", version) or not re.fullmatch(
|
|
96
|
+
rf"(?:v?{re.escape(version)}|.+-v?{re.escape(version)})", tag
|
|
97
|
+
):
|
|
98
|
+
raise SubmissionMismatch(
|
|
99
|
+
f"release tag {tag!r} does not match submitted version {version!r}"
|
|
100
|
+
)
|
|
101
|
+
return tag
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def normalized_release_asset(filename: str) -> str:
|
|
105
|
+
return re.sub(
|
|
106
|
+
r"(?<!\d)v?\d+\.\d+\.\d+(?!\d)",
|
|
107
|
+
"{version}",
|
|
108
|
+
filename,
|
|
109
|
+
flags=re.IGNORECASE,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def published_manifest(archive_path: Path, preset_id: str) -> tuple[dict, bool]:
|
|
114
|
+
try:
|
|
115
|
+
with zipfile.ZipFile(archive_path) as archive:
|
|
116
|
+
matching = []
|
|
117
|
+
invalid = []
|
|
118
|
+
manifests = [
|
|
119
|
+
member for member in archive.infolist()
|
|
120
|
+
if not member.is_dir()
|
|
121
|
+
and member.filename.rsplit("/", 1)[-1] == "preset.yml"
|
|
122
|
+
]
|
|
123
|
+
if len(manifests) > MAX_MANIFEST_COUNT:
|
|
124
|
+
raise SubmissionMismatch(
|
|
125
|
+
f"archive contains more than {MAX_MANIFEST_COUNT} preset.yml files"
|
|
126
|
+
)
|
|
127
|
+
total_size = sum(member.file_size for member in manifests)
|
|
128
|
+
if total_size > MAX_TOTAL_MANIFEST_SIZE:
|
|
129
|
+
raise SubmissionMismatch(
|
|
130
|
+
"archive preset.yml files exceed the "
|
|
131
|
+
f"{MAX_TOTAL_MANIFEST_SIZE // (1024 * 1024)} MiB total limit"
|
|
132
|
+
)
|
|
133
|
+
for member in manifests:
|
|
134
|
+
try:
|
|
135
|
+
if member.file_size > MAX_MANIFEST_SIZE:
|
|
136
|
+
raise ValueError("preset.yml exceeds 1 MiB")
|
|
137
|
+
with archive.open(member) as stream:
|
|
138
|
+
data = yaml.safe_load(stream.read().decode("utf-8"))
|
|
139
|
+
except (yaml.YAMLError, UnicodeError, ValueError) as exc:
|
|
140
|
+
invalid.append(f"{member.filename}: {exc}")
|
|
141
|
+
continue
|
|
142
|
+
if isinstance(data, dict) and isinstance(data.get("preset"), dict):
|
|
143
|
+
if data["preset"].get("id") == preset_id:
|
|
144
|
+
matching.append((member.filename, data))
|
|
145
|
+
except FileNotFoundError as exc:
|
|
146
|
+
raise Blocked(f"downloaded archive is unavailable at {archive_path}: {exc}") from exc
|
|
147
|
+
except PermissionError as exc:
|
|
148
|
+
raise Blocked(f"cannot read downloaded archive at {archive_path}: {exc}") from exc
|
|
149
|
+
except OSError as exc:
|
|
150
|
+
raise Blocked(f"cannot read downloaded archive at {archive_path}: {exc}") from exc
|
|
151
|
+
except (zipfile.BadZipFile, EOFError) as exc:
|
|
152
|
+
raise SubmissionMismatch(f"downloaded archive is not a readable ZIP: {exc}") from exc
|
|
153
|
+
if len(matching) != 1:
|
|
154
|
+
if not matching and invalid:
|
|
155
|
+
raise SubmissionMismatch(
|
|
156
|
+
f"no published preset.yml for {preset_id!r}; invalid manifests: "
|
|
157
|
+
+ "; ".join(invalid)
|
|
158
|
+
)
|
|
159
|
+
raise SubmissionMismatch(
|
|
160
|
+
f"expected one published preset.yml for {preset_id!r}, found {len(matching)}"
|
|
161
|
+
)
|
|
162
|
+
return matching[0][1], len(manifests) == 1
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def required_extensions(manifest: dict) -> list[str]:
|
|
166
|
+
requires = manifest.get("requires")
|
|
167
|
+
if not isinstance(requires, dict):
|
|
168
|
+
raise SubmissionMismatch("published preset.yml has no requires mapping")
|
|
169
|
+
extensions = requires.get("extensions", [])
|
|
170
|
+
if not isinstance(extensions, list):
|
|
171
|
+
raise SubmissionMismatch("published requires.extensions must be a list")
|
|
172
|
+
result = []
|
|
173
|
+
for item in extensions:
|
|
174
|
+
if isinstance(item, str):
|
|
175
|
+
result.append(item)
|
|
176
|
+
elif isinstance(item, dict) and isinstance(item.get("id"), str):
|
|
177
|
+
if item.get("required", True) is not False:
|
|
178
|
+
result.append(item["id"])
|
|
179
|
+
else:
|
|
180
|
+
raise SubmissionMismatch("invalid published requires.extensions entry")
|
|
181
|
+
return result
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def check_readme(text: str, issue: dict, *, single_preset_archive: bool) -> None:
|
|
185
|
+
expected = field(issue, "download_url")
|
|
186
|
+
preset_id = field(issue, "preset_id")
|
|
187
|
+
owner, repo = repository_parts(field(issue, "repository"))
|
|
188
|
+
submitted_scope = re.fullmatch(r"(.+)-v?\d+\.\d+\.\d+", release_tag(issue))
|
|
189
|
+
accepted_scopes = {preset_id}
|
|
190
|
+
if submitted_scope:
|
|
191
|
+
accepted_scopes.add(submitted_scope[1])
|
|
192
|
+
expected_path = urlsplit(expected).path.split("/")
|
|
193
|
+
accepted = False
|
|
194
|
+
for match in re.finditer(
|
|
195
|
+
r"(?<![\w-])specify[ \t]+preset[ \t]+add[ \t]+"
|
|
196
|
+
r"(?P<option>--from|--dev|[a-z][a-z0-9-]*)"
|
|
197
|
+
r"(?:[ \t]+(?P<value>[^\s`]+))?",
|
|
198
|
+
text,
|
|
199
|
+
):
|
|
200
|
+
option = match["option"]
|
|
201
|
+
raw_value = match["value"] or ""
|
|
202
|
+
if option == "--from":
|
|
203
|
+
value = raw_value.strip("'\"<>(),.;")
|
|
204
|
+
if value == expected:
|
|
205
|
+
accepted = True
|
|
206
|
+
continue
|
|
207
|
+
parsed = urlsplit(value)
|
|
208
|
+
parts = parsed.path.split("/")
|
|
209
|
+
tag = (
|
|
210
|
+
parts[5] if len(parts) > 5 and parts[3] == "releases"
|
|
211
|
+
else parts[6].removesuffix(".zip")
|
|
212
|
+
if len(parts) > 6 and parts[3] == "archive"
|
|
213
|
+
else ""
|
|
214
|
+
)
|
|
215
|
+
scoped = re.fullmatch(r"(.+)-v?\d+\.\d+\.\d+", tag)
|
|
216
|
+
same_repository = (
|
|
217
|
+
parsed.netloc.lower() == "github.com"
|
|
218
|
+
and parsed.path.lower().startswith(f"/{owner}/{repo}/")
|
|
219
|
+
)
|
|
220
|
+
# An unscoped tag alone does not identify a preset in a monorepo.
|
|
221
|
+
same_release_asset = (
|
|
222
|
+
len(expected_path) > 6
|
|
223
|
+
and expected_path[3:5] == ["releases", "download"]
|
|
224
|
+
and len(parts) > 6
|
|
225
|
+
and parts[3:5] == ["releases", "download"]
|
|
226
|
+
and normalized_release_asset(expected_path[6])
|
|
227
|
+
== normalized_release_asset(parts[6])
|
|
228
|
+
)
|
|
229
|
+
unscoped_archive = (
|
|
230
|
+
single_preset_archive
|
|
231
|
+
and submitted_scope is None
|
|
232
|
+
and expected_path[3:6] == ["archive", "refs", "tags"]
|
|
233
|
+
and parts[3:6] == ["archive", "refs", "tags"]
|
|
234
|
+
)
|
|
235
|
+
if (scoped and scoped[1] in accepted_scopes) or (
|
|
236
|
+
same_repository and not scoped and (same_release_asset or unscoped_archive)
|
|
237
|
+
):
|
|
238
|
+
raise SubmissionMismatch(
|
|
239
|
+
f"README --from URL for {preset_id} differs from Download URL: {value}"
|
|
240
|
+
)
|
|
241
|
+
elif option == "--dev":
|
|
242
|
+
value = raw_value.strip("'\"")
|
|
243
|
+
if value and not value.startswith("-"):
|
|
244
|
+
accepted = True
|
|
245
|
+
elif option == preset_id:
|
|
246
|
+
accepted = True
|
|
247
|
+
if not accepted:
|
|
248
|
+
raise SubmissionMismatch(
|
|
249
|
+
"README has no valid specify preset add command for the submitted preset"
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def count_items(value: str) -> int:
|
|
254
|
+
return sum(line.lstrip().startswith("- ") for line in value.splitlines())
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def expected_values(issue: dict, manifest: dict, digest: str) -> dict:
|
|
258
|
+
pack = manifest.get("preset")
|
|
259
|
+
requires = manifest.get("requires")
|
|
260
|
+
if not isinstance(pack, dict) or not isinstance(requires, dict):
|
|
261
|
+
raise SubmissionMismatch("published preset.yml lacks preset or requires metadata")
|
|
262
|
+
extension_ids = csv_values(issue.get("required_extensions", ""))
|
|
263
|
+
actual_extensions = required_extensions(manifest)
|
|
264
|
+
comparisons = {
|
|
265
|
+
"preset.id": (pack.get("id"), field(issue, "preset_id")),
|
|
266
|
+
"preset.version": (pack.get("version"), field(issue, "version")),
|
|
267
|
+
"requires.speckit_version": (
|
|
268
|
+
requires.get("speckit_version"), field(issue, "speckit_version")
|
|
269
|
+
),
|
|
270
|
+
"requires.extensions": (sorted(actual_extensions), sorted(extension_ids)),
|
|
271
|
+
}
|
|
272
|
+
for name, (actual, expected) in comparisons.items():
|
|
273
|
+
if actual != expected:
|
|
274
|
+
raise SubmissionMismatch(
|
|
275
|
+
f"published {name} {actual!r} differs from submitted {expected!r}"
|
|
276
|
+
)
|
|
277
|
+
dependencies = {"speckit_version": field(issue, "speckit_version")}
|
|
278
|
+
if extension_ids:
|
|
279
|
+
dependencies["extensions"] = extension_ids
|
|
280
|
+
provided = {
|
|
281
|
+
"templates": count_items(field(issue, "templates_provided")),
|
|
282
|
+
"commands": count_items(field(issue, "commands_provided")),
|
|
283
|
+
}
|
|
284
|
+
scripts = issue.get("scripts_count", "0")
|
|
285
|
+
if scripts:
|
|
286
|
+
try:
|
|
287
|
+
number = int(scripts)
|
|
288
|
+
except (ValueError, TypeError) as exc:
|
|
289
|
+
raise SubmissionMismatch("scripts_count must be a non-negative integer") from exc
|
|
290
|
+
if number < 0:
|
|
291
|
+
raise SubmissionMismatch("scripts_count must be a non-negative integer")
|
|
292
|
+
if number:
|
|
293
|
+
provided["scripts"] = number
|
|
294
|
+
return {
|
|
295
|
+
"id": field(issue, "preset_id"),
|
|
296
|
+
"name": field(issue, "preset_name"),
|
|
297
|
+
"version": field(issue, "version"),
|
|
298
|
+
"description": field(issue, "description"),
|
|
299
|
+
"author": field(issue, "author"),
|
|
300
|
+
"repository": field(issue, "repository"),
|
|
301
|
+
"homepage": field(issue, "repository"),
|
|
302
|
+
"download_url": field(issue, "download_url"),
|
|
303
|
+
"sha256": digest,
|
|
304
|
+
"documentation": field(issue, "documentation"),
|
|
305
|
+
"license": field(issue, "license"),
|
|
306
|
+
"requires": dependencies,
|
|
307
|
+
"provides": provided,
|
|
308
|
+
"tags": csv_values(field(issue, "tags")),
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def submission(args: argparse.Namespace) -> None:
|
|
313
|
+
issue = read_json(args.issue, "issue input", Blocked)
|
|
314
|
+
release_tag(issue)
|
|
315
|
+
manifest, single_preset_archive = published_manifest(
|
|
316
|
+
args.archive, field(issue, "preset_id")
|
|
317
|
+
)
|
|
318
|
+
check_readme(
|
|
319
|
+
read_text(args.readme, "fetched README"),
|
|
320
|
+
issue,
|
|
321
|
+
single_preset_archive=single_preset_archive,
|
|
322
|
+
)
|
|
323
|
+
try:
|
|
324
|
+
with args.archive.open("rb") as archive:
|
|
325
|
+
digest = hashlib.file_digest(archive, "sha256").hexdigest()
|
|
326
|
+
except OSError as exc:
|
|
327
|
+
raise Blocked(f"cannot hash downloaded archive: {exc}") from exc
|
|
328
|
+
expected = expected_values(issue, manifest, digest)
|
|
329
|
+
catalog = read_json(args.catalog, "original catalog", Blocked)
|
|
330
|
+
entries = catalog.get("presets")
|
|
331
|
+
if not isinstance(entries, dict):
|
|
332
|
+
raise Blocked("original catalog has no presets object")
|
|
333
|
+
previous = entries.get(expected["id"])
|
|
334
|
+
if previous is not None and not isinstance(previous, dict):
|
|
335
|
+
raise Blocked("original catalog entry is not an object")
|
|
336
|
+
if previous is not None and not isinstance(previous.get("created_at"), str):
|
|
337
|
+
raise Blocked("original catalog entry has no created_at to preserve")
|
|
338
|
+
original_rows = documentation_rows(
|
|
339
|
+
read_text(args.docs, "original documentation", Blocked), Blocked
|
|
340
|
+
)
|
|
341
|
+
expected_row = documentation_row(expected)
|
|
342
|
+
previous_row = None
|
|
343
|
+
if previous is not None:
|
|
344
|
+
previous_row = existing_documentation_row(original_rows, previous)
|
|
345
|
+
snapshot = {
|
|
346
|
+
"expected": expected,
|
|
347
|
+
"created_at": previous.get("created_at") if previous else None,
|
|
348
|
+
"expected_timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT00:00:00Z"),
|
|
349
|
+
"documentation": {
|
|
350
|
+
"expected_row_count": original_rows.count(expected_row),
|
|
351
|
+
"previous_row": previous_row,
|
|
352
|
+
"previous_row_count": original_rows.count(previous_row)
|
|
353
|
+
if previous_row is not None else 0,
|
|
354
|
+
},
|
|
355
|
+
}
|
|
356
|
+
try:
|
|
357
|
+
args.snapshot.write_text(json.dumps(snapshot), encoding="utf-8")
|
|
358
|
+
except OSError as exc:
|
|
359
|
+
raise Blocked(f"cannot write verifier snapshot: {exc}") from exc
|
|
360
|
+
print("PASSED: published preset.yml, release tag, README, and issue fields agree")
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def documentation_row(entry: dict) -> str:
|
|
364
|
+
def cell(value: str) -> str:
|
|
365
|
+
return value.replace("\\", r"\\").replace("|", r"\|").replace("\n", " ")
|
|
366
|
+
|
|
367
|
+
provided = entry["provides"]
|
|
368
|
+
quantities = [
|
|
369
|
+
f"{count} {name[:-1] if count == 1 else name}"
|
|
370
|
+
for name, count in provided.items() if count
|
|
371
|
+
]
|
|
372
|
+
dependencies = entry["requires"].get("extensions", [])
|
|
373
|
+
requires = ", ".join(f"{name} extension" for name in dependencies) or "—"
|
|
374
|
+
repo = entry["repository"].rstrip("/").rsplit("/", 1)[-1]
|
|
375
|
+
return (
|
|
376
|
+
f"| {cell(entry['name'])} | {cell(entry['description'])} | "
|
|
377
|
+
f"{', '.join(quantities)} | {requires} | "
|
|
378
|
+
f"[{repo}]({entry['repository']}) |"
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def markdown_table_cells(row: str) -> list[str]:
|
|
383
|
+
cells = []
|
|
384
|
+
cell = []
|
|
385
|
+
escaped = False
|
|
386
|
+
for character in row:
|
|
387
|
+
if escaped:
|
|
388
|
+
if character in ("\\", "|"):
|
|
389
|
+
cell.append(character)
|
|
390
|
+
else:
|
|
391
|
+
cell.extend(("\\", character))
|
|
392
|
+
escaped = False
|
|
393
|
+
elif character == "\\":
|
|
394
|
+
escaped = True
|
|
395
|
+
elif character == "|":
|
|
396
|
+
cells.append("".join(cell).strip())
|
|
397
|
+
cell = []
|
|
398
|
+
else:
|
|
399
|
+
cell.append(character)
|
|
400
|
+
if escaped:
|
|
401
|
+
cell.append("\\")
|
|
402
|
+
cells.append("".join(cell).strip())
|
|
403
|
+
return cells
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def documentation_rows(text: str, error_type: type[Exception]) -> list[str]:
|
|
407
|
+
lines = text.splitlines()
|
|
408
|
+
try:
|
|
409
|
+
start = next(i for i, line in enumerate(lines) if line.startswith("| Preset |"))
|
|
410
|
+
except StopIteration as exc:
|
|
411
|
+
raise error_type("documentation has no Community Presets table") from exc
|
|
412
|
+
rows = []
|
|
413
|
+
for line in lines[start + 2:]:
|
|
414
|
+
if not line.startswith("|"):
|
|
415
|
+
break
|
|
416
|
+
rows.append(line.strip())
|
|
417
|
+
return rows
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def existing_documentation_row(rows: list[str], entry: dict) -> str:
|
|
421
|
+
name = entry.get("name")
|
|
422
|
+
repository = entry.get("repository")
|
|
423
|
+
if not isinstance(name, str) or not isinstance(repository, str):
|
|
424
|
+
raise Blocked("original catalog entry lacks documentation row identity")
|
|
425
|
+
matches = []
|
|
426
|
+
for row in rows:
|
|
427
|
+
cells = markdown_table_cells(row)
|
|
428
|
+
if len(cells) < 3 or cells[1] != name:
|
|
429
|
+
continue
|
|
430
|
+
url_cell = cells[-2] if cells[-1] == "" else cells[-1]
|
|
431
|
+
link = re.fullmatch(r"\[[^\]]*\]\(([^)]+)\)", url_cell)
|
|
432
|
+
if link and link[1].rstrip("/") == repository.rstrip("/"):
|
|
433
|
+
matches.append(row)
|
|
434
|
+
if len(matches) != 1:
|
|
435
|
+
raise Blocked(
|
|
436
|
+
"original documentation must contain exactly one row matching the "
|
|
437
|
+
f"catalog name and repository for {name!r}; found {len(matches)}"
|
|
438
|
+
)
|
|
439
|
+
return matches[0]
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def generated(args: argparse.Namespace) -> None:
|
|
443
|
+
snapshot = read_json(args.snapshot, "verifier snapshot", Blocked)
|
|
444
|
+
expected = snapshot.get("expected")
|
|
445
|
+
if not isinstance(expected, dict) or not isinstance(expected.get("id"), str):
|
|
446
|
+
raise Blocked("verifier snapshot lacks validated expected values")
|
|
447
|
+
expected_timestamp = snapshot.get("expected_timestamp")
|
|
448
|
+
if not isinstance(expected_timestamp, str):
|
|
449
|
+
raise Blocked("verifier snapshot lacks the expected UTC timestamp")
|
|
450
|
+
catalog = read_json(args.catalog, "generated catalog", GeneratedError)
|
|
451
|
+
entries = catalog.get("presets")
|
|
452
|
+
if not isinstance(entries, dict):
|
|
453
|
+
raise GeneratedError("generated catalog has no presets object")
|
|
454
|
+
keys = list(entries)
|
|
455
|
+
if keys != sorted(keys):
|
|
456
|
+
raise GeneratedError("catalog preset IDs are not in alphabetical order")
|
|
457
|
+
entry = entries.get(expected["id"])
|
|
458
|
+
if not isinstance(entry, dict):
|
|
459
|
+
raise GeneratedError(f"catalog is missing entry {expected['id']}")
|
|
460
|
+
for key, value in expected.items():
|
|
461
|
+
if entry.get(key) != value:
|
|
462
|
+
raise GeneratedError(f"catalog {key} does not match validated value: {value!r}")
|
|
463
|
+
if snapshot.get("created_at") is not None:
|
|
464
|
+
if entry.get("created_at") != snapshot["created_at"]:
|
|
465
|
+
raise GeneratedError("catalog created_at was not preserved on update")
|
|
466
|
+
elif entry.get("created_at") != expected_timestamp:
|
|
467
|
+
raise GeneratedError("new catalog created_at does not match the expected UTC date")
|
|
468
|
+
if entry.get("updated_at") != expected_timestamp:
|
|
469
|
+
raise GeneratedError("catalog entry updated_at does not match the expected UTC date")
|
|
470
|
+
if catalog.get("updated_at") != expected_timestamp:
|
|
471
|
+
raise GeneratedError("catalog top-level updated_at does not match the expected UTC date")
|
|
472
|
+
documentation = snapshot.get("documentation")
|
|
473
|
+
if not isinstance(documentation, dict):
|
|
474
|
+
raise Blocked("verifier snapshot lacks original documentation state")
|
|
475
|
+
expected_row_count = documentation.get("expected_row_count")
|
|
476
|
+
previous_row = documentation.get("previous_row")
|
|
477
|
+
previous_row_count = documentation.get("previous_row_count")
|
|
478
|
+
if (
|
|
479
|
+
not isinstance(expected_row_count, int)
|
|
480
|
+
or isinstance(expected_row_count, bool)
|
|
481
|
+
or expected_row_count < 0
|
|
482
|
+
or previous_row is not None and not isinstance(previous_row, str)
|
|
483
|
+
or not isinstance(previous_row_count, int)
|
|
484
|
+
or isinstance(previous_row_count, bool)
|
|
485
|
+
or previous_row_count < 0
|
|
486
|
+
):
|
|
487
|
+
raise Blocked("verifier snapshot has invalid original documentation state")
|
|
488
|
+
rows = documentation_rows(
|
|
489
|
+
read_text(args.docs, "generated documentation", GeneratedError),
|
|
490
|
+
GeneratedError,
|
|
491
|
+
)
|
|
492
|
+
names = [markdown_table_cells(row)[1] for row in rows]
|
|
493
|
+
if names != sorted(names, key=str.casefold):
|
|
494
|
+
raise GeneratedError("documentation preset names are not in alphabetical order")
|
|
495
|
+
expected_row = documentation_row(expected)
|
|
496
|
+
expected_generated_count = expected_row_count + (
|
|
497
|
+
0 if previous_row == expected_row else 1
|
|
498
|
+
)
|
|
499
|
+
if rows.count(expected_row) != expected_generated_count:
|
|
500
|
+
raise GeneratedError(f"documentation row does not match validated values: {expected_row}")
|
|
501
|
+
if previous_row is not None and previous_row != expected_row:
|
|
502
|
+
expected_previous_count = max(0, previous_row_count - 1)
|
|
503
|
+
if rows.count(previous_row) != expected_previous_count:
|
|
504
|
+
raise GeneratedError("previous documentation row was not replaced")
|
|
505
|
+
print("PASSED: generated catalog and documentation match validated submission")
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
def main() -> int:
|
|
509
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
510
|
+
parser.add_argument("phase", choices=("submission", "generated"))
|
|
511
|
+
for name in ("issue", "archive", "readme", "catalog", "docs", "snapshot"):
|
|
512
|
+
parser.add_argument(f"--{name}", required=True, type=Path)
|
|
513
|
+
args = parser.parse_args()
|
|
514
|
+
try:
|
|
515
|
+
if args.phase == "submission":
|
|
516
|
+
submission(args)
|
|
517
|
+
else:
|
|
518
|
+
generated(args)
|
|
519
|
+
except SubmissionMismatch as exc:
|
|
520
|
+
print(f"FAILED: {exc}")
|
|
521
|
+
return 1
|
|
522
|
+
except Blocked as exc:
|
|
523
|
+
print(f"BLOCKED: {exc}")
|
|
524
|
+
return 2
|
|
525
|
+
except GeneratedError as exc:
|
|
526
|
+
print(f"REPAIR: {exc}")
|
|
527
|
+
return 3
|
|
528
|
+
return 0
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
if __name__ == "__main__":
|
|
532
|
+
sys.exit(main())
|