kanon-cli 3.2.0__tar.gz → 3.3.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-3.2.0 → kanon_cli-3.3.0}/CHANGELOG.md +109 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/PKG-INFO +40 -1
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/README.md +39 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/cli-reference.md +79 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/coming-from-pip-npm-cargo.md +1 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/configuration.md +73 -3
- kanon_cli-3.3.0/docs/privacy.md +90 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/pyproject.toml +1 -1
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/__init__.py +1 -1
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/cli.py +75 -8
- kanon_cli-3.3.0/src/kanon_cli/commands/list.py +560 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/constants.py +182 -2
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/cli_args.py +21 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/install.py +109 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/lockfile.py +99 -14
- kanon_cli-3.3.0/src/kanon_cli/core/telemetry.py +1109 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/update_check.py +61 -6
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/conftest.py +38 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/completion/expected-bash.sh +11 -3
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/completion/expected-powershell.ps1 +1 -1
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/completion/expected-zsh.sh +17 -0
- kanon_cli-3.3.0/tests/fixtures/help/kanon-list.txt +35 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-toplevel.txt +3 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/conftest.py +5 -3
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_help_snapshots.py +1 -0
- kanon_cli-3.3.0/tests/functional/test_list.py +196 -0
- kanon_cli-3.3.0/tests/functional/test_list_telemetry.py +119 -0
- kanon_cli-3.3.0/tests/functional/test_telemetry_journey.py +309 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_cli_entry_points.py +16 -13
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_completion_bash.py +12 -1
- kanon_cli-3.3.0/tests/integration/test_list_command_json.py +141 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/conftest.py +4 -3
- kanon_cli-3.3.0/tests/scenarios/test_install_graph_capture.py +101 -0
- kanon_cli-3.3.0/tests/scenarios/test_list_journey.py +151 -0
- kanon_cli-3.3.0/tests/unit/test_build_project_entries.py +156 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_cli.py +156 -6
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_constants.py +3 -3
- kanon_cli-3.3.0/tests/unit/test_constants_list.py +106 -0
- kanon_cli-3.3.0/tests/unit/test_list.py +466 -0
- kanon_cli-3.3.0/tests/unit/test_lockfile_reconcile.py +132 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_search.py +15 -25
- kanon_cli-3.3.0/tests/unit/test_telemetry.py +1087 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_update_check.py +85 -8
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.claude/settings.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/.devcontainer.postcreate.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/VERSION +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/catalog-entry.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/devcontainer-functions.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/devcontainer.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/fix-line-endings.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/nix-family-os/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/nix-family-os/tinyproxy-daemon.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/nix-family-os/tinyproxy.conf.template +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/postcreate-wrapper.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/project-setup.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/wsl-family-os/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/wsl-family-os/tinyproxy-daemon.sh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.devcontainer/wsl-family-os/tinyproxy.conf.template +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.github/CODEOWNERS +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.github/actions/setup-kanon/action.yml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.github/workflows/codeql-analysis.yml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.github/workflows/main-validation.yml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.github/workflows/pr-validation.yml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.github/workflows/publish.yml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.gitignore +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.markdownlint.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.pre-commit-config.yaml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.tool-versions +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/.yamllint +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/CLAUDE.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/CONTRIBUTING.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/LICENSE +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/Makefile +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/architecture.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/catalog-author-guide.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/catalog-format-versioning.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/catalogs-explained.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/claude-marketplaces-guide.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/cli/catalog-audit.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/cli/doctor.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/cli/validate.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/cli.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/contributing.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/creating-manifest-repos.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/creating-packages.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/doctor.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/exit-codes.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/git-auth-setup.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/how-it-works.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/installation.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/integration-testing.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/lifecycle.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/list-and-add.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/lockfile.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/migrating-existing-kanon-files.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/migration-to-add.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/multi-source-guide.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/outdated-and-why.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/pipeline-integration.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/repo/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/repo/internal-fs-layout.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/repo/manifest-format.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/repo/python-support.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/repo/repo-hooks.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/repo/smart-sync.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/repo/windows.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/security-model.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/setup-guide.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/shell-completion.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/test-coverage.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/testing/matrix-traceability.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/troubleshooting.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/url-canonicalization.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/docs/version-resolution.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/git-hooks/pre-commit +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/git-hooks/pre-push +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/link +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/requirements-dev.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/requirements.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/scripts/check_archive_no_duplicates.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/__main__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/add.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/clean.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/completion.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/doctor.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/install.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/marketplace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/outdated.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/remove.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/repo.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/search.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/validate.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/commands/why.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/cache.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/cached_catalogs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/catalog_entries.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/catalog_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/lockfile_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/midtoken.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/pep440_filter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/powershell.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/preamble.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/project_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/sanitize.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/completions/source_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/clean.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/discover.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/git_runner.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/include_walker.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/kanon_hash.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/kanonenv.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/kanonenv_writer.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/manifest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/manifest_vars.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/marketplace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/marketplace_validator.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/remote_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/core/xml_validator.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/color.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/editor.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/error.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/event_log.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/fetch.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/git_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/git_config.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/git_refs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/git_ssh +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/git_superproject.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/git_trace2_event_log.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/git_trace2_event_log_base.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/hooks/commit-msg +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/hooks/pre-auto-gc +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/hooks.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/main.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/manifest_xml.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/pager.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/platform_utils.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/platform_utils_win32.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/progress.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/project.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/repo +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/repo_logging.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/repo_trace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/requirements.jsonc +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/ssh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/abandon.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/branches.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/checkout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/cherry_pick.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/diff.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/diffmanifests.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/download.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/envsubst.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/forall.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/gc.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/grep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/help.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/info.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/init.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/list.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/manifest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/overview.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/prune.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/rebase.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/selfupdate.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/smartsync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/stage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/start.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/status.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/sync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/subcmds/upload.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/version_constraints.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/repo/wrapper.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/utils/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/utils/concurrency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/utils/levenshtein.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/utils/lock_file_path.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/utils/spawn.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/src/kanon_cli/version.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/duplicate-child-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/missing-recommended-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/missing-required-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/multiple-blocks-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/dotted-name-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/hyphenated-name-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/uppercase-name-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-a-1-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-a-2-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-b-1-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-b-2-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/file-url-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/query-string-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/unresolvable-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/legacy-catalog-dir/catalog/sample-entry/.kanon +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalog/legacy-catalog-dir/repo-specs/sample.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalogs/zero-pep440-tags/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/catalogs/zero-pep440-tags/repo-specs/entry-a/entry-a-marketplace.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/completion/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/errors/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/errors/conflict-detected.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/errors/entry-not-found.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/errors/lockfile-hash-mismatch.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/errors/lockfile-sha-unreachable.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/errors/missing-catalog-source.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/errors/missing-required-metadata-field.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/errors/source-collision.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/errors/zero-pep440-tags-under-prefix.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-add.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-catalog-audit.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-catalog.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-clean.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-completion.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-doctor.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-install.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-marketplace.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-outdated.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-remove.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-search.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/help/kanon-why.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/repo/.gitignore +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/repo/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/repo/linter-test-bad.invalid-yaml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/repo/linter-test-bad.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/repo/linter-test-bad.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/repo/sample-manifest.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/repo/sample-project-config.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/repo/test.gitconfig +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/fixtures/repo/version_constraints_data.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_add_alias_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_alias_consumer_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_argparse_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_argparse_help.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_ci_runs_operator_path_tests.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_clean_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_cli_entry_point.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_completion_snapshots.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_default_branch_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_env_int_guard_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_error_snapshots.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_exit_code_matrix.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_groups_filter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_help_text_contract.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_home_flag_unwritable_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_init_default_branch_prerequisite_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_install_hermetic_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_install_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_install_real_kanon.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_install_v3_lock_fail_fast_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_kanon_home_store_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_kanon_repo_cli.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_kanon_repo_e2e.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_kanon_repo_lifecycle_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_lifecycle_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_make_operator_path_targets.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_marketplace_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_matrix_traceability_complete.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_provider_agnostic.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_abandon_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_abandon_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_abandon_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_branches_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_branches_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_branches_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_checkout_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_checkout_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_checkout_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_cherry_pick_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_cherry_pick_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_cherry_pick_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_diff_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_diff_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_diff_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_diffmanifests_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_diffmanifests_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_diffmanifests_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_dir_override.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_download_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_download_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_download_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_envsubst_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_envsubst_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_envsubst_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_exit_codes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_forall_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_forall_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_forall_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_gc_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_gc_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_gc_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_grep_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_grep_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_grep_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_help_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_help_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_help_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_info_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_info_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_info_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_init_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_init_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_init_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_init_mirror.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_list_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_list_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_list_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_manifest_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_manifest_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_manifest_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_manifest_revision_as_tag.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_overview_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_overview_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_overview_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_passthrough.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_prune_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_prune_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_prune_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_rebase_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_rebase_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_rebase_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_selfupdate_disabled.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_selfupdate_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_selfupdate_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_selfupdate_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_smartsync_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_smartsync_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_smartsync_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_stage_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_stage_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_stage_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_start_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_start_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_start_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_status_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_status_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_status_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_sync_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_sync_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_sync_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_upload_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_upload_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_repo_upload_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_singular_catalog_source_inert.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_stdout_stderr_discipline.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_update_alert_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_validate_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_validate_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_validate_lockfile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_validate_marketplace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_validate_xml_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_validate_xml_repo_root.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/functional/test_zero_source_clean_error.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/conftest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/fixtures/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/fixtures/synthetic/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/fixtures/synthetic/conftest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/fixtures/synthetic/drift.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/fixtures/synthetic/test_synthetic_pytest_fixtures.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/fixtures/synthetic/upgrade_versioned.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/provider_allowlist.txt +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/conftest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_bug_fixes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_consolidated_constraints_e2e.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_envsubst_integration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_import_functional.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_linkfile_copyfile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_linkfile_exclude_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_manifest_parsing.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_process_isolation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_repo_module_smoke.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_repo_pipeline.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_repo_run_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_repo_sync_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_version_constraints_integration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_annotation_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_contactinfo_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_copyfile_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_default_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_extend_project_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_include_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_linkfile_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_manifest_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_manifest_server_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_notice_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_project_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_remote_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_remove_project_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_repo_hooks_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_submanifest_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/repo/test_xml_superproject_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_add_core.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_add_dry_run.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_add_env_var_detection.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_add_zero_tags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_auto_discovery.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_background_refresh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_cache_clock_skew.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_cache_layout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_catalog_audit_entry_uniqueness.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_catalog_audit_framework.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_catalog_audit_legacy_dir.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_catalog_audit_metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_catalog_audit_remote_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_catalog_audit_source_name.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_catalog_audit_strict.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_catalog_audit_tag_format.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_catalog_constraints.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_ci_validation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_clean_env_override_cleanup.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_clean_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_clean_paths.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_complete_cached_catalogs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_complete_catalog_entries.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_complete_catalog_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_complete_lockfile_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_complete_project_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_complete_source_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_completion_powershell_subcommand.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_completion_subcommand.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_completion_zsh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_concurrency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_concurrency_serialization.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_copyfile_fs_effects.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_cross_platform_contract.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_doc_validation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_doctor_cache_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_doctor_cache_flags_workspace_independent.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_doctor_consistency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_doctor_default_subcheck_output.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_doctor_effective_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_doctor_prune_cache.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_doctor_remote_check.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_envsubst_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_fs_fault_extended.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_fs_fault_injection.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_full_lifecycle_synthetic.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_full_user_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_git_fault_injection.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_git_retry_env.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_gitignore_idempotency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_home_flag_store_relocation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_after_add.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_env_var_resolution.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_include_cycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_include_diamond.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_lock_file_derivation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_lockfile_replay.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_marketplace_registration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_no_kanon_remediation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_optional_vars.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_path_conflict_integration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_paths.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_per_alias_gitbase.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_reconcile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_refresh_lock.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_refresh_lock_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_remote_url_policy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_required_vars.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_install_strict.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_json_output_stream_discipline.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_kanon_add_placeholder_handling.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_kanon_clean_embedded.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_kanon_dir_collision.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_kanon_full_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_kanon_install_embedded.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_kanonenv_parsing.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_lifecycle_recovery.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_linkfile_fs_effects.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_list_all_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_list_all_versions_canonical.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_list_all_versions_malformed_revision_resilience.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_list_default.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_list_detail.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_list_filter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_list_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_list_synthetic_catalog_variants.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_list_tree.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_lockfile_roundtrip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_marketplace_install.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_marketplace_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_marketplace_orphan_prune.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_midtoken_bash.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_midtoken_zsh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_misc_features.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_multi_source_aggregation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_no_bundled_catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_no_default_catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_no_hardcoded_org_values.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_observability.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_outdated.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_outdated_branch_drift.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_outdated_fail_on_upgrade.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_outdated_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_outdated_refs_tags_revision_parsing.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_platform_parity.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_preamble_bash.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_preamble_zsh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_remove_core.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_remove_dry_run.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_remove_force_integration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_signal_handling.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_synthetic_drift_fixture.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_synthetic_upgrade_versioned_fixture.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_unicode_encoding.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_validate_marketplace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_validate_marketplace_revision_existence.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_validate_metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_validate_xml.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_version_resolution.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_version_widened_bare_pep440.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_wheel_e2e.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_why_ambiguous.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_why_chain_walker.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_why_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_why_live_resolve.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_why_not_found_suggestion.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/integration/test_workspace_dir_env.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f1_s2_t5_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f5_s2_t7_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s1_t1_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s1_t2_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s1_t3_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s1_t4_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s2_t1_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s2_t2_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s2_t3_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s2_t4_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s2_t5_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s2_t6_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s3_t1_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_f6_s3_t2_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/regression/test_e0_install_relative_regression.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/_rp_helpers.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_ad.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_bs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_cd.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_content_pins.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_cs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_doctor_cache.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_doctor_journey.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_ec.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_ep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_ev.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_hv.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_ic.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_id.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_ks.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_lf.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_lockfile_lifecycle.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_marketplace_direct_checkout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_mk.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_ms.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_ns_marketplace_and_global_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_outdated_two_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_pk.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rc.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_refresh_lock_existing_checkout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rls_exact_vs_range.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_abandon.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_branches.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_checkout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_cherry_pick.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_diff.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_diffmanifests.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_download.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_envsubst.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_forall.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_gc.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_grep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_help.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_info.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_init.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_list.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_manifest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_overview.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_prune.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_rebase.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_smartsync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_stage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_start.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_status.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_sync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_upload.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rp_wrap.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_rx.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_scenario_coverage_meta.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_search_multi_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_tc_bootstrap.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_tc_clean.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_tc_install.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_tc_validate.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_uj.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_va.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_va_validate_lockfile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_why_surface_query.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_why_url_path.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/scenarios/test_why_url_path_placeholder.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/security/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/security/test_security_hardening.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/test_wheel_layout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/commands/test_repo_dir_resolution.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/conftest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/conftest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/fixtures/.gitignore +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/fixtures/README.md +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/fixtures/sample-manifest.xml +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/fixtures/sample-project-config.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/fixtures/test.gitconfig +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/fixtures/version_constraints_data.json +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/functional/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/functional/test_features.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/subcmds/__init__.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/subcmds/test_init_mirror.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/subcmds/test_manifest_revision_as_tag.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/subcmds/test_manifest_revision_as_tag_pep440.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/subcmds/test_selfupdate_stub.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_abandon_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_branches_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug10_selfupdate_incompatible.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug11_race_condition.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug12_backup_preserved.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug13_init_reinit_warning.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug14_non_tty_log.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug15_prerelease_docs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug16_nested_var_warning.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug18_envsubst_double_parse.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug19_glob_src_error.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug1_envsubst_malformed_xml.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug20_glob_dest_file.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug2_linkfile_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug3_execv_replaces_process.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug4_symlink_overwrite.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug5_empty_envsubst_list.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug6_undefined_env_vars.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug7_git_ls_remote_retry.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug8_ls_remote_stderr.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_bug9_constraint_resolution_cache.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_checklocalpath_rules_1_5.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_checklocalpath_rules_6_11.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_checkout_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_cherrypick_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_color.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_conftest_fixtures.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_diffmanifests_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_doc_validate_git_preconditions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_download_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_editor.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_embedded_mode.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_envsubst_basic.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_envsubst_edge.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_envsubst_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_error.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_event_log.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_event_log_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_fetch.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_fixture_files.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_forall_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_git_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_git_config.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_git_refs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_git_superproject.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_git_trace2_event_log.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_gitconfig_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_grep_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_harness_smoke.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_hooks.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_import_verification.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_imports.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_include_path_resolution.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_info_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_init_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_list_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_main.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_main_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_main_init_download_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_makefile_lint_format.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_makefile_structure.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_makefile_test_targets.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_manifest_coverage_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_manifest_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_manifest_doc_rp_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_manifest_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_manifest_subcmd_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_manifest_xml.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_manifest_xml_pep440.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_medium_files_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_mkdtemp_cleanup.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_overview_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_package_structure.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_pager.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_parselist.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_pep440_edge_1.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_pep440_edge_2.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_pep440_ops_ge.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_pep440_ops_rest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_platform_utils.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_process_isolation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_progress.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project_coverage_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project_coverage_threshold.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project_deep_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project_final_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project_integration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project_metaproject_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project_methods.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_project_sync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_prune_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_rebase_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_remaining_coverage_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_repo_envsubst_api.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_repo_logging.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_repo_run_api.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_repo_sync_api.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_repo_trace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_revision_inheritance.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_revision_tag_branch_sha.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_ruff_config.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_selfupdate_embedded.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_selfupdate_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_small_files_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_ssh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_ssh_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_stage_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_stage_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_start_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_status_coverage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_status_gaps.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_status_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmd_imports.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_abandon.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_branches.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_checkout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_cherry_pick.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_diff.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_diffmanifests.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_download.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_envsubst.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_forall.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_gc.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_grep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_help.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_info.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_init.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_list.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_manifest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_overview.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_prune.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_rebase.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_selfupdate.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_smartsync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_stage.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_start.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_status.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_sync.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_subcmds_upload.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_superproject_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_sync_coverage_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_sync_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_sync_deep_boost.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_sync_massive.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_upload_deep.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_version_consolidation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_version_constraints.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_wheel_contents.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_wrapper.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_annotation_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_annotation_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_annotation_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_contactinfo_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_contactinfo_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_contactinfo_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_copyfile_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_copyfile_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_copyfile_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_default_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_default_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_default_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_extend_project_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_extend_project_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_extend_project_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_fault_malformed.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_fault_structural.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_include_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_include_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_include_cycles.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_include_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_linkfile_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_linkfile_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_linkfile_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_manifest_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_manifest_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_manifest_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_manifest_server_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_manifest_server_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_manifest_server_flow.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_manifest_server_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_notice_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_notice_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_notice_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_project_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_project_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_project_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_remote_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_remote_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_remote_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_remove_project_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_remove_project_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_remove_project_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_repo_hooks_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_repo_hooks_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_repo_hooks_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_submanifest_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_submanifest_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_submanifest_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_superproject_attributes.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_superproject_crossref.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_superproject_flow.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xml_superproject_happy.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xmlbool.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_xmlint.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/repo/test_yamllint_config.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_accessed_at_coalescing.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_add.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_add_collision.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_add_zero_tags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_background_refresh.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_bare_semver_to_tag.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_cache.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_cache_layout.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_cache_ttl.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_cached_catalogs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_audit_check_parser.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_audit_entry_uniqueness.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_audit_framework.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_audit_legacy_dir.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_audit_metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_audit_project_tag_format.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_audit_remote_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_audit_source_name.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_audit_strict.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_audit_tag_format.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_catalog_source_parsing.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_check_no_comments.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_ci_workflows.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_clean.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_clean_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_cli_args.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_cli_help_format.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_cli_json_stream_discipline.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_complete_cached_catalogs.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_complete_catalog_entries.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_complete_catalog_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_complete_lockfile_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_complete_project_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_complete_source_names.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_completion.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_completion_sanitization.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_completion_subcommand.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_concurrency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_conftest_scrubber.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_constants_doctor_subcheck.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_constants_env_int.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_constants_install_after_add.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_constants_outdated_refs_tags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_constants_why_lockfile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_coverage_gaps.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_derive_source_name.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_discover.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_discover_source_names_missing_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_docs_embedded_architecture.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_docs_remaining_and_catalog.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_doctor.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_doctor_cache_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_doctor_completion_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_doctor_completion_staleness.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_doctor_consistency.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_doctor_coverage_gaps.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_doctor_effective_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_doctor_remote_reachability.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_env_isolation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_envsubst_subcommand.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_git_runner.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_home_flag.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_include_walker.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_color_default.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_conflict_detection.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_https_enforcement.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_placeholder_validation.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_reconcile_decision.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_refresh_lock.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_refresh_lock_source.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_state_matrix.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_strict_flags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_install_strict_lock_orphan_naming.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_integration_testing_doc_manifest_paths.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_integration_testing_doc_s2_t14.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_integration_testing_doc_s2_t4.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_integration_testing_doc_s2_t5.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_integration_testing_doc_s2_t6.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_integration_testing_doc_s2_t7.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_integration_testing_doc_s2_tier1.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_isolation_fixtures.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_kanon_hash.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_kanonenv.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_kanonenv_advanced_edge_cases.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_kanonenv_edge_cases.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_kanonenv_writer.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_levenshtein.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_lock_file_path.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_lockfile.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_lockfile_coverage_gaps.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_lockfile_schema_migration.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_manifest.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_marketplace.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_marketplace_cmd.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_marketplace_install.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_marketplace_non_plugin_skip.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_marketplace_validator.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_midtoken_splitter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_outdated.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_outdated_branch_pinned.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_outdated_fail_on_upgrade.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_outdated_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_pep440_filter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_powershell.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_pre_push_hook.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_preamble.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_preamble_semver_tags.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_provider_agnosticism.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_pyproject_build_config.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_remote_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_remove.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_remove_dry_run.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_remove_force.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_remove_line_endings.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_repo.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_repo_abspath.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_repo_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_resolve_catalog_dir.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_revision_resolve.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_rx_catalog_sub_repo.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_sanitize.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_search_all_versions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_search_coverage_gaps.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_search_detail.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_search_filter.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_search_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_search_tree.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_spawn.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_url.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_validate.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_validate_command.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_validate_metadata.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_version.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_version_constraint_errors.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_why.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_why_ambiguity.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_why_format_json.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_why_suggestions.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tests/unit/test_xml_validator.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tools/lint/check_no_comments.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/tools/test_tmp_monitor.py +0 -0
- {kanon_cli-3.2.0 → kanon_cli-3.3.0}/uv.lock +0 -0
|
@@ -2,8 +2,111 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
## v3.3.0 (2026-07-17)
|
|
6
|
+
|
|
7
|
+
### Feature
|
|
8
|
+
|
|
9
|
+
* feat: kanon list command + usage telemetry, full install-graph capture, and update-warning enhancement (#91)
|
|
10
|
+
|
|
11
|
+
* feat: add usage telemetry, full install-graph capture, and update-warning enhancement
|
|
12
|
+
|
|
13
|
+
Emit one structured usage-telemetry event per CLI command to the Caylent
|
|
14
|
+
collector, fully capturing what was installed (every direct source plus every
|
|
15
|
+
transitive repo package with URLs and resolved content SHAs), and enhance the
|
|
16
|
+
"update available" warning.
|
|
17
|
+
|
|
18
|
+
Telemetry (new core/telemetry.py):
|
|
19
|
+
- Hooked via try/finally around dispatch in cli.py; captures command, subcommand,
|
|
20
|
+
boolean flag names, allowlisted flag values, outcome (exit code/status/error
|
|
21
|
+
class/duration), runtime environment, and credential-stripped git provenance.
|
|
22
|
+
- OTLP/HTTP logs JSON with one log record whose body is a flat
|
|
23
|
+
{tool,timestamp,event_type,payload} object (payload a JSON string); POSTed via
|
|
24
|
+
stdlib urllib in a detached, non-blocking, silent, never-fail background
|
|
25
|
+
process (utils/spawn.spawn_detached), HTTPS-only guard, timeouts + body cap.
|
|
26
|
+
- Auto opted-in by default; the only opt-out is KANON_TELEMETRY_DISABLED (no
|
|
27
|
+
--no-telemetry flag). KANON_TELEMETRY_ENDPOINT / --telemetry-endpoint and
|
|
28
|
+
KANON_TELEMETRY_DEBUG / --telemetry-debug are supported.
|
|
29
|
+
- Zero-secret allowlist: never raw argv, keys, tokens, credentials, env-var
|
|
30
|
+
values, or file contents; every URL is credential-stripped.
|
|
31
|
+
|
|
32
|
+
Full install-graph capture (core/install.py):
|
|
33
|
+
- Populate SourceEntry.projects on install by resolving project -> remote -> URL
|
|
34
|
+
from the already-synced manifests (walk_includes_collecting_remotes +
|
|
35
|
+
join_project_repo_url + canonicalize_repo_url) joined with the captured content
|
|
36
|
+
pins. This also fixes `kanon why` showing an empty project layer on
|
|
37
|
+
install-written lockfiles. Telemetry emits payload.install_graph and a
|
|
38
|
+
flattened payload.installed_packages[] (direct + transitive), capped under the
|
|
39
|
+
collector body limit with install_graph_truncated on overflow.
|
|
40
|
+
|
|
41
|
+
Update-warning enhancement (core/update_check.py):
|
|
42
|
+
- Yellow banner with the current version in red and the latest in green; a red
|
|
43
|
+
"no internet access -- could not check for updates" notice on a failed fetch,
|
|
44
|
+
shown at most once per window; default KANON_UPDATE_CHECK_TTL lowered to 3h.
|
|
45
|
+
|
|
46
|
+
Docs: new docs/privacy.md (collected fields, encryption, opt-out) linked from
|
|
47
|
+
README; telemetry rows in docs/cli-reference.md and docs/configuration.md;
|
|
48
|
+
regenerated help + completion snapshots.
|
|
49
|
+
|
|
50
|
+
* test: include telemetry global flags in bash completion expectation
|
|
51
|
+
|
|
52
|
+
The new --telemetry-debug / --telemetry-endpoint global flags now appear in the
|
|
53
|
+
top-level bash completion, so the exact-match global_flags row in
|
|
54
|
+
test_completion_bash.py is extended to include them.
|
|
55
|
+
|
|
56
|
+
* test: use provider-neutral remote name in build_project_entries fixture
|
|
57
|
+
|
|
58
|
+
The provider-agnostic host gate forbids the bare token 'gh'; rename the fixture
|
|
59
|
+
manifest remote from 'gh' to 'origin' so the manifest XML fixtures carry no
|
|
60
|
+
provider-specific reference.
|
|
61
|
+
|
|
62
|
+
* fix: record real command outcome in telemetry and emit for --version/--help/bare invocations
|
|
63
|
+
|
|
64
|
+
* feat: add kanon list command (declared vs installed source inventory)
|
|
65
|
+
|
|
66
|
+
Add `kanon list`, the flat inventory command that reconciles the sources
|
|
67
|
+
declared in .kanon against those installed in .kanon.lock and tags each one
|
|
68
|
+
installed / not-installed / orphan -- the kanon analogue of `pip list` /
|
|
69
|
+
`npm ls` / `poetry show`.
|
|
70
|
+
|
|
71
|
+
Flags: --declared, --tree, --status <installed|not-installed|orphan>,
|
|
72
|
+
--format <table|json>, --kanon-file, --lock-file. Every failure path yields a
|
|
73
|
+
clean single-prefixed ERROR (no traceback). The command emits usage telemetry
|
|
74
|
+
like every other command (command=list, --tree flag, --format/--status values
|
|
75
|
+
via the flag-value allowlist).
|
|
76
|
+
|
|
77
|
+
The declared-vs-installed partition reuses a new non-raising
|
|
78
|
+
reconcile_declared_installed() extracted from check_lockfile_consistency (one
|
|
79
|
+
source of truth). Covered by unit/functional/integration/scenario tests plus a
|
|
80
|
+
real-git add->install->edit->list journey; list.py at 100% coverage. Help and
|
|
81
|
+
shell-completion snapshots and docs updated.
|
|
82
|
+
|
|
83
|
+
The 3.0.0 list->search rename left guards asserting `list` is an unknown
|
|
84
|
+
command; those are updated to reflect `list` now being a distinct command.
|
|
85
|
+
|
|
86
|
+
* test: isolate test subprocesses from coverage subprocess measurement
|
|
87
|
+
|
|
88
|
+
Under `pytest --cov` (make test) pytest-cov and coverage export COV_CORE_* /
|
|
89
|
+
COVERAGE_PROCESS_* so spawned subprocesses auto-start coverage. A measured
|
|
90
|
+
`kanon` subprocess then writes a .coverage-data directory into its working
|
|
91
|
+
directory -- resolved relative to the child CWD on some filesystems -- which
|
|
92
|
+
behavioural subprocess tests that inspect the child filesystem
|
|
93
|
+
(`kanon repo status --orphans`) or parse its stderr (`--telemetry-debug` JSON)
|
|
94
|
+
then trip over, non-deterministically across OS / filesystem.
|
|
95
|
+
|
|
96
|
+
Strip the coverage subprocess-trigger variables from the child environment in
|
|
97
|
+
the functional and scenario subprocess runners and the telemetry-journey env
|
|
98
|
+
builder via a shared strip_subprocess_coverage_env helper. Behavioural CLI
|
|
99
|
+
subprocess tests do not need coverage of the child; the 90% coverage gate is
|
|
100
|
+
measured in-process on the unit tier, which uses its own runner and is
|
|
101
|
+
unaffected. ([`57246f8`](https://github.com/caylent-solutions/kanon/commit/57246f8a8a46b99ad2b35a954289d7a9e7d1966c))
|
|
102
|
+
|
|
103
|
+
|
|
5
104
|
## v3.2.0 (2026-07-13)
|
|
6
105
|
|
|
106
|
+
### Chore
|
|
107
|
+
|
|
108
|
+
* chore(release): 3.2.0 ([`b503e3c`](https://github.com/caylent-solutions/kanon/commit/b503e3cf92479b6192b186ad6b2481563c916074))
|
|
109
|
+
|
|
7
110
|
### Feature
|
|
8
111
|
|
|
9
112
|
* feat(clean): ~/.kanon-home store rename, .kanon-dir guard, --purge/--purge-all (store-only teardown with no .kanon), no unconditional .gitignore (#89)
|
|
@@ -85,6 +188,12 @@ lifecycle also documents clean --purge-all running without a .kanon.
|
|
|
85
188
|
|
|
86
189
|
Co-authored-by: t <t@e.x> ([`d9b0ad1`](https://github.com/caylent-solutions/kanon/commit/d9b0ad1856ab58487b7ed3efdc3ff9d87b60b193))
|
|
87
190
|
|
|
191
|
+
### Unknown
|
|
192
|
+
|
|
193
|
+
* Merge pull request #90 from caylent-solutions/release-3.2.0
|
|
194
|
+
|
|
195
|
+
Release 3.2.0 ([`fb944e2`](https://github.com/caylent-solutions/kanon/commit/fb944e251cf650020070e29cb28a26cbffc886da))
|
|
196
|
+
|
|
88
197
|
|
|
89
198
|
## v3.1.1 (2026-06-27)
|
|
90
199
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kanon-cli
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.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
|
|
@@ -55,6 +55,7 @@ via declarative manifests.
|
|
|
55
55
|
- [kanon remove](#kanon-remove)
|
|
56
56
|
- [kanon install](#kanon-install)
|
|
57
57
|
- [kanon clean](#kanon-clean)
|
|
58
|
+
- [kanon list](#kanon-list)
|
|
58
59
|
- [kanon outdated](#kanon-outdated)
|
|
59
60
|
- [kanon why](#kanon-why)
|
|
60
61
|
- [kanon doctor](#kanon-doctor)
|
|
@@ -208,6 +209,7 @@ persistent installation and advanced options, see
|
|
|
208
209
|
| `kanon search` | List packages available in a catalog or show detail for one | [docs/list-and-add.md](docs/list-and-add.md) |
|
|
209
210
|
| `kanon add` | Add a package (with optional version constraint) to `.kanon` | [docs/list-and-add.md](docs/list-and-add.md) |
|
|
210
211
|
| `kanon remove` | Remove a package from `.kanon` | [docs/list-and-add.md](docs/list-and-add.md) |
|
|
212
|
+
| `kanon list` | List sources declared in `.kanon` vs installed in `.kanon.lock` (installed / not-installed / orphan) | [docs/cli-reference.md](docs/cli-reference.md#kanon-list) |
|
|
211
213
|
| `kanon outdated` | Show packages in `.kanon` that have newer versions available | [docs/outdated-and-why.md](docs/outdated-and-why.md) |
|
|
212
214
|
| `kanon why` | Explain why a specific package version was resolved | [docs/outdated-and-why.md](docs/outdated-and-why.md) |
|
|
213
215
|
| `kanon install` | Resolve, clone, and symlink all packages; writes `.kanon.lock` | [docs/lockfile.md](docs/lockfile.md) |
|
|
@@ -593,6 +595,26 @@ store directory (default `~/.kanon-home`), removing only kanon-owned content
|
|
|
593
595
|
(`store/`, `cache/`, and the emptied root) and refusing unsafe `KANON_HOME`
|
|
594
596
|
paths such as your home directory or the filesystem root.
|
|
595
597
|
|
|
598
|
+
### kanon list
|
|
599
|
+
|
|
600
|
+
Lists the sources declared in `.kanon` against those installed in `.kanon.lock`,
|
|
601
|
+
tagging each `installed`, `not-installed`, or `orphan` -- the kanon analogue of
|
|
602
|
+
`pip list` / `npm ls`.
|
|
603
|
+
|
|
604
|
+
```bash
|
|
605
|
+
kanon list # every source, declared vs installed, tagged
|
|
606
|
+
kanon list --declared # only sources declared in .kanon (no orphans)
|
|
607
|
+
kanon list --status orphan # only sources in the lock no longer declared
|
|
608
|
+
kanon list --tree # expand installed sources to transitive packages
|
|
609
|
+
kanon list --format json # machine-readable JSON
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
A source is `installed` when it is in both files, `not-installed` when declared
|
|
613
|
+
but not yet locked (run `kanon install`), and `orphan` when locked but no longer
|
|
614
|
+
declared. Key options: `--declared`, `--tree`, `--status {installed,not-installed,orphan}`,
|
|
615
|
+
`--format {table,json}`, `--kanon-file`, `--lock-file`. See
|
|
616
|
+
[docs/cli-reference.md](docs/cli-reference.md#kanon-list).
|
|
617
|
+
|
|
596
618
|
### kanon outdated
|
|
597
619
|
|
|
598
620
|
Compares each source in `.kanon` against the catalog and emits a table of
|
|
@@ -1483,6 +1505,23 @@ version bumps.
|
|
|
1483
1505
|
supported; see [Platform support](#platform-support) and use WSL2)
|
|
1484
1506
|
- [Contributing](CONTRIBUTING.md) -- How to create and maintain Kanon
|
|
1485
1507
|
packages and marketplaces
|
|
1508
|
+
- [Privacy & Telemetry](docs/privacy.md) -- What usage telemetry kanon
|
|
1509
|
+
collects, why, how it is encrypted, and how to turn it off
|
|
1510
|
+
|
|
1511
|
+
---
|
|
1512
|
+
|
|
1513
|
+
## Usage telemetry
|
|
1514
|
+
|
|
1515
|
+
kanon emits one anonymised-by-design usage event per command to help the
|
|
1516
|
+
maintainers understand which commands and package sources are used. Telemetry
|
|
1517
|
+
is **on by default**, runs **silently** and **non-blocking**, never blocks or
|
|
1518
|
+
fails your command, and serialises only an explicit allowlist of kanon-computed
|
|
1519
|
+
fields -- never raw argv, credentials, keys, tokens, env-var values, or file
|
|
1520
|
+
contents (every URL is credential-stripped before it is sent).
|
|
1521
|
+
|
|
1522
|
+
Disable it entirely by setting `KANON_TELEMETRY_DISABLED=1`. See
|
|
1523
|
+
[docs/privacy.md](docs/privacy.md) for the full list of collected fields and the
|
|
1524
|
+
transit/at-rest encryption.
|
|
1486
1525
|
|
|
1487
1526
|
---
|
|
1488
1527
|
|
|
@@ -33,6 +33,7 @@ via declarative manifests.
|
|
|
33
33
|
- [kanon remove](#kanon-remove)
|
|
34
34
|
- [kanon install](#kanon-install)
|
|
35
35
|
- [kanon clean](#kanon-clean)
|
|
36
|
+
- [kanon list](#kanon-list)
|
|
36
37
|
- [kanon outdated](#kanon-outdated)
|
|
37
38
|
- [kanon why](#kanon-why)
|
|
38
39
|
- [kanon doctor](#kanon-doctor)
|
|
@@ -186,6 +187,7 @@ persistent installation and advanced options, see
|
|
|
186
187
|
| `kanon search` | List packages available in a catalog or show detail for one | [docs/list-and-add.md](docs/list-and-add.md) |
|
|
187
188
|
| `kanon add` | Add a package (with optional version constraint) to `.kanon` | [docs/list-and-add.md](docs/list-and-add.md) |
|
|
188
189
|
| `kanon remove` | Remove a package from `.kanon` | [docs/list-and-add.md](docs/list-and-add.md) |
|
|
190
|
+
| `kanon list` | List sources declared in `.kanon` vs installed in `.kanon.lock` (installed / not-installed / orphan) | [docs/cli-reference.md](docs/cli-reference.md#kanon-list) |
|
|
189
191
|
| `kanon outdated` | Show packages in `.kanon` that have newer versions available | [docs/outdated-and-why.md](docs/outdated-and-why.md) |
|
|
190
192
|
| `kanon why` | Explain why a specific package version was resolved | [docs/outdated-and-why.md](docs/outdated-and-why.md) |
|
|
191
193
|
| `kanon install` | Resolve, clone, and symlink all packages; writes `.kanon.lock` | [docs/lockfile.md](docs/lockfile.md) |
|
|
@@ -571,6 +573,26 @@ store directory (default `~/.kanon-home`), removing only kanon-owned content
|
|
|
571
573
|
(`store/`, `cache/`, and the emptied root) and refusing unsafe `KANON_HOME`
|
|
572
574
|
paths such as your home directory or the filesystem root.
|
|
573
575
|
|
|
576
|
+
### kanon list
|
|
577
|
+
|
|
578
|
+
Lists the sources declared in `.kanon` against those installed in `.kanon.lock`,
|
|
579
|
+
tagging each `installed`, `not-installed`, or `orphan` -- the kanon analogue of
|
|
580
|
+
`pip list` / `npm ls`.
|
|
581
|
+
|
|
582
|
+
```bash
|
|
583
|
+
kanon list # every source, declared vs installed, tagged
|
|
584
|
+
kanon list --declared # only sources declared in .kanon (no orphans)
|
|
585
|
+
kanon list --status orphan # only sources in the lock no longer declared
|
|
586
|
+
kanon list --tree # expand installed sources to transitive packages
|
|
587
|
+
kanon list --format json # machine-readable JSON
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
A source is `installed` when it is in both files, `not-installed` when declared
|
|
591
|
+
but not yet locked (run `kanon install`), and `orphan` when locked but no longer
|
|
592
|
+
declared. Key options: `--declared`, `--tree`, `--status {installed,not-installed,orphan}`,
|
|
593
|
+
`--format {table,json}`, `--kanon-file`, `--lock-file`. See
|
|
594
|
+
[docs/cli-reference.md](docs/cli-reference.md#kanon-list).
|
|
595
|
+
|
|
574
596
|
### kanon outdated
|
|
575
597
|
|
|
576
598
|
Compares each source in `.kanon` against the catalog and emits a table of
|
|
@@ -1461,6 +1483,23 @@ version bumps.
|
|
|
1461
1483
|
supported; see [Platform support](#platform-support) and use WSL2)
|
|
1462
1484
|
- [Contributing](CONTRIBUTING.md) -- How to create and maintain Kanon
|
|
1463
1485
|
packages and marketplaces
|
|
1486
|
+
- [Privacy & Telemetry](docs/privacy.md) -- What usage telemetry kanon
|
|
1487
|
+
collects, why, how it is encrypted, and how to turn it off
|
|
1488
|
+
|
|
1489
|
+
---
|
|
1490
|
+
|
|
1491
|
+
## Usage telemetry
|
|
1492
|
+
|
|
1493
|
+
kanon emits one anonymised-by-design usage event per command to help the
|
|
1494
|
+
maintainers understand which commands and package sources are used. Telemetry
|
|
1495
|
+
is **on by default**, runs **silently** and **non-blocking**, never blocks or
|
|
1496
|
+
fails your command, and serialises only an explicit allowlist of kanon-computed
|
|
1497
|
+
fields -- never raw argv, credentials, keys, tokens, env-var values, or file
|
|
1498
|
+
contents (every URL is credential-stripped before it is sent).
|
|
1499
|
+
|
|
1500
|
+
Disable it entirely by setting `KANON_TELEMETRY_DISABLED=1`. See
|
|
1501
|
+
[docs/privacy.md](docs/privacy.md) for the full list of collected fields and the
|
|
1502
|
+
transit/at-rest encryption.
|
|
1464
1503
|
|
|
1465
1504
|
---
|
|
1466
1505
|
|
|
@@ -15,6 +15,12 @@ are registered once via `kanon_cli.core.cli_args` so every parser exposes them.
|
|
|
15
15
|
| `--no-color` | `NO_COLOR` | auto | Disable ANSI color. Any non-empty `NO_COLOR` also disables color. |
|
|
16
16
|
| `--no-update-check` | `KANON_SKIP_UPDATE_CHECK` | off | Skip the best-effort PyPI "update available" check. The flag is equivalent to setting `KANON_SKIP_UPDATE_CHECK=1`. |
|
|
17
17
|
| `--home` / `--store-dir <path>` | `KANON_HOME` | `~/.kanon-home` | Shared kanon home root (content-addressed store plus caches). `--store-dir` is an accepted alias of `--home`. Precedence: flag > `KANON_HOME` env > `~/.kanon-home`. |
|
|
18
|
+
| `--telemetry-debug` | `KANON_TELEMETRY_DEBUG` | off | Print the exact usage-telemetry JSON that would be sent to stderr for this invocation (still non-blocking). |
|
|
19
|
+
| `--telemetry-endpoint <url>` | `KANON_TELEMETRY_ENDPOINT` | `https://collector.platform.solutions.caylent.com/v1/logs` | Override the usage-telemetry collector endpoint (`https://` only). Flag wins over the env var. |
|
|
20
|
+
|
|
21
|
+
Usage telemetry is on by default and can be disabled entirely by setting
|
|
22
|
+
`KANON_TELEMETRY_DISABLED` to a truthy value (there is no disable flag). See
|
|
23
|
+
[docs/privacy.md](privacy.md) for exactly what is collected and why.
|
|
18
24
|
|
|
19
25
|
## Shared Argument Factories
|
|
20
26
|
|
|
@@ -68,6 +74,9 @@ completion variables), see [docs/configuration.md](configuration.md).
|
|
|
68
74
|
| `KANON_CATALOG_SOURCES` | Remote catalog source(s) as `<git_url>@<ref>`, one entry per line. Sets the default for every command that accepts `--catalog-source`; the resolving commands require exactly one entry unless `--catalog-source` is passed. | (none) |
|
|
69
75
|
| `KANON_HOME` | Shared kanon home root (store plus caches). Overridden by the `--home` / `--store-dir` flag. | `~/.kanon-home` |
|
|
70
76
|
| `KANON_SKIP_UPDATE_CHECK` | Set to `1` to skip the PyPI update-available check (same effect as `--no-update-check`). | (unset) |
|
|
77
|
+
| `KANON_TELEMETRY_DISABLED` | Set to a truthy value (`1`/`true`/`yes`/`on`) to disable usage telemetry entirely. The only opt-out; there is no disable flag. See [docs/privacy.md](privacy.md). | (unset) |
|
|
78
|
+
| `KANON_TELEMETRY_ENDPOINT` | Usage-telemetry collector endpoint (`https://` only). Overridden by `--telemetry-endpoint`. | `https://collector.platform.solutions.caylent.com/v1/logs` |
|
|
79
|
+
| `KANON_TELEMETRY_DEBUG` | Set to a truthy value to print the would-send telemetry JSON to stderr (same effect as `--telemetry-debug`). | (unset) |
|
|
71
80
|
| `KANON_OUTDATED_FORMAT` | Default output format for `kanon outdated` (`table` or `json`). Overridden by `--format`. | `table` |
|
|
72
81
|
| `KANON_OUTDATED_JSON_INDENT` | JSON indentation (number of spaces) used by `kanon outdated --format json`. | `2` |
|
|
73
82
|
| `KANON_WHY_FORMAT` | Default output format for `kanon why` (`text` or `json`). Overridden by `--format`. | `text` |
|
|
@@ -129,6 +138,76 @@ and operating systems.
|
|
|
129
138
|
|
|
130
139
|
---
|
|
131
140
|
|
|
141
|
+
### `kanon list`
|
|
142
|
+
|
|
143
|
+
List the sources declared in `.kanon` against the sources installed in
|
|
144
|
+
`.kanon.lock`, tagging each with its status. This is the flat inventory
|
|
145
|
+
command -- the kanon analogue of `pip list` / `npm ls` / `poetry show`. It
|
|
146
|
+
complements [`kanon why`](#kanon-why) (the dependency graph),
|
|
147
|
+
[`kanon outdated`](#kanon-outdated) (version staleness), and `kanon validate
|
|
148
|
+
lockfile` (which *fails* on the same declared-vs-installed drift this command
|
|
149
|
+
merely reports).
|
|
150
|
+
|
|
151
|
+
**Status tags:**
|
|
152
|
+
|
|
153
|
+
| Status | Meaning |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `installed` | declared in `.kanon` **and** present in `.kanon.lock` |
|
|
156
|
+
| `not-installed` | declared in `.kanon` but not yet in the lock -- run `kanon install` |
|
|
157
|
+
| `orphan` | present in `.kanon.lock` but no longer declared in `.kanon` |
|
|
158
|
+
|
|
159
|
+
The status is computed from the same alias comparison that `kanon install` and
|
|
160
|
+
`kanon validate lockfile` enforce (`core/lockfile.py:reconcile_declared_installed`);
|
|
161
|
+
`list` presents the divergence read-only instead of failing on it. The tags
|
|
162
|
+
apply to the direct source aliases (transitive packages are only ever shown as
|
|
163
|
+
installed, under `--tree`).
|
|
164
|
+
|
|
165
|
+
**Flags:**
|
|
166
|
+
|
|
167
|
+
| Flag | Effect |
|
|
168
|
+
|---|---|
|
|
169
|
+
| _(none)_ | Show every source (the declared ∪ installed union), one row each. |
|
|
170
|
+
| `--declared` | Show only sources declared in `.kanon` (omit `orphan` sources). |
|
|
171
|
+
| `--tree` | Expand each installed source to its transitive packages (from the lock). |
|
|
172
|
+
| `--status <installed\|not-installed\|orphan>` | Show only sources with the given status. |
|
|
173
|
+
| `--format <table\|json>` | Output format (default `table`). `KANON_LIST_OUTPUT_FORMAT` sets the default; the flag wins. |
|
|
174
|
+
| `--kanon-file <path>` | Path to `.kanon` (default: auto-discovery walking up from the cwd; `KANON_KANON_FILE` overrides). |
|
|
175
|
+
| `--lock-file <path>` | Path to `.kanon.lock` (default `<kanon-file>.lock`; `KANON_LOCK_FILE` overrides). |
|
|
176
|
+
|
|
177
|
+
**Behaviour:**
|
|
178
|
+
|
|
179
|
+
1. **`.kanon` required** -- resolved via `--kanon-file`, the `KANON_KANON_FILE`
|
|
180
|
+
env var, or auto-discovery. When none is found the command exits `1` with a
|
|
181
|
+
clean `ERROR:` message.
|
|
182
|
+
2. **Lockfile optional** -- when `.kanon.lock` is absent every declared source is
|
|
183
|
+
reported `not-installed` and a note is written to stderr; the command still
|
|
184
|
+
exits `0`. An explicit `--lock-file` / `KANON_LOCK_FILE` that does not exist
|
|
185
|
+
is an error.
|
|
186
|
+
3. **Exit code** -- `0` for any successful inventory (including the empty and
|
|
187
|
+
not-yet-installed states); `1` for an unresolvable `.kanon`, an
|
|
188
|
+
unreadable/malformed lock, or an unrecognised `KANON_LIST_OUTPUT_FORMAT`.
|
|
189
|
+
|
|
190
|
+
**Examples:**
|
|
191
|
+
|
|
192
|
+
```console
|
|
193
|
+
$ kanon list
|
|
194
|
+
SOURCE | REF | STATUS
|
|
195
|
+
-------+----------------------+--------------
|
|
196
|
+
bar | 2.0.0 | not-installed
|
|
197
|
+
baz | 0.9.0 (cccccccccccc) | orphan
|
|
198
|
+
foo | 1.0.0 (aaaaaaaaaaaa) | installed
|
|
199
|
+
|
|
200
|
+
$ kanon list --status orphan
|
|
201
|
+
SOURCE | REF | STATUS
|
|
202
|
+
-------+----------------------+-------
|
|
203
|
+
baz | 0.9.0 (cccccccccccc) | orphan
|
|
204
|
+
|
|
205
|
+
$ kanon list --format json
|
|
206
|
+
{"sources":[{"alias":"foo","status":"installed","name":"foo", ...}]}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
132
211
|
### `kanon outdated`
|
|
133
212
|
|
|
134
213
|
Compare installed sources against the catalog and report which are behind.
|
|
@@ -24,6 +24,7 @@ This guide is for engineers who are comfortable with one or more of:
|
|
|
24
24
|
| Search | pip search | npm search | cargo search | kanon search |
|
|
25
25
|
| Add | pip install x==1.0 | npm i x@1.0 | cargo add x@1.0 | kanon add x@1.0 |
|
|
26
26
|
| Outdated | pip list -o | npm outdated | cargo outdated | kanon outdated |
|
|
27
|
+
| List installed | pip list | npm ls | cargo tree | kanon list |
|
|
27
28
|
|
|
28
29
|
## Where the model differs
|
|
29
30
|
|
|
@@ -294,6 +294,16 @@ filter, `kanon search --tree` exits with an error suggesting `--regex`,
|
|
|
294
294
|
`<substring>`, or `--max-depth 0`. Override with
|
|
295
295
|
`--no-filter-required`.
|
|
296
296
|
|
|
297
|
+
**`KANON_LIST_OUTPUT_FORMAT`** (default: `table`) -- Default output
|
|
298
|
+
format for `kanon list` (the declared-vs-installed inventory command).
|
|
299
|
+
Supported values: `table`, `json`. Overridden by the `--format` CLI
|
|
300
|
+
flag. Distinct from `KANON_LIST_FORMAT` above, which configures
|
|
301
|
+
`kanon search`'s output.
|
|
302
|
+
|
|
303
|
+
**`KANON_LIST_JSON_INDENT`** (default: `2`) -- Number of spaces per
|
|
304
|
+
indentation level in JSON output from `kanon list --format json`. Must
|
|
305
|
+
be a non-negative integer parseable by Python `int()`.
|
|
306
|
+
|
|
297
307
|
**`KANON_OUTDATED_FORMAT`** (default: `table`) -- Default output
|
|
298
308
|
format for `kanon outdated`. Currently only `table` is supported.
|
|
299
309
|
Overridden by `--format` CLI flag.
|
|
@@ -570,7 +580,11 @@ number of completion error lines surfaced by `kanon doctor` (subcheck
|
|
|
570
580
|
|
|
571
581
|
kanon performs a best-effort PyPI check for a newer `kanon-cli` release
|
|
572
582
|
and prints an upgrade hint when one is available. The check is cached and
|
|
573
|
-
never blocks a command on failure.
|
|
583
|
+
never blocks a command on failure. When an upgrade is available the banner
|
|
584
|
+
is yellow with the current (installed) version in red and the latest
|
|
585
|
+
version in green. When a check is attempted but the network is unreachable,
|
|
586
|
+
a red `no internet access -- could not check for updates` notice is printed
|
|
587
|
+
to stderr at most once per cache window.
|
|
574
588
|
|
|
575
589
|
**`KANON_SKIP_UPDATE_CHECK`** (default: unset) -- When set to exactly `1`,
|
|
576
590
|
the PyPI update-available check is skipped entirely. The global
|
|
@@ -584,9 +598,9 @@ kanon --no-update-check install .kanon
|
|
|
584
598
|
export KANON_SKIP_UPDATE_CHECK=1
|
|
585
599
|
```
|
|
586
600
|
|
|
587
|
-
**`KANON_UPDATE_CHECK_TTL`** (default: `
|
|
601
|
+
**`KANON_UPDATE_CHECK_TTL`** (default: `10800`) -- Seconds the cached
|
|
588
602
|
"latest version" result is considered fresh before the next check refetches
|
|
589
|
-
it. Must be a positive integer.
|
|
603
|
+
it (default 3 hours). Must be a positive integer.
|
|
590
604
|
|
|
591
605
|
**`KANON_UPDATE_CONNECT_TIMEOUT`** (default: `2`) -- Connect timeout in
|
|
592
606
|
seconds for the PyPI request. Must be a positive integer.
|
|
@@ -600,6 +614,62 @@ integer.
|
|
|
600
614
|
|
|
601
615
|
---
|
|
602
616
|
|
|
617
|
+
### Usage telemetry
|
|
618
|
+
|
|
619
|
+
kanon emits one anonymised-by-design usage event per command to the Caylent
|
|
620
|
+
telemetry collector so the maintainers can understand which commands and
|
|
621
|
+
package sources are used. Telemetry is **on by default**, runs **silently**
|
|
622
|
+
and **non-blocking** in a detached background process, and **never** blocks,
|
|
623
|
+
delays, or fails your command. It serialises only an explicit allowlist of
|
|
624
|
+
kanon-computed fields and never raw argv, credentials, keys, tokens, env-var
|
|
625
|
+
values, or file contents; every URL is credential-stripped before it is sent.
|
|
626
|
+
See [docs/privacy.md](privacy.md) for the exact fields collected, the reason
|
|
627
|
+
for each, and the transit/at-rest encryption.
|
|
628
|
+
|
|
629
|
+
**`KANON_TELEMETRY_DISABLED`** (default: unset) -- The single opt-out. Set to
|
|
630
|
+
a truthy value (`1`, `true`, `yes`, or `on`) to disable telemetry entirely.
|
|
631
|
+
There is no disable flag; this env var is the only off switch.
|
|
632
|
+
|
|
633
|
+
```bash
|
|
634
|
+
# Turn telemetry off for the whole session
|
|
635
|
+
export KANON_TELEMETRY_DISABLED=1
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
**`KANON_TELEMETRY_ENDPOINT`** (default:
|
|
639
|
+
`https://collector.platform.solutions.caylent.com/v1/logs`) -- The collector
|
|
640
|
+
endpoint. Must be an `https://` URL. The global `--telemetry-endpoint <url>`
|
|
641
|
+
flag overrides this for a single invocation.
|
|
642
|
+
|
|
643
|
+
**`KANON_TELEMETRY_DEBUG`** (default: unset) -- When truthy, prints the exact
|
|
644
|
+
JSON that would be sent to stderr (still non-blocking). Equivalent to the
|
|
645
|
+
global `--telemetry-debug` flag. Use it to inspect precisely what an event
|
|
646
|
+
contains.
|
|
647
|
+
|
|
648
|
+
```bash
|
|
649
|
+
# See exactly what an event contains without changing send behaviour
|
|
650
|
+
kanon --telemetry-debug install .kanon
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
**`KANON_TELEMETRY_CONNECT_TIMEOUT`** (default: `2`) /
|
|
654
|
+
**`KANON_TELEMETRY_READ_TIMEOUT`** (default: `3`) -- Connect / read timeouts
|
|
655
|
+
in seconds for the background POST. Must be positive integers.
|
|
656
|
+
|
|
657
|
+
**`KANON_TELEMETRY_MAX_BODY_BYTES`** (default: `4194304`) /
|
|
658
|
+
**`KANON_TELEMETRY_GRAPH_SIZE_CAP`** (default: `3145728`) -- The maximum
|
|
659
|
+
serialised body size and the install-graph size cap. When an install graph
|
|
660
|
+
exceeds the cap it is dropped in favour of the flattened installed-packages
|
|
661
|
+
summary with `install_graph_truncated: true`, so the fact that packages were
|
|
662
|
+
installed is never lost. Must be positive integers.
|
|
663
|
+
|
|
664
|
+
**`KANON_TELEMETRY_GIT_TIMEOUT`** (default: `3`) -- Per-command timeout in
|
|
665
|
+
seconds for the read-only `git` probes used to collect credential-stripped
|
|
666
|
+
repository provenance. Must be a positive integer.
|
|
667
|
+
|
|
668
|
+
**`KANON_TELEMETRY_LOG`** (default: `${KANON_HOME}/cache/telemetry-errors.log`)
|
|
669
|
+
-- Path to the append-only background telemetry error log.
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
603
673
|
### Retry policy
|
|
604
674
|
|
|
605
675
|
kanon retries `git ls-remote` calls on transient errors. Auth-failure
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Privacy & Telemetry
|
|
2
|
+
|
|
3
|
+
kanon emits one usage-telemetry event per command so the maintainers can
|
|
4
|
+
understand which commands are used, which package sources are installed, and
|
|
5
|
+
where failures occur. This page documents exactly what is collected, why, how it
|
|
6
|
+
is protected in transit and at rest, and how to turn it off.
|
|
7
|
+
|
|
8
|
+
## Design principles
|
|
9
|
+
|
|
10
|
+
- **On by default.** Telemetry is enabled out of the box for every user. There
|
|
11
|
+
is no opt-in prompt, no first-run consent gate, and no enable toggle.
|
|
12
|
+
- **Silent and non-blocking.** The event payload is built in the foreground from
|
|
13
|
+
local git and lockfile reads only (no network). The actual HTTPS POST is fired
|
|
14
|
+
in a detached background process, so your command is never blocked, delayed on
|
|
15
|
+
the network, or failed by telemetry. A happy-path command prints nothing about
|
|
16
|
+
telemetry on stdout or stderr.
|
|
17
|
+
- **Never-fail.** Any telemetry error (payload build, serialisation, or network)
|
|
18
|
+
is swallowed for this best-effort feature and, where possible, recorded in a
|
|
19
|
+
background error log (`${KANON_HOME}/cache/telemetry-errors.log`). It never
|
|
20
|
+
surfaces to your command.
|
|
21
|
+
- **Zero secrets by construction.** Only an explicit allowlist of kanon-computed
|
|
22
|
+
fields is serialised. Raw argv is never emitted. SSH/private keys, tokens,
|
|
23
|
+
credentials, key files, `~/.ssh`, environment-variable values, and file
|
|
24
|
+
contents are never read or emitted. Every git/source URL is credential-stripped
|
|
25
|
+
(any `user:pass@` / `token@` userinfo is dropped; host, org, and repo are kept)
|
|
26
|
+
before it is serialised.
|
|
27
|
+
|
|
28
|
+
## What is collected
|
|
29
|
+
|
|
30
|
+
Each event is a single OTLP/HTTP log record whose body is a flat JSON object with
|
|
31
|
+
four top-level keys -- `tool` (always `kanon`), `timestamp`, `event_type`
|
|
32
|
+
(always `cli_command`), and `payload`. The rich fields ride inside `payload`:
|
|
33
|
+
|
|
34
|
+
| Field | Where | Collected? | Why / notes |
|
|
35
|
+
|-------|-------|-----------|-------------|
|
|
36
|
+
| `tool` = `kanon`, `timestamp`, `event_type` = `cli_command` | body | Yes | Routing and partitioning; `tool` is the partition key. |
|
|
37
|
+
| `schema_version`, `run_id` | payload | Yes | Payload schema version and a per-invocation random id (a fresh UUID each run -- never a stable device or user id). |
|
|
38
|
+
| `environment`: `kanon_version`, `python_version`, `os`, `arch`, `install_type`, `is_ci` | payload | Yes | Understand the runtime mix (versions, platform, wheel/editable/source install, CI vs interactive). No hostname, username, or path. |
|
|
39
|
+
| `invocation`: `command`, `subcommand`, boolean flag **names**, allowlisted flag **values** | payload | Yes | Which command/subcommand ran and which boolean flags were set (names only). Only closed-domain values (e.g. `--format text|json`) are recorded. Never raw argv. |
|
|
40
|
+
| `outcome`: `exit_code`, `status`, `error_type`, `duration_ms` | payload | Yes | Success/failure rates and latency. `error_type` is the exception **class name** only -- never a message or traceback. |
|
|
41
|
+
| `git`: `user_email`, `remote_host`, `org`, `repo`, `branch` | payload | Yes | Attribute usage to a team/repo. The remote URL is **credential-stripped**; only host/org/repo are kept. |
|
|
42
|
+
| `install_graph` (on `kanon install`) | payload | Yes | The complete resolved graph: per direct source (`alias`, `name`, `manifest_url`, `ref_spec`, `resolved_ref`, `resolved_sha`, `registered_marketplaces`) plus its transitive `projects[]` (`name`, `url`, `canonical_url`, `resolved_ref`, `resolved_sha`) and the include chain. All URLs credential-stripped. |
|
|
43
|
+
| `installed_packages[]` (on `kanon install`) | payload | Yes | Flattened list of every direct source (`scope: direct`) and every transitive repo package (`scope: transitive`) with `name`, `url`, and `sha` -- easy analytics of what was installed. |
|
|
44
|
+
| Raw argv, non-allowlisted or secret-capable flag values | -- | **Never** | -- |
|
|
45
|
+
| SSH/private keys, tokens, credentials, key files, `~/.ssh`, env-var values | -- | **Never** | Never read or emitted. |
|
|
46
|
+
| Source code, file contents, full local file paths | -- | **Never** | -- |
|
|
47
|
+
| Error messages / stack traces | -- | **Never** | Exception class name only. |
|
|
48
|
+
|
|
49
|
+
The serialised install graph is capped well under the collector's body limit. If
|
|
50
|
+
a graph is very large it is dropped in favour of the flattened
|
|
51
|
+
`installed_packages[]` summary plus `install_graph_truncated: true`, so the fact
|
|
52
|
+
that packages were installed is never lost.
|
|
53
|
+
|
|
54
|
+
## Encryption
|
|
55
|
+
|
|
56
|
+
- **In transit:** the event is POSTed over HTTPS/TLS to the collector. The
|
|
57
|
+
emitter enforces an HTTPS-only guard and refuses any non-`https://` endpoint.
|
|
58
|
+
- **At rest:** the collector stores events in an S3-backed data lake encrypted
|
|
59
|
+
with a customer-managed KMS key (SSE-KMS).
|
|
60
|
+
|
|
61
|
+
## How to turn it off
|
|
62
|
+
|
|
63
|
+
Set the environment variable `KANON_TELEMETRY_DISABLED` to a truthy value
|
|
64
|
+
(`1`, `true`, `yes`, or `on`). This is the **only** opt-out -- there is no
|
|
65
|
+
`--no-telemetry` flag.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Disable telemetry for the whole session
|
|
69
|
+
export KANON_TELEMETRY_DISABLED=1
|
|
70
|
+
|
|
71
|
+
# Or for a single command
|
|
72
|
+
KANON_TELEMETRY_DISABLED=1 kanon install .kanon
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Inspecting exactly what is sent
|
|
76
|
+
|
|
77
|
+
Use the `--telemetry-debug` global flag (or `KANON_TELEMETRY_DEBUG=1`) to print
|
|
78
|
+
the exact JSON that would be sent to stderr. This does not change the
|
|
79
|
+
non-blocking send behaviour; it only surfaces the payload so you can audit it.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
kanon --telemetry-debug install .kanon
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Related configuration
|
|
86
|
+
|
|
87
|
+
See [docs/configuration.md](configuration.md#usage-telemetry) for the full list
|
|
88
|
+
of telemetry environment variables (endpoint override, timeouts, size caps, and
|
|
89
|
+
the error-log path) and [docs/cli-reference.md](cli-reference.md#global-flags)
|
|
90
|
+
for the global flags.
|