kanon-cli 2.0.1__tar.gz → 2.1.0__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.
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/CHANGELOG.md +89 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/PKG-INFO +9 -8
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/README.md +8 -7
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/catalog-author-guide.md +3 -2
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/catalogs-explained.md +4 -3
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/claude-marketplaces-guide.md +7 -4
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/cli/validate.md +3 -2
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/creating-manifest-repos.md +9 -5
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/list-and-add.md +4 -3
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/pyproject.toml +3 -1
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/__init__.py +1 -1
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/add.py +2 -5
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/catalog.py +12 -10
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/list.py +11 -26
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/catalog_entries.py +2 -6
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/constants.py +0 -1
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/manifest.py +2 -7
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/marketplace_validator.py +3 -3
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/metadata.py +58 -2
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/legacy-catalog-dir/repo-specs/sample.xml +1 -1
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_validate_lifecycle.py +36 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_validate_marketplace.py +29 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_full_user_journey.py +6 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_list_all_versions_malformed_revision_resilience.py +1 -1
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_misc_features.py +0 -4
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_validate_marketplace.py +18 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_mk.py +6 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_tc_validate.py +6 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_va.py +6 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_add.py +2 -2
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_audit_metadata.py +42 -12
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_audit_source_name.py +5 -5
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_list.py +0 -67
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_list_coverage_gaps.py +3 -3
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_manifest.py +12 -38
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_marketplace_validator.py +18 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_metadata.py +101 -0
- kanon_cli-2.0.1/tests/unit/repo/fixtures/.repo_not.present.gitconfig.json +0 -1
- kanon_cli-2.0.1/tests/unit/repo/fixtures/.repo_test.gitconfig.json +0 -56
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.claude/settings.json +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/.devcontainer.postcreate.sh +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/VERSION +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/catalog-entry.json +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/devcontainer-functions.sh +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/devcontainer.json +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/fix-line-endings.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/nix-family-os/README.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/nix-family-os/tinyproxy-daemon.sh +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/nix-family-os/tinyproxy.conf.template +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/postcreate-wrapper.sh +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/project-setup.sh +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/wsl-family-os/README.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/wsl-family-os/tinyproxy-daemon.sh +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.devcontainer/wsl-family-os/tinyproxy.conf.template +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.github/CODEOWNERS +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.github/actions/setup-kanon/action.yml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.github/workflows/codeql-analysis.yml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.github/workflows/main-validation.yml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.github/workflows/pr-validation.yml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.github/workflows/publish.yml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.gitignore +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.markdownlint.json +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.pre-commit-config.yaml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.tool-versions +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/.yamllint +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/CLAUDE.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/CONTRIBUTING.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/LICENSE +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/Makefile +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/architecture.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/catalog-format-versioning.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/cli/catalog-audit.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/cli/doctor.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/cli-reference.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/cli.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/coming-from-pip-npm-cargo.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/configuration.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/contributing.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/creating-packages.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/doctor.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/exit-codes.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/git-auth-setup.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/how-it-works.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/installation.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/integration-testing.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/lifecycle.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/lockfile.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/migrating-existing-kanon-files.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/migration-bootstrap-to-add.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/multi-source-guide.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/outdated-and-why.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/pipeline-integration.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/repo/README.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/repo/internal-fs-layout.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/repo/manifest-format.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/repo/python-support.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/repo/repo-hooks.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/repo/smart-sync.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/repo/windows.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/security-model.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/setup-guide.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/shell-completion.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/test-coverage.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/testing/matrix-traceability.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/troubleshooting.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/url-canonicalization.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/docs/version-resolution.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/git-hooks/pre-commit +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/git-hooks/pre-push +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/link +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/requirements-dev.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/requirements.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/scripts/check_archive_no_duplicates.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/__main__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/cli.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/bootstrap.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/clean.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/completion.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/doctor.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/install.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/outdated.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/remove.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/repo.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/validate.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/commands/why.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/cache.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/cached_catalogs.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/catalog_versions.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/lockfile_names.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/midtoken.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/pep440_filter.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/preamble.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/project_versions.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/sanitize.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/completions/source_names.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/catalog.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/clean.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/cli_args.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/discover.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/include_walker.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/install.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/kanon_hash.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/kanonenv.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/lockfile.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/marketplace.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/remote_url.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/url.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/core/xml_validator.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/color.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/command.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/editor.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/error.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/event_log.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/fetch.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/git_command.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/git_config.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/git_refs.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/git_ssh +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/git_superproject.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/git_trace2_event_log.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/git_trace2_event_log_base.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/hooks/commit-msg +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/hooks/pre-auto-gc +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/hooks.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/main.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/manifest_xml.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/pager.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/platform_utils.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/platform_utils_win32.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/progress.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/project.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/repo +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/repo_logging.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/repo_trace.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/requirements.jsonc +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/ssh.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/abandon.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/branches.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/checkout.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/cherry_pick.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/diff.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/diffmanifests.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/download.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/envsubst.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/forall.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/gc.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/grep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/help.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/info.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/init.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/list.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/manifest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/overview.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/prune.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/rebase.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/selfupdate.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/smartsync.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/stage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/start.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/status.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/sync.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/subcmds/upload.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/version_constraints.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/repo/wrapper.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/utils/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/utils/concurrency.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/utils/levenshtein.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/utils/lock_file_path.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/src/kanon_cli/version.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/conftest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/duplicate-child-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/missing-recommended-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/missing-required-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/multiple-blocks-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/dotted-name-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/hyphenated-name-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/uppercase-name-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-a-1-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-a-2-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-b-1-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-b-2-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/file-url-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/query-string-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/unresolvable-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalog/legacy-catalog-dir/catalog/sample-entry/.kanon +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalogs/zero-pep440-tags/README.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/catalogs/zero-pep440-tags/repo-specs/entry-a/entry-a-marketplace.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/completion/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/completion/expected-bash.sh +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/completion/expected-zsh.sh +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/errors/README.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/errors/conflict-detected.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/errors/entry-not-found.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/errors/lockfile-hash-mismatch.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/errors/lockfile-sha-unreachable.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/errors/missing-catalog-source.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/errors/missing-required-metadata-field.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/errors/source-collision.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/errors/zero-pep440-tags-under-prefix.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/README.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-add.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-catalog-audit.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-catalog.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-clean.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-completion.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-doctor.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-install.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-list.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-outdated.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-remove.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-toplevel.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/help/kanon-why.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/repo/.gitignore +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/repo/README.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/repo/linter-test-bad.invalid-yaml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/repo/linter-test-bad.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/repo/linter-test-bad.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/repo/sample-manifest.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/repo/sample-project-config.json +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/repo/test.gitconfig +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/fixtures/repo/version_constraints_data.json +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/conftest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_argparse_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_argparse_help.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_bootstrap_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_bootstrap_list_and_default_target.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_ci_runs_operator_path_tests.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_clean_lifecycle.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_cli_entry_point.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_completion_snapshots.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_error_snapshots.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_exit_code_matrix.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_groups_filter.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_help_snapshots.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_help_text_contract.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_install_lifecycle.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_install_real_kanon.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_kanon_repo_cli.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_kanon_repo_e2e.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_kanon_repo_lifecycle_journey.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_make_operator_path_targets.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_matrix_traceability_complete.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_provider_agnostic.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_abandon_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_abandon_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_abandon_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_branches_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_branches_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_branches_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_checkout_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_checkout_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_checkout_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_cherry_pick_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_cherry_pick_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_cherry_pick_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_diff_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_diff_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_diff_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_diffmanifests_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_diffmanifests_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_diffmanifests_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_dir_override.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_download_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_download_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_download_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_envsubst_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_envsubst_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_envsubst_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_exit_codes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_forall_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_forall_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_forall_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_gc_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_gc_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_gc_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_grep_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_grep_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_grep_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_help_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_help_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_help_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_info_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_info_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_info_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_init_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_init_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_init_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_init_mirror.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_list_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_list_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_list_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_manifest_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_manifest_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_manifest_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_manifest_revision_as_tag.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_overview_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_overview_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_overview_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_passthrough.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_prune_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_prune_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_prune_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_rebase_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_rebase_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_rebase_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_selfupdate_disabled.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_selfupdate_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_selfupdate_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_selfupdate_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_smartsync_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_smartsync_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_smartsync_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_stage_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_stage_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_stage_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_start_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_start_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_start_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_status_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_status_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_status_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_sync_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_sync_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_sync_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_upload_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_upload_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_repo_upload_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_stdout_stderr_discipline.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_validate_xml_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_validate_xml_repo_root.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/functional/test_zero_source_clean_error.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/conftest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/fixtures/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/fixtures/synthetic/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/fixtures/synthetic/conftest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/fixtures/synthetic/drift.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/fixtures/synthetic/test_synthetic_pytest_fixtures.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/fixtures/synthetic/upgrade_versioned.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/provider_allowlist.txt +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_bug_fixes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_consolidated_constraints_e2e.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_envsubst_integration.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_import_functional.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_linkfile_copyfile.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_linkfile_exclude_journey.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_manifest_parsing.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_process_isolation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_repo_module_smoke.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_repo_pipeline.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_repo_run_lifecycle.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_repo_sync_lifecycle.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_version_constraints_integration.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_annotation_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_contactinfo_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_copyfile_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_default_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_extend_project_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_include_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_linkfile_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_manifest_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_manifest_server_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_notice_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_project_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_remote_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_remove_project_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_repo_hooks_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_submanifest_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/repo/test_xml_superproject_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_add_core.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_add_dry_run.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_add_marketplace_flag.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_add_zero_tags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_auto_discovery.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_background_refresh.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_bootstrap_shim.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_cache_clock_skew.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_cache_layout.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_catalog_audit_entry_uniqueness.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_catalog_audit_framework.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_catalog_audit_legacy_dir.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_catalog_audit_metadata.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_catalog_audit_remote_url.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_catalog_audit_source_name.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_catalog_audit_strict.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_catalog_audit_tag_format.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_catalog_constraints.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_ci_validation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_clean_env_override_cleanup.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_clean_lifecycle.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_clean_paths.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_cli_entry_points.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_complete_cached_catalogs.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_complete_catalog_entries.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_complete_catalog_versions.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_complete_lockfile_names.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_complete_project_versions.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_complete_source_names.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_completion_bash.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_completion_subcommand.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_completion_zsh.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_concurrency.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_concurrency_serialization.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_copyfile_fs_effects.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_doc_validation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_doctor_cache_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_doctor_cache_flags_workspace_independent.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_doctor_consistency.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_doctor_default_subcheck_output.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_doctor_effective_source.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_doctor_prune_cache.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_doctor_remote_check.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_envsubst_command.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_fs_fault_extended.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_fs_fault_injection.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_full_lifecycle_synthetic.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_git_fault_injection.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_git_retry_env.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_gitignore_idempotency.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_after_add.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_command.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_conflict_url_normalization.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_include_cycle.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_include_diamond.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_lifecycle.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_lock_file_derivation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_lockfile_replay.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_marketplace_registration.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_no_kanon_remediation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_optional_vars.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_paths.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_reconcile.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_refresh_lock.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_refresh_lock_source.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_remote_url_policy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_required_vars.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_install_strict.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_json_output_stream_discipline.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_kanon_add_placeholder_handling.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_kanon_clean_embedded.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_kanon_full_lifecycle.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_kanon_install_embedded.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_kanonenv_parsing.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_lifecycle_recovery.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_linkfile_fs_effects.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_list_all_versions.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_list_all_versions_canonical.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_list_default.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_list_detail.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_list_filter.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_list_format_json.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_list_synthetic_catalog_variants.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_list_tree.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_lockfile_roundtrip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_marketplace_install.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_marketplace_lifecycle.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_marketplace_orphan_prune.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_midtoken_bash.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_midtoken_zsh.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_multi_source_aggregation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_no_bundled_catalog.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_no_default_catalog.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_no_hardcoded_org_values.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_observability.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_outdated.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_outdated_branch_drift.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_outdated_fail_on_upgrade.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_outdated_format_json.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_outdated_refs_tags_revision_parsing.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_platform_parity.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_preamble_bash.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_preamble_zsh.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_remove_core.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_remove_dry_run.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_remove_force_integration.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_signal_handling.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_synthetic_drift_fixture.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_synthetic_upgrade_versioned_fixture.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_unicode_encoding.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_validate_metadata.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_validate_xml.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_version_resolution.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_version_widened_bare_pep440.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_wheel_e2e.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_why_ambiguous.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_why_chain_walker.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_why_format_json.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_why_live_resolve.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_why_not_found_suggestion.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/integration/test_workspace_dir_env.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f1_s2_t5_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f5_s2_t7_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s1_t1_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s1_t2_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s1_t3_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s1_t4_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s2_t1_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s2_t2_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s2_t3_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s2_t4_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s2_t5_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s2_t6_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s3_t1_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_f6_s3_t2_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/regression/test_e0_install_relative_regression.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/_rp_helpers.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/conftest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_ad.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_bs.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_cd.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_cs.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_doctor_cache.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_ec.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_ep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_ev.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_hv.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_ic.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_id.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_ks.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_lf.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_lockfile_lifecycle.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_marketplace_direct_checkout.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_ms.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_pk.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rc.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_refresh_lock_existing_checkout.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rls_exact_vs_range.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_abandon.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_branches.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_checkout.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_cherry_pick.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_diff.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_diffmanifests.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_download.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_envsubst.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_forall.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_gc.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_grep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_help.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_info.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_init.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_list.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_manifest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_overview.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_prune.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_rebase.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_smartsync.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_stage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_start.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_status.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_sync.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_upload.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rp_wrap.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_rx.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_scenario_coverage_meta.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_tc_bootstrap.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_tc_clean.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_tc_install.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_uj.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_why_surface_query.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_why_url_path.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/scenarios/test_why_url_path_placeholder.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/security/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/security/test_security_hardening.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/test_wheel_layout.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/commands/test_repo_dir_resolution.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/conftest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/conftest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/fixtures/.gitignore +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/fixtures/README.md +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/fixtures/sample-manifest.xml +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/fixtures/sample-project-config.json +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/fixtures/test.gitconfig +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/fixtures/version_constraints_data.json +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/functional/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/functional/test_features.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/subcmds/__init__.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/subcmds/test_init_mirror.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/subcmds/test_manifest_revision_as_tag.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/subcmds/test_manifest_revision_as_tag_pep440.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/subcmds/test_selfupdate_stub.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_abandon_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_branches_coverage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug10_selfupdate_incompatible.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug11_race_condition.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug12_backup_preserved.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug13_init_reinit_warning.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug14_non_tty_log.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug15_prerelease_docs.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug16_nested_var_warning.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug18_envsubst_double_parse.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug19_glob_src_error.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug1_envsubst_malformed_xml.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug20_glob_dest_file.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug2_linkfile_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug3_execv_replaces_process.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug4_symlink_overwrite.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug5_empty_envsubst_list.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug6_undefined_env_vars.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug7_git_ls_remote_retry.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug8_ls_remote_stderr.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_bug9_constraint_resolution_cache.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_checklocalpath_rules_1_5.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_checklocalpath_rules_6_11.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_checkout_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_cherrypick_coverage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_color.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_command.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_conftest_fixtures.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_diffmanifests_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_doc_validate_git_preconditions.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_download_coverage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_editor.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_embedded_mode.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_envsubst_basic.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_envsubst_edge.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_envsubst_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_error.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_event_log.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_event_log_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_fetch.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_fixture_files.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_forall_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_git_command.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_git_config.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_git_refs.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_git_superproject.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_git_trace2_event_log.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_gitconfig_coverage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_grep_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_harness_smoke.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_hooks.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_import_verification.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_imports.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_include_path_resolution.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_info_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_init_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_list_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_main.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_main_coverage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_main_init_download_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_makefile_lint_format.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_makefile_structure.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_makefile_test_targets.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_manifest_coverage_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_manifest_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_manifest_doc_rp_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_manifest_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_manifest_subcmd_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_manifest_xml.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_manifest_xml_pep440.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_medium_files_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_mkdtemp_cleanup.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_overview_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_package_structure.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_pager.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_parselist.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_pep440_edge_1.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_pep440_edge_2.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_pep440_ops_ge.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_pep440_ops_rest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_platform_utils.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_process_isolation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_progress.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project_coverage_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project_coverage_threshold.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project_deep_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project_final_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project_integration.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project_metaproject_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project_methods.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_project_sync.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_prune_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_rebase_coverage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_remaining_coverage_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_repo_envsubst_api.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_repo_logging.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_repo_run_api.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_repo_sync_api.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_repo_trace.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_revision_inheritance.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_revision_tag_branch_sha.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_ruff_config.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_selfupdate_embedded.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_selfupdate_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_small_files_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_ssh.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_ssh_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_stage_coverage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_stage_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_start_coverage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_status_coverage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_status_gaps.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_status_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmd_imports.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_abandon.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_branches.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_checkout.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_cherry_pick.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_diff.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_diffmanifests.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_download.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_envsubst.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_forall.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_gc.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_grep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_help.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_info.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_init.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_list.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_manifest.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_overview.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_prune.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_rebase.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_selfupdate.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_smartsync.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_stage.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_start.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_status.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_sync.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_subcmds_upload.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_superproject_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_sync_coverage_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_sync_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_sync_deep_boost.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_sync_massive.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_upload_deep.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_version_consolidation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_version_constraints.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_wheel_contents.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_wrapper.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_annotation_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_annotation_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_annotation_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_contactinfo_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_contactinfo_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_contactinfo_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_copyfile_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_copyfile_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_copyfile_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_default_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_default_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_default_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_extend_project_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_extend_project_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_extend_project_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_fault_malformed.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_fault_structural.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_include_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_include_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_include_cycles.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_include_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_linkfile_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_linkfile_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_linkfile_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_manifest_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_manifest_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_manifest_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_manifest_server_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_manifest_server_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_manifest_server_flow.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_manifest_server_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_notice_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_notice_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_notice_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_project_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_project_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_project_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_remote_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_remote_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_remote_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_remove_project_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_remove_project_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_remove_project_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_repo_hooks_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_repo_hooks_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_repo_hooks_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_submanifest_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_submanifest_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_submanifest_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_superproject_attributes.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_superproject_crossref.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_superproject_flow.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xml_superproject_happy.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xmlbool.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_xmlint.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/repo/test_yamllint_config.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_accessed_at_coalescing.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_add_collision.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_add_zero_tags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_background_refresh.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_bare_semver_to_tag.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_bootstrap_deprecation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_cache.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_cache_layout.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_cache_ttl.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_audit_check_parser.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_audit_entry_uniqueness.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_audit_framework.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_audit_legacy_dir.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_audit_project_tag_format.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_audit_remote_url.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_audit_strict.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_audit_tag_format.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_catalog_source_parsing.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_ci_workflows.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_clean.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_clean_command.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_cli.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_cli_args.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_cli_help_format.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_cli_json_stream_discipline.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_complete_cached_catalogs.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_complete_catalog_entries.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_complete_catalog_versions.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_complete_lockfile_names.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_complete_project_versions.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_complete_source_names.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_completion.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_completion_sanitization.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_completion_subcommand.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_concurrency.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_conftest_scrubber.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_constants.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_constants_doctor_subcheck.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_constants_install_after_add.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_constants_outdated_refs_tags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_constants_why_lockfile.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_coverage_gaps.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_derive_source_name.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_discover.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_discover_source_names_missing_url.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_docs_embedded_architecture.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_docs_remaining_and_catalog.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_doctor.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_doctor_cache_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_doctor_completion_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_doctor_completion_staleness.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_doctor_consistency.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_doctor_coverage_gaps.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_doctor_effective_source.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_doctor_remote_reachability.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_env_isolation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_envsubst_subcommand.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_include_walker.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install_command.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install_conflict_detection.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install_https_enforcement.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install_placeholder_validation.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install_reconcile_decision.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install_refresh_lock.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install_refresh_lock_source.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install_state_matrix.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install_strict_flags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_install_strict_lock_orphan_naming.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_integration_testing_doc_manifest_paths.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_integration_testing_doc_s2_t14.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_integration_testing_doc_s2_t4.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_integration_testing_doc_s2_t5.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_integration_testing_doc_s2_t6.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_integration_testing_doc_s2_t7.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_integration_testing_doc_s2_tier1.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_kanon_hash.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_kanonenv.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_kanonenv_advanced_edge_cases.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_kanonenv_edge_cases.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_levenshtein.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_list_all_versions.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_list_detail.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_list_filter.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_list_format_json.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_list_tree.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_lock_file_path.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_lockfile.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_lockfile_coverage_gaps.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_lockfile_schema_migration.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_marketplace.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_marketplace_install.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_marketplace_non_plugin_skip.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_midtoken_splitter.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_outdated.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_outdated_branch_pinned.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_outdated_fail_on_upgrade.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_outdated_format_json.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_pep440_filter.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_pre_push_hook.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_preamble.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_preamble_semver_tags.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_provider_agnosticism.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_pyproject_build_config.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_remote_url.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_remove.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_remove_dry_run.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_remove_force.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_remove_line_endings.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_repo.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_repo_abspath.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_repo_command.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_resolve_catalog_dir.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_revision_resolve.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_rx_catalog_sub_repo.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_sanitize.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_url.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_validate.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_validate_command.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_validate_metadata.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_version.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_version_constraint_errors.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_why.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_why_ambiguity.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_why_format_json.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_why_suggestions.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/tests/unit/test_xml_validator.py +0 -0
- {kanon_cli-2.0.1 → kanon_cli-2.1.0}/uv.lock +0 -0
|
@@ -2,14 +2,93 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
## v2.1.0 (2026-06-09)
|
|
6
|
+
|
|
7
|
+
### Feature
|
|
8
|
+
|
|
9
|
+
* feat: discover catalog entries by <catalog-metadata>, not the *-marketplace.xml filename
|
|
10
|
+
|
|
11
|
+
feat: discover catalog entries by <catalog-metadata>, not the *-marketplace.xml filename ([`3a55eea`](https://github.com/caylent-solutions/kanon/commit/3a55eea6ac2380551f8e0bc045252d84db1d0408))
|
|
12
|
+
|
|
13
|
+
* feat: discover catalog entries by <catalog-metadata>, not the *-marketplace.xml filename
|
|
14
|
+
|
|
15
|
+
A catalog entry is now any repo-specs/**/*.xml manifest that contains a
|
|
16
|
+
<catalog-metadata> block; the *-marketplace.xml filename suffix is no longer
|
|
17
|
+
required. Plain packages (e.g. widget.xml, my-tool.xml) can be catalog entries,
|
|
18
|
+
not only packaged Claude marketplaces.
|
|
19
|
+
|
|
20
|
+
- Add core.metadata.find_catalog_entry_files(repo_root): globs repo-specs/**/*.xml
|
|
21
|
+
and keeps files whose content (XML comments stripped) declares a
|
|
22
|
+
<catalog-metadata> block. Shared by every discovery site.
|
|
23
|
+
- Route kanon list, add, validate marketplace, validate metadata, catalog audit,
|
|
24
|
+
and shell completion through it; remove MARKETPLACE_FILE_GLOB and the
|
|
25
|
+
per-command *-marketplace.xml globs.
|
|
26
|
+
- Backward compatible: *-marketplace.xml still matches (it carries the block).
|
|
27
|
+
Metadata-less includes (remote.xml) are not entries, but are still validated by
|
|
28
|
+
kanon validate xml and resolved via <include>.
|
|
29
|
+
- Markers that appear only inside an XML comment are ignored.
|
|
30
|
+
- Migrate test fixtures that relied on filename discovery to carry
|
|
31
|
+
<catalog-metadata>; add find_catalog_entry_files unit coverage and a
|
|
32
|
+
comment-exclusion regression.
|
|
33
|
+
- Update author/explainer docs to describe content-based discovery. ([`3faca3f`](https://github.com/caylent-solutions/kanon/commit/3faca3fbb6aef3e9db871145e9998cd38efbb3c5))
|
|
34
|
+
|
|
35
|
+
|
|
5
36
|
## v2.0.1 (2026-06-03)
|
|
6
37
|
|
|
38
|
+
### Chore
|
|
39
|
+
|
|
40
|
+
* chore(release): 2.0.1 ([`90dd32b`](https://github.com/caylent-solutions/kanon/commit/90dd32b290f65544727c00f5e752071d0fc23595))
|
|
41
|
+
|
|
7
42
|
### Documentation
|
|
8
43
|
|
|
9
44
|
* docs: present kanon repo as a native subcommand in the CLI reference (#73)
|
|
10
45
|
|
|
46
|
+
Drop the 'embedded repo dispatcher' wording from the 'kanon repo'
|
|
47
|
+
CLI-reference entry; describe it as kanon's native 'repo' subcommand
|
|
48
|
+
with arguments forwarded verbatim. Developer-facing
|
|
49
|
+
docs/architecture.md is intentionally left accurate about the
|
|
50
|
+
vendored repo fork. ([`f054536`](https://github.com/caylent-solutions/kanon/commit/f05453662fbc07e3406c072b7094ebb7ad2cbc24))
|
|
51
|
+
|
|
11
52
|
* docs: align CLI documentation with the released 2.0.0 surface (#72)
|
|
12
53
|
|
|
54
|
+
Rewrite README.md and audit docs/ so every command, flag, and behavior
|
|
55
|
+
matches the verified 2.0 CLI (help snapshot fixtures + src/).
|
|
56
|
+
|
|
57
|
+
README.md:
|
|
58
|
+
- Replace the bootstrap-centric standalone-usage flow with the real 2.0
|
|
59
|
+
flow: list (discover) -> add -> install -> clean (--orphans).
|
|
60
|
+
- Replace the bootstrap/install/clean/validate-only CLI Reference with a
|
|
61
|
+
full per-command reference (list, add, remove, install, clean, outdated,
|
|
62
|
+
why, doctor, validate xml/marketplace/metadata, catalog audit, repo,
|
|
63
|
+
completion); bootstrap appears only as a deprecation note (exits 3).
|
|
64
|
+
- Fix KANON_CATALOG_SOURCE to its real role and full precedence chain
|
|
65
|
+
(flag > env > lock [catalog] > .kanon [catalog]).
|
|
66
|
+
- Update the TOC, Subcommands table, architecture diagram, the
|
|
67
|
+
manifest-repo authoring sections to the nested <catalog-metadata>
|
|
68
|
+
/*-marketplace.xml model, and the project-structure layout (no catalog/).
|
|
69
|
+
|
|
70
|
+
docs/:
|
|
71
|
+
- setup-guide: drop stale pipx/python3 install-failure entries that no
|
|
72
|
+
longer match kanon install; prefix bare repo commands with kanon.
|
|
73
|
+
- installation: add --strict-lock/--strict-drift/--lock-file to synopsis
|
|
74
|
+
and flag table.
|
|
75
|
+
- configuration: add the 4th-tier .kanon [catalog] fallback to precedence.
|
|
76
|
+
- doctor: document the NO_SOURCES finding for a zero-source .kanon.
|
|
77
|
+
- creating-manifest-repos: keywords are comma-separated (was space).
|
|
78
|
+
- catalog-author-guide: drop the removed catalog/ directory reference.
|
|
79
|
+
- multi-source-guide: retitle (drop "Bootstrap"); de-"forthcoming" links.
|
|
80
|
+
- how-it-works: kanon repo sync (was bare repo sync).
|
|
81
|
+
|
|
82
|
+
doc-validation tests (test_docs_embedded_architecture,
|
|
83
|
+
test_doc_validation) pass; markdown edits add no new lint categories and
|
|
84
|
+
keep no trailing whitespace with a single trailing newline. ([`b99d4b4`](https://github.com/caylent-solutions/kanon/commit/b99d4b48cdc56bfa4ff79d3fa6db3d50768382d2))
|
|
85
|
+
|
|
86
|
+
### Unknown
|
|
87
|
+
|
|
88
|
+
* Merge pull request #74 from caylent-solutions/release-2.0.1
|
|
89
|
+
|
|
90
|
+
chore(release): 2.0.1 ([`4a49134`](https://github.com/caylent-solutions/kanon/commit/4a491348e9e2770bfb510d2116fb150451bcc123))
|
|
91
|
+
|
|
13
92
|
|
|
14
93
|
## v2.0.0 (2026-06-03)
|
|
15
94
|
|
|
@@ -752,6 +831,10 @@ No code changed (docs/planning-only removal); format-check + lint-check pass.
|
|
|
752
831
|
|
|
753
832
|
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> ([`8f0ac32`](https://github.com/caylent-solutions/kanon/commit/8f0ac32e874369c9aa5c3c3431003211adc4aee4))
|
|
754
833
|
|
|
834
|
+
### Chore
|
|
835
|
+
|
|
836
|
+
* chore(release): 2.0.0 ([`747851f`](https://github.com/caylent-solutions/kanon/commit/747851f4d0625c00a3661e9a165c952c6c27abc0))
|
|
837
|
+
|
|
755
838
|
### Documentation
|
|
756
839
|
|
|
757
840
|
* docs(readme): update Kanon overview (#68)
|
|
@@ -760,6 +843,12 @@ Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> ([`8f0ac32`](https
|
|
|
760
843
|
|
|
761
844
|
* docs(readme): restore overview emphasis ([`19a00f5`](https://github.com/caylent-solutions/kanon/commit/19a00f5173e9ee49f38b1403706c6de83bbc7cee))
|
|
762
845
|
|
|
846
|
+
### Unknown
|
|
847
|
+
|
|
848
|
+
* Merge pull request #70 from caylent-solutions/release-2.0.0
|
|
849
|
+
|
|
850
|
+
Release 2.0.0 ([`36bbb1d`](https://github.com/caylent-solutions/kanon/commit/36bbb1d6109dd076cf6d8454fdc4d88e63db3f3d))
|
|
851
|
+
|
|
763
852
|
|
|
764
853
|
## v1.3.1 (2026-05-04)
|
|
765
854
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kanon-cli
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Kanon (Kanon Package Manager) CLI tool
|
|
5
5
|
Project-URL: Homepage, https://github.com/caylent-solutions/kanon
|
|
6
6
|
Project-URL: Issues, https://github.com/caylent-solutions/kanon/issues
|
|
@@ -323,8 +323,9 @@ kanon list --detail # human-readable record per entry
|
|
|
323
323
|
kanon list my-tool --detail # narrow to entries matching a substring
|
|
324
324
|
```
|
|
325
325
|
|
|
326
|
-
`kanon list` reads the
|
|
327
|
-
manifest repo and prints one
|
|
326
|
+
`kanon list` reads the catalog entry manifests (any `repo-specs/**/*.xml`
|
|
327
|
+
file with a `<catalog-metadata>` block) in the manifest repo and prints one
|
|
328
|
+
catalog entry name per line.
|
|
328
329
|
|
|
329
330
|
**2. Add entries to `.kanon`:**
|
|
330
331
|
|
|
@@ -852,8 +853,8 @@ For full documentation, see [docs/how-it-works.md](docs/how-it-works.md).
|
|
|
852
853
|
A manifest repository contains `repo-specs/` with XML manifests that define
|
|
853
854
|
what packages to sync, from which repositories, and at which versions. **The
|
|
854
855
|
manifest repo IS the catalog** -- there is no separate `catalog/` directory.
|
|
855
|
-
Each catalog entry is a single
|
|
856
|
-
that carries a nested `<catalog-metadata>` block; the
|
|
856
|
+
Each catalog entry is a single `*.xml` file under `repo-specs/` (any
|
|
857
|
+
filename) that carries a nested `<catalog-metadata>` block; the
|
|
857
858
|
`<catalog-metadata><name>` child is the entry name consumers pass to
|
|
858
859
|
`kanon add <name>`. See
|
|
859
860
|
[docs/creating-manifest-repos.md](docs/creating-manifest-repos.md) for the
|
|
@@ -873,10 +874,10 @@ my-manifest-repo/
|
|
|
873
874
|
packages.xml # Package repos with pinned versions
|
|
874
875
|
```
|
|
875
876
|
|
|
876
|
-
### Catalog entry
|
|
877
|
+
### Catalog entry
|
|
877
878
|
|
|
878
|
-
Each catalog entry is
|
|
879
|
-
nested `<catalog-metadata>` block. Required fields are `name`,
|
|
879
|
+
Each catalog entry is an XML file under `repo-specs/` (any filename)
|
|
880
|
+
containing exactly one nested `<catalog-metadata>` block. Required fields are `name`,
|
|
880
881
|
`display-name`, `description`, and `version`; recommended fields are `type`,
|
|
881
882
|
`owner-name`, `owner-email`, and `keywords` (comma-separated). The legacy
|
|
882
883
|
flat-attribute scheme (metadata as XML attributes) is rejected.
|
|
@@ -301,8 +301,9 @@ kanon list --detail # human-readable record per entry
|
|
|
301
301
|
kanon list my-tool --detail # narrow to entries matching a substring
|
|
302
302
|
```
|
|
303
303
|
|
|
304
|
-
`kanon list` reads the
|
|
305
|
-
manifest repo and prints one
|
|
304
|
+
`kanon list` reads the catalog entry manifests (any `repo-specs/**/*.xml`
|
|
305
|
+
file with a `<catalog-metadata>` block) in the manifest repo and prints one
|
|
306
|
+
catalog entry name per line.
|
|
306
307
|
|
|
307
308
|
**2. Add entries to `.kanon`:**
|
|
308
309
|
|
|
@@ -830,8 +831,8 @@ For full documentation, see [docs/how-it-works.md](docs/how-it-works.md).
|
|
|
830
831
|
A manifest repository contains `repo-specs/` with XML manifests that define
|
|
831
832
|
what packages to sync, from which repositories, and at which versions. **The
|
|
832
833
|
manifest repo IS the catalog** -- there is no separate `catalog/` directory.
|
|
833
|
-
Each catalog entry is a single
|
|
834
|
-
that carries a nested `<catalog-metadata>` block; the
|
|
834
|
+
Each catalog entry is a single `*.xml` file under `repo-specs/` (any
|
|
835
|
+
filename) that carries a nested `<catalog-metadata>` block; the
|
|
835
836
|
`<catalog-metadata><name>` child is the entry name consumers pass to
|
|
836
837
|
`kanon add <name>`. See
|
|
837
838
|
[docs/creating-manifest-repos.md](docs/creating-manifest-repos.md) for the
|
|
@@ -851,10 +852,10 @@ my-manifest-repo/
|
|
|
851
852
|
packages.xml # Package repos with pinned versions
|
|
852
853
|
```
|
|
853
854
|
|
|
854
|
-
### Catalog entry
|
|
855
|
+
### Catalog entry
|
|
855
856
|
|
|
856
|
-
Each catalog entry is
|
|
857
|
-
nested `<catalog-metadata>` block. Required fields are `name`,
|
|
857
|
+
Each catalog entry is an XML file under `repo-specs/` (any filename)
|
|
858
|
+
containing exactly one nested `<catalog-metadata>` block. Required fields are `name`,
|
|
858
859
|
`display-name`, `description`, and `version`; recommended fields are `type`,
|
|
859
860
|
`owner-name`, `owner-email`, and `keywords` (comma-separated). The legacy
|
|
860
861
|
flat-attribute scheme (metadata as XML attributes) is rejected.
|
|
@@ -118,8 +118,9 @@ the emitted finding message, and give the catalog-author fix.
|
|
|
118
118
|
### Rule 1 -- catalog-metadata completeness
|
|
119
119
|
|
|
120
120
|
**What it looks for:**
|
|
121
|
-
The check reads every
|
|
122
|
-
|
|
121
|
+
The check reads every catalog entry manifest (any `repo-specs/**/*.xml` file
|
|
122
|
+
with a `<catalog-metadata>` block) under `repo-specs/` and inspects the
|
|
123
|
+
`<catalog-metadata>` block for:
|
|
123
124
|
|
|
124
125
|
1. Missing or whitespace-only **required** fields -- produces one ERROR
|
|
125
126
|
(M001) per missing field.
|
|
@@ -4,8 +4,9 @@ A **manifest repo** is a git repository whose `repo-specs/` directory contains
|
|
|
4
4
|
installable kanon dependency definitions. When you point kanon at a manifest
|
|
5
5
|
repo via `--catalog-source`, you are pointing it at the catalog itself -- there
|
|
6
6
|
is no separate "catalog" entity inside the repository, and no `catalog/<name>/`
|
|
7
|
-
subdirectory model. The repository is the catalog; each
|
|
8
|
-
file
|
|
7
|
+
subdirectory model. The repository is the catalog; each `repo-specs/**/*.xml`
|
|
8
|
+
file that contains a `<catalog-metadata>` block is a catalog entry (any
|
|
9
|
+
filename; the `-marketplace.xml` suffix is a convention, not a requirement).
|
|
9
10
|
|
|
10
11
|
## What is a manifest repo?
|
|
11
12
|
|
|
@@ -19,7 +20,7 @@ repo-specs/
|
|
|
19
20
|
...
|
|
20
21
|
```
|
|
21
22
|
|
|
22
|
-
Each
|
|
23
|
+
Each XML file with a `<catalog-metadata>` block is a **catalog entry** -- a single dependency
|
|
23
24
|
definition identified by the `<name>` child of its `<catalog-metadata>` block.
|
|
24
25
|
The `<name>` value is the **entry name**. There is exactly one
|
|
25
26
|
`<catalog-metadata>` block per XML file, and entry names must be unique across
|
|
@@ -18,10 +18,13 @@ composition. Currently marketplace manifests use a flat structure (each includes
|
|
|
18
18
|
|
|
19
19
|
### Naming Convention
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
The
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
A catalog entry is any `*.xml` file under `repo-specs/` that contains a
|
|
22
|
+
`<catalog-metadata>` block. The filename is unrestricted: `*-marketplace.xml`
|
|
23
|
+
is a common convention, but `widget.xml` or `my-tool.xml` work equally well.
|
|
24
|
+
The `kanon validate marketplace` command discovers every such entry under
|
|
25
|
+
`repo-specs/`. Files with no `<catalog-metadata>` block (e.g., shared includes
|
|
26
|
+
like `remote.xml`, `packages.xml`) are not entries and are not validated as
|
|
27
|
+
marketplace manifests -- they are still checked by `kanon validate xml`.
|
|
25
28
|
|
|
26
29
|
### Example Manifest
|
|
27
30
|
|
|
@@ -99,8 +99,9 @@ kanon validate marketplace --repo-root /path/to/repo
|
|
|
99
99
|
|
|
100
100
|
### `kanon validate metadata`
|
|
101
101
|
|
|
102
|
-
Check every
|
|
103
|
-
soft-spot violations (spec
|
|
102
|
+
Check every catalog entry manifest (any `repo-specs/**/*.xml` file with a
|
|
103
|
+
`<catalog-metadata>` block) for in-repo catalog soft-spot violations (spec
|
|
104
|
+
Section 3.5 rules 1, 2, 3) without network access.
|
|
104
105
|
|
|
105
106
|
No git operations are performed. No `git ls-remote` calls. No cloning.
|
|
106
107
|
|
|
@@ -6,14 +6,16 @@ of packages for kanon consumers.
|
|
|
6
6
|
## What a manifest repo is
|
|
7
7
|
|
|
8
8
|
A **manifest repo** is a git repository whose `repo-specs/` directory
|
|
9
|
-
holds XML manifest files
|
|
9
|
+
holds XML manifest files. Each file that contains a `<catalog-metadata>`
|
|
10
|
+
block is a catalog entry, regardless of its filename. The git
|
|
10
11
|
URL (with an optional `@<ref>`) of this repository is exactly what a
|
|
11
12
|
consumer passes to `--catalog-source` or sets in `KANON_CATALOG_SOURCE`.
|
|
12
13
|
|
|
13
14
|
The manifest repo IS the catalog. There is no separate catalog directory;
|
|
14
|
-
every catalog entry lives in a single
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
every catalog entry lives in a single `*.xml` file under `repo-specs/`,
|
|
16
|
+
identified by its `<catalog-metadata>` block (the `-marketplace.xml` suffix
|
|
17
|
+
is a convention, not a requirement). The `<catalog-metadata><name>` child is
|
|
18
|
+
the **entry name** -- the
|
|
17
19
|
identifier consumers pass to `kanon add <name>`.
|
|
18
20
|
|
|
19
21
|
Key terminology (canonical form from spec Section 1.1):
|
|
@@ -46,7 +48,9 @@ my-manifest-repo/
|
|
|
46
48
|
+-- README.md
|
|
47
49
|
```
|
|
48
50
|
|
|
49
|
-
Every
|
|
51
|
+
Every `repo-specs/**/*.xml` file that contains a `<catalog-metadata>` block is
|
|
52
|
+
a catalog entry, regardless of filename; files without the block (such as
|
|
53
|
+
shared `<include>` targets) are not entries. There
|
|
50
54
|
is no `catalog/` directory in a current manifest repo. If you are
|
|
51
55
|
migrating a repo that still has one, see
|
|
52
56
|
[Migrating away from catalog/\<name\>/](#migrating-away-from-catalogname)
|
|
@@ -33,9 +33,10 @@ kanon list [--catalog-source <git-url>@<ref>]
|
|
|
33
33
|
|
|
34
34
|
`kanon list` clones the manifest repo identified by
|
|
35
35
|
`--catalog-source` (or `KANON_CATALOG_SOURCE`) and walks every
|
|
36
|
-
`repo-specs
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
`repo-specs/**/*.xml` file. One entry is emitted per XML file whose
|
|
37
|
+
`<catalog-metadata>` block contains the required fields (the filename is
|
|
38
|
+
unrestricted -- the `-marketplace.xml` suffix is a convention, not a
|
|
39
|
+
requirement). Entry name = `<catalog-metadata><name>`.
|
|
39
40
|
|
|
40
41
|
The legacy `catalog/<name>/` directory inside a manifest repo is
|
|
41
42
|
ignored; `kanon list` reads only the XML manifests.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "kanon-cli"
|
|
7
|
-
version = "2.0
|
|
7
|
+
version = "2.1.0"
|
|
8
8
|
description = "Kanon (Kanon Package Manager) CLI tool"
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -38,6 +38,7 @@ Homepage = "https://github.com/caylent-solutions/kanon"
|
|
|
38
38
|
Issues = "https://github.com/caylent-solutions/kanon/issues"
|
|
39
39
|
|
|
40
40
|
|
|
41
|
+
|
|
41
42
|
[tool.hatch.build.targets.wheel]
|
|
42
43
|
packages = [
|
|
43
44
|
"src/kanon_cli",
|
|
@@ -118,6 +119,7 @@ minor_tags = ["feat"]
|
|
|
118
119
|
patch_tags = ["fix", "perf", "security", "revert"]
|
|
119
120
|
|
|
120
121
|
|
|
122
|
+
|
|
121
123
|
[dependency-groups]
|
|
122
124
|
dev = [
|
|
123
125
|
"build>=1.4.3",
|
|
@@ -41,6 +41,7 @@ from kanon_cli.core.metadata import (
|
|
|
41
41
|
CatalogMetadataParseError,
|
|
42
42
|
_parse_catalog_metadata,
|
|
43
43
|
derive_source_name,
|
|
44
|
+
find_catalog_entry_files,
|
|
44
45
|
)
|
|
45
46
|
from kanon_cli.version import _list_tags, _resolve_constraint_from_tags, is_version_constraint, resolve_version
|
|
46
47
|
|
|
@@ -400,11 +401,7 @@ def _build_entry_catalog(
|
|
|
400
401
|
Returns:
|
|
401
402
|
List of (CatalogMetadata, xml_path, url) triples for every entry found.
|
|
402
403
|
"""
|
|
403
|
-
|
|
404
|
-
if not repo_specs.is_dir():
|
|
405
|
-
return []
|
|
406
|
-
|
|
407
|
-
xml_paths = list(repo_specs.rglob("*-marketplace.xml"))
|
|
404
|
+
xml_paths = find_catalog_entry_files(manifest_root)
|
|
408
405
|
entries: list[tuple[CatalogMetadata, pathlib.Path, str]] = []
|
|
409
406
|
error_paths: list[str] = []
|
|
410
407
|
|
|
@@ -65,8 +65,8 @@ from kanon_cli.constants import (
|
|
|
65
65
|
KANON_CATALOG_AUDIT_VALID_CHECKS,
|
|
66
66
|
KANON_CATALOG_ENTRY_NAME_ALLOWED_CHARS_RE,
|
|
67
67
|
)
|
|
68
|
-
from kanon_cli.core.manifest import
|
|
69
|
-
from kanon_cli.core.metadata import audit_catalog_metadata, derive_source_name
|
|
68
|
+
from kanon_cli.core.manifest import collect_remote_url_findings
|
|
69
|
+
from kanon_cli.core.metadata import audit_catalog_metadata, derive_source_name, find_catalog_entry_files
|
|
70
70
|
from kanon_cli.core.url import canonicalize_repo_url
|
|
71
71
|
|
|
72
72
|
# Alias for the XML parse error type from defusedxml to avoid importing from the
|
|
@@ -379,10 +379,11 @@ def _format_findings(findings: list[AuditFinding], fmt: str) -> str:
|
|
|
379
379
|
def _iter_entry_names(
|
|
380
380
|
target_path: pathlib.Path,
|
|
381
381
|
) -> Iterator[tuple[pathlib.Path, str]]:
|
|
382
|
-
"""Yield ``(xml_file, entry_name)`` pairs for every parseable
|
|
382
|
+
"""Yield ``(xml_file, entry_name)`` pairs for every parseable catalog entry.
|
|
383
383
|
|
|
384
|
-
Walks
|
|
385
|
-
|
|
384
|
+
Walks every catalog entry manifest (any ``repo-specs/**/*.xml`` that carries a
|
|
385
|
+
``<catalog-metadata>`` block) via
|
|
386
|
+
:func:`kanon_cli.core.metadata.find_catalog_entry_files`. For each file the function:
|
|
386
387
|
|
|
387
388
|
1. Parses the XML, silently skipping files that raise
|
|
388
389
|
:exc:`XMLParseError` (malformed-XML errors are the ``metadata``
|
|
@@ -403,7 +404,7 @@ def _iter_entry_names(
|
|
|
403
404
|
Tuples of ``(xml_file, entry_name)`` where ``entry_name`` is the
|
|
404
405
|
stripped text content of the ``<name>`` element.
|
|
405
406
|
"""
|
|
406
|
-
for xml_file in
|
|
407
|
+
for xml_file in find_catalog_entry_files(target_path):
|
|
407
408
|
try:
|
|
408
409
|
tree = ET.parse(xml_file)
|
|
409
410
|
except XMLParseError:
|
|
@@ -431,10 +432,11 @@ def _iter_entry_names(
|
|
|
431
432
|
|
|
432
433
|
|
|
433
434
|
def _check_metadata(target_path: pathlib.Path) -> list[AuditFinding]:
|
|
434
|
-
"""Check every
|
|
435
|
+
"""Check every catalog entry manifest under ``repo-specs/`` for metadata issues.
|
|
435
436
|
|
|
436
|
-
Walks
|
|
437
|
-
|
|
437
|
+
Walks every catalog entry manifest (any ``repo-specs/**/*.xml`` that carries a
|
|
438
|
+
``<catalog-metadata>`` block) via
|
|
439
|
+
:func:`kanon_cli.core.metadata.find_catalog_entry_files` and calls
|
|
438
440
|
:func:`kanon_cli.core.metadata.audit_catalog_metadata` on each file.
|
|
439
441
|
|
|
440
442
|
Converts each :class:`MetadataAuditIssue` returned into an
|
|
@@ -449,7 +451,7 @@ def _check_metadata(target_path: pathlib.Path) -> list[AuditFinding]:
|
|
|
449
451
|
"""
|
|
450
452
|
findings: list[AuditFinding] = []
|
|
451
453
|
|
|
452
|
-
for xml_file in
|
|
454
|
+
for xml_file in find_catalog_entry_files(target_path):
|
|
453
455
|
for issue in audit_catalog_metadata(xml_file):
|
|
454
456
|
findings.append(
|
|
455
457
|
AuditFinding(
|
|
@@ -49,7 +49,12 @@ from kanon_cli.constants import (
|
|
|
49
49
|
)
|
|
50
50
|
from kanon_cli.core.catalog import _parse_catalog_source
|
|
51
51
|
from kanon_cli.core.cli_args import add_catalog_source_arg
|
|
52
|
-
from kanon_cli.core.metadata import
|
|
52
|
+
from kanon_cli.core.metadata import (
|
|
53
|
+
CatalogMetadata,
|
|
54
|
+
CatalogMetadataParseError,
|
|
55
|
+
_parse_catalog_metadata,
|
|
56
|
+
find_catalog_entry_files,
|
|
57
|
+
)
|
|
53
58
|
from kanon_cli.version import is_version_constraint, resolve_version
|
|
54
59
|
|
|
55
60
|
# -- Detail formatter private constants --
|
|
@@ -412,7 +417,7 @@ def _walk_all_versions(
|
|
|
412
417
|
)
|
|
413
418
|
sys.exit(1)
|
|
414
419
|
|
|
415
|
-
xml_paths =
|
|
420
|
+
xml_paths = find_catalog_entry_files(repo_dir)
|
|
416
421
|
version_names: list[str] = []
|
|
417
422
|
legacy_skipped_count = 0
|
|
418
423
|
for xml_path in xml_paths:
|
|
@@ -512,26 +517,6 @@ def _resolve_manifest_repo(catalog_source: str) -> pathlib.Path:
|
|
|
512
517
|
return repo_dir
|
|
513
518
|
|
|
514
519
|
|
|
515
|
-
def _walk_marketplace_xmls(manifest_root: pathlib.Path) -> list[pathlib.Path]:
|
|
516
|
-
"""Walk ``repo-specs/**/*-marketplace.xml`` under manifest_root.
|
|
517
|
-
|
|
518
|
-
Reads ONLY files under the ``repo-specs/`` directory. The legacy
|
|
519
|
-
``catalog/<name>/`` directory is explicitly excluded per spec Section 4.1.
|
|
520
|
-
|
|
521
|
-
Args:
|
|
522
|
-
manifest_root: Root directory of the cloned manifest repo.
|
|
523
|
-
|
|
524
|
-
Returns:
|
|
525
|
-
List of :class:`pathlib.Path` objects pointing to discovered XML
|
|
526
|
-
files. Empty when ``repo-specs/`` is absent or contains no
|
|
527
|
-
``*-marketplace.xml`` files.
|
|
528
|
-
"""
|
|
529
|
-
repo_specs = manifest_root / "repo-specs"
|
|
530
|
-
if not repo_specs.is_dir():
|
|
531
|
-
return []
|
|
532
|
-
return list(repo_specs.rglob("*-marketplace.xml"))
|
|
533
|
-
|
|
534
|
-
|
|
535
520
|
def _build_sorted_index(manifest_root: pathlib.Path) -> list[str]:
|
|
536
521
|
"""Build a lexicographically sorted list of catalog entry names.
|
|
537
522
|
|
|
@@ -546,7 +531,7 @@ def _build_sorted_index(manifest_root: pathlib.Path) -> list[str]:
|
|
|
546
531
|
Sorted list of entry name strings. Empty when the catalog has no
|
|
547
532
|
``*-marketplace.xml`` files.
|
|
548
533
|
"""
|
|
549
|
-
xml_paths =
|
|
534
|
+
xml_paths = find_catalog_entry_files(manifest_root)
|
|
550
535
|
names: list[str] = []
|
|
551
536
|
for xml_path in xml_paths:
|
|
552
537
|
metadata = _parse_catalog_metadata(xml_path)
|
|
@@ -573,7 +558,7 @@ def _build_sorted_metadata(manifest_root: pathlib.Path) -> list[CatalogMetadata]
|
|
|
573
558
|
Sorted list of :class:`CatalogMetadata` instances. Empty when the
|
|
574
559
|
catalog has no ``*-marketplace.xml`` files.
|
|
575
560
|
"""
|
|
576
|
-
xml_paths =
|
|
561
|
+
xml_paths = find_catalog_entry_files(manifest_root)
|
|
577
562
|
entries: list[CatalogMetadata] = []
|
|
578
563
|
for xml_path in xml_paths:
|
|
579
564
|
metadata = _parse_catalog_metadata(xml_path)
|
|
@@ -866,7 +851,7 @@ def _render_tree(
|
|
|
866
851
|
FileNotFoundError: When no ``*-marketplace.xml`` for ``entry_name``
|
|
867
852
|
is found under ``repo-specs/``.
|
|
868
853
|
"""
|
|
869
|
-
xml_files =
|
|
854
|
+
xml_files = find_catalog_entry_files(manifest_root)
|
|
870
855
|
entry_xml: pathlib.Path | None = None
|
|
871
856
|
entry_version = "unknown"
|
|
872
857
|
|
|
@@ -882,7 +867,7 @@ def _render_tree(
|
|
|
882
867
|
|
|
883
868
|
if entry_xml is None:
|
|
884
869
|
raise FileNotFoundError(
|
|
885
|
-
f"No
|
|
870
|
+
f"No catalog entry manifest found for entry '{entry_name}' under {manifest_root / 'repo-specs'}"
|
|
886
871
|
)
|
|
887
872
|
|
|
888
873
|
sha = _sha12_from_path(entry_xml)
|
|
@@ -53,7 +53,7 @@ from kanon_cli.constants import (
|
|
|
53
53
|
KANON_COMPLETION_TIMEOUT,
|
|
54
54
|
)
|
|
55
55
|
from kanon_cli.core.catalog import _parse_catalog_source
|
|
56
|
-
from kanon_cli.core.metadata import CatalogMetadataParseError, _parse_catalog_metadata
|
|
56
|
+
from kanon_cli.core.metadata import CatalogMetadataParseError, _parse_catalog_metadata, find_catalog_entry_files
|
|
57
57
|
|
|
58
58
|
_COMPLETER_NAME = "__complete_catalog_entries"
|
|
59
59
|
|
|
@@ -116,12 +116,8 @@ def _build_index(repo_dir: Path) -> list[str]:
|
|
|
116
116
|
Returns:
|
|
117
117
|
Sorted list of safe catalog entry names found in repo-specs/.
|
|
118
118
|
"""
|
|
119
|
-
specs_root = repo_dir / "repo-specs"
|
|
120
|
-
if not specs_root.is_dir():
|
|
121
|
-
return []
|
|
122
|
-
|
|
123
119
|
names: list[str] = []
|
|
124
|
-
for xml_path in
|
|
120
|
+
for xml_path in find_catalog_entry_files(repo_dir):
|
|
125
121
|
try:
|
|
126
122
|
metadata = _parse_catalog_metadata(xml_path)
|
|
127
123
|
except CatalogMetadataParseError:
|
|
@@ -14,7 +14,6 @@ EXIT_CODE_DEPRECATED = 3
|
|
|
14
14
|
|
|
15
15
|
# -- Marketplace validation --
|
|
16
16
|
MARKETPLACE_DIR_PREFIX = "${CLAUDE_MARKETPLACES_DIR}/"
|
|
17
|
-
MARKETPLACE_FILE_GLOB = "*-marketplace.xml"
|
|
18
17
|
ALLOWED_BRANCHES = frozenset({"main"})
|
|
19
18
|
REFS_TAGS_RE = re.compile(r"^refs/tags/.+/\d+\.\d+\.\d+$")
|
|
20
19
|
CONSTRAINT_RE = re.compile(r"^(~=|>=|<=|>|<)\d+\.\d+\.\d+$")
|
|
@@ -35,6 +35,7 @@ from typing import TYPE_CHECKING, NamedTuple, cast
|
|
|
35
35
|
import defusedxml.ElementTree as ET
|
|
36
36
|
|
|
37
37
|
from kanon_cli.constants import KANON_ALLOW_INSECURE_REMOTES
|
|
38
|
+
from kanon_cli.core.metadata import find_catalog_entry_files
|
|
38
39
|
from kanon_cli.core.remote_url import RemoteUrlScheme, _classify_remote_url_scheme
|
|
39
40
|
|
|
40
41
|
if TYPE_CHECKING:
|
|
@@ -129,12 +130,6 @@ def walk_includes_collecting_remotes(
|
|
|
129
130
|
return remotes
|
|
130
131
|
|
|
131
132
|
|
|
132
|
-
def _iter_marketplace_xml_paths(target_path: pathlib.Path) -> list[pathlib.Path]:
|
|
133
|
-
"""Return sorted list of *-marketplace.xml paths under target_path/repo-specs/."""
|
|
134
|
-
repo_specs = target_path / "repo-specs"
|
|
135
|
-
return sorted(repo_specs.rglob("*-marketplace.xml"))
|
|
136
|
-
|
|
137
|
-
|
|
138
133
|
# Regex that matches any remaining ${VAR} or $VAR placeholder after expansion.
|
|
139
134
|
_PLACEHOLDER_RE = re.compile(r"\$\{[^}]+\}|\$[A-Za-z_][A-Za-z0-9_]*")
|
|
140
135
|
|
|
@@ -221,7 +216,7 @@ def collect_remote_url_findings(
|
|
|
221
216
|
|
|
222
217
|
findings: list[RawFinding] = []
|
|
223
218
|
|
|
224
|
-
for xml_file in
|
|
219
|
+
for xml_file in find_catalog_entry_files(target_path):
|
|
225
220
|
# Build the remote-name -> fetch-URL map for this file and its includes.
|
|
226
221
|
try:
|
|
227
222
|
remote_map = walk_includes_collecting_remotes(xml_file, target_path)
|
|
@@ -16,9 +16,9 @@ from kanon_cli.constants import (
|
|
|
16
16
|
ALLOWED_BRANCHES,
|
|
17
17
|
CONSTRAINT_RE,
|
|
18
18
|
MARKETPLACE_DIR_PREFIX,
|
|
19
|
-
MARKETPLACE_FILE_GLOB,
|
|
20
19
|
REFS_TAGS_RE,
|
|
21
20
|
)
|
|
21
|
+
from kanon_cli.core.metadata import find_catalog_entry_files
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def validate_linkfile_dest(xml_path: Path) -> list[str]:
|
|
@@ -215,11 +215,11 @@ def validate_marketplace(repo_root: Path) -> int:
|
|
|
215
215
|
Returns:
|
|
216
216
|
0 if all files pass validation, 1 otherwise.
|
|
217
217
|
"""
|
|
218
|
-
marketplace_files =
|
|
218
|
+
marketplace_files = find_catalog_entry_files(repo_root)
|
|
219
219
|
|
|
220
220
|
if not marketplace_files:
|
|
221
221
|
print(
|
|
222
|
-
"Error: No
|
|
222
|
+
"Error: No catalog entry manifests (*.xml with a <catalog-metadata> block) found under repo-specs/",
|
|
223
223
|
file=sys.stderr,
|
|
224
224
|
)
|
|
225
225
|
return 1
|