apm-cli 0.23.0__tar.gz → 0.23.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {apm_cli-0.23.0/src/apm_cli.egg-info → apm_cli-0.23.1}/PKG-INFO +1 -1
- {apm_cli-0.23.0 → apm_cli-0.23.1}/pyproject.toml +1 -1
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/install.py +19 -18
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/package_resolution.py +81 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/lockfile.py +21 -7
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/template.py +22 -10
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/content_hash.py +55 -2
- {apm_cli-0.23.0 → apm_cli-0.23.1/src/apm_cli.egg-info}/PKG-INFO +1 -1
- {apm_cli-0.23.0 → apm_cli-0.23.1}/AUTHORS +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/LICENSE +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/NOTICE +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/README.md +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/setup.cfg +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/antigravity.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/base.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/claude.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/codex.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/copilot.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/cursor.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/gemini.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/hermes.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/intellij.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/kiro.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/opencode.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/vscode.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/client/windsurf.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/package_manager/base.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/bootstrap_mirror.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/bundle/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/bundle/local_bundle.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/bundle/lockfile_enrichment.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/bundle/packer.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/bundle/plugin_exporter.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/bundle/unpacker.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/cache/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/cache/git_cache.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/cache/http_cache.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/cache/integrity.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/cache/locking.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/cache/paths.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/cache/url_normalize.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/cli.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/_apm_yml_writer.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/_helpers.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/approve.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/audit.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/cache.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/compile/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/compile/cli.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/compile/watcher.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/config.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/deps/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/deps/_utils.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/deps/cli.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/deps/why.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/doctor.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/experimental.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/find.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/init.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/lifecycle.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/list_cmd.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/lock.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/audit.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/check.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/doctor.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/init.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/migrate.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/outdated.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/plugin/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/plugin/add.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/plugin/remove.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/marketplace/validate.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/mcp.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/outdated.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/pack.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/plugin/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/plugin/init.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/policy.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/prune.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/publish.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/run.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/runtime.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/self_update.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/targets.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/uninstall/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/uninstall/cli.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/uninstall/engine.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/update.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/commands/view.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/agents_compiler.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/build_id.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/claude_formatter.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/constants.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/constitution.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/constitution_block.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/context_optimizer.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/distributed_compiler.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/gemini_formatter.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/injector.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/link_resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/managed_section.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/output_writer.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/template_builder.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/compilation/user_root_context.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/config.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/constants.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/apm_yml.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/auth.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/azure_cli.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/build_orchestrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/command_logger.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/conflict_detector.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/docker_args.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/errors.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/experimental.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/install_audit.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/lifecycle_scripts.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/null_logger.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/operations.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/plugin_manifest.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/safe_installer.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/scope.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/script_executors.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/script_runner.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/script_trust.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/target_detection.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/core/token_manager.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/_shared.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/aggregator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/apm_resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/artifactory_entry.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/bare_cache.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/clone_engine.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/dependency_graph.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/download_strategies.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/git_auth_env.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/git_file_transport.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/git_reference_resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/git_remote_ops.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/git_semver_resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/github_downloader.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/github_downloader_validation.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/host_backends.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/installed_package.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/lockfile.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/outdated_row.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/package_validator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/path_anchoring.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/plugin_parser.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/registry/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/registry/auth.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/registry/client.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/registry/config_loader.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/registry/extractor.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/registry/feature_gate.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/registry/outdated.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/registry/resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/registry/semver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/registry_proxy.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/revision_pins.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/shared_clone_cache.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/tiered_ref_resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/transport_selection.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/verifier.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/deps/why_walker.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/drift.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/export/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/export/authoring.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/export/declared_license.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/export/formats.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/export/purl.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/export/sbom.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/export/spdx.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/export/spdx_data.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/factory.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/artifactory_resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/cache_pin.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/context.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/deployed_paths.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/drift.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/errors.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/exec_gate.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/gitlab_resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/heals/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/heals/base.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/helpers/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/helpers/security_scan.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/insecure_policy.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/integrity.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/local_bundle_handler.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/lsp/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/lsp/integration.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/manifest_reconcile.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/mcp/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/mcp/args.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/mcp/command.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/mcp/conflicts.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/mcp/entry.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/mcp/registry.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/mcp/warnings.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/mcp/writer.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/package_selection.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/_redownload.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/_skip_logic.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/audit.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/cleanup.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/download.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/finalize.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/heal.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/integrate.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/local_content.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/policy_gate.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/policy_target_check.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/post_deps_local.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/resolve.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/phases/targets.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/pipeline.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/plan.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/presentation/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/presentation/dry_run.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/registry_wiring.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/request.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/root_redirect.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/service.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/services.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/skill_path_migration.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/sources.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/summary.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/target_filter.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/install/validation.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/_shared.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/agent_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/base_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/canvas_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/cleanup.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/command_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/copilot_app_db.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/copilot_app_project.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/copilot_app_workflow_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/copilot_app_ws.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/coverage.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/dispatch.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/hook_file_routing.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/hook_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/instruction_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/kiro_hook_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/lsp_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/mcp_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/mcp_integrator_install.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/prompt_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/skill_integrator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/skill_transformer.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/targets.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/integration/utils.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/_git_utils.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/_io.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/_shared.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/audit.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/auth_helpers.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/builder.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/client.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/diagnostics.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/drift_check.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/errors.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/git_stderr.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/init_template.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/migration.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/models.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/output_mappers.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/output_profiles.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/ref_resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/registry.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/semver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/shadow_detector.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/tag_pattern.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/validator.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/version_check.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/version_pins.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/version_resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/yml_editor.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/marketplace/yml_schema.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/apm_package.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/dependency/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/dependency/identity.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/dependency/lsp.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/dependency/mcp.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/dependency/reference.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/dependency/subsets.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/dependency/types.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/format_detection.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/plugin.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/results.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/models/validation.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/output/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/output/formatters.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/output/models.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/output/script_formatters.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/_constraint_pinning.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/_help_text.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/_shared.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/ci_checks.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/discovery.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/inheritance.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/install_preflight.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/matcher.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/models.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/outcome_routing.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/parser.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/policy_checks.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/project_config.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/policy/schema.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/primitives/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/primitives/discovery.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/primitives/models.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/primitives/parser.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/registry/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/registry/client.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/registry/integration.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/registry/operations.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/runtime/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/runtime/base.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/runtime/codex_runtime.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/runtime/copilot_runtime.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/runtime/factory.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/runtime/llm_runtime.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/runtime/manager.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/runtime/utils.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/audit_report.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/content_scanner.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/executables.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/external/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/external/base.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/external/gate.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/external/generic_sarif.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/external/options.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/external/registry.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/external/runner.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/external/sarif_ingest.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/external/skillspector.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/file_scanner.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/security/gate.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/update_policy.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/archive.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/atomic_io.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/console.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/diagnostics.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/exclude.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/file_ops.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/git_env.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/git_sparse.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/github_host.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/guards.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/helpers.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/install_tui.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/normalization.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/path_security.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/paths.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/patterns.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/perf_stats.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/reflink.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/short_sha.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/subprocess_env.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/version_checker.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/utils/yaml_io.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/version.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/workflow/__init__.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/workflow/discovery.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/workflow/parser.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli/workflow/runner.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli.egg-info/SOURCES.txt +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli.egg-info/dependency_links.txt +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli.egg-info/entry_points.txt +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli.egg-info/requires.txt +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/src/apm_cli.egg-info/top_level.txt +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_apm_package_models.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_apm_resolver.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_codex_docker_args_fix.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_codex_empty_string_and_defaults.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_collision_integration.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_console.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_distributed_compilation.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_empty_string_and_defaults.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_enhanced_discovery.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_github_downloader.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_github_downloader_token_precedence.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_gitlab_git_transport.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_lockfile.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_runnable_prompts.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_runtime_manager_token_precedence.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_token_manager.py +0 -0
- {apm_cli-0.23.0 → apm_cli-0.23.1}/tests/test_virtual_package_multi_install.py +0 -0
|
@@ -47,8 +47,9 @@ from apm_cli.install.mcp.entry import _build_mcp_entry # noqa: F401
|
|
|
47
47
|
from apm_cli.install.mcp.writer import _add_mcp_to_apm_yml # noqa: F401
|
|
48
48
|
from apm_cli.install.package_resolution import (
|
|
49
49
|
GIT_PARENT_USER_SCOPE_ERROR,
|
|
50
|
+
apply_cli_skill_pin,
|
|
51
|
+
cli_skill_subset,
|
|
50
52
|
dependency_reference_to_yaml_entry,
|
|
51
|
-
normalize_and_merge_skill_subset,
|
|
52
53
|
persist_dependency_list_if_changed,
|
|
53
54
|
resolve_parsed_dependency_reference,
|
|
54
55
|
update_existing_dependency_entry_if_needed,
|
|
@@ -329,6 +330,7 @@ def _resolve_package_references(
|
|
|
329
330
|
scope=None,
|
|
330
331
|
allow_insecure=False,
|
|
331
332
|
skill_subset=None,
|
|
333
|
+
skill_subset_from_cli=False,
|
|
332
334
|
default_registry=None,
|
|
333
335
|
):
|
|
334
336
|
"""Validate, canonicalize, and resolve package references.
|
|
@@ -453,16 +455,15 @@ def _resolve_package_references(
|
|
|
453
455
|
)
|
|
454
456
|
canonical = dep_ref.to_canonical()
|
|
455
457
|
identity = dep_ref.get_identity()
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
)
|
|
458
|
+
apply_cli_skill_pin(
|
|
459
|
+
dep_ref,
|
|
460
|
+
skill_subset,
|
|
461
|
+
skill_subset_from_cli,
|
|
462
|
+
current_deps,
|
|
463
|
+
_apm_yml_entries,
|
|
464
|
+
dependency_reference_cls=DependencyReference,
|
|
465
|
+
logger=logger,
|
|
466
|
+
)
|
|
466
467
|
if marketplace_dep_ref is not None or direct_virtual_resolved:
|
|
467
468
|
_apm_yml_entries[canonical] = dependency_reference_to_yaml_entry(dep_ref)
|
|
468
469
|
except ValueError as e:
|
|
@@ -633,6 +634,7 @@ def _validate_and_add_packages_to_apm_yml(
|
|
|
633
634
|
scope=None,
|
|
634
635
|
allow_insecure=False,
|
|
635
636
|
skill_subset=None,
|
|
637
|
+
skill_subset_from_cli=False,
|
|
636
638
|
):
|
|
637
639
|
"""Validate packages exist and can be accessed, then add to apm.yml dependencies section.
|
|
638
640
|
|
|
@@ -701,6 +703,7 @@ def _validate_and_add_packages_to_apm_yml(
|
|
|
701
703
|
scope=scope,
|
|
702
704
|
allow_insecure=allow_insecure,
|
|
703
705
|
skill_subset=skill_subset,
|
|
706
|
+
skill_subset_from_cli=skill_subset_from_cli,
|
|
704
707
|
default_registry=_default_registry_for_cli,
|
|
705
708
|
)
|
|
706
709
|
|
|
@@ -1048,7 +1051,7 @@ def _handle_mcp_install(
|
|
|
1048
1051
|
"skill_names",
|
|
1049
1052
|
multiple=True,
|
|
1050
1053
|
metavar="NAME",
|
|
1051
|
-
help="Install only named skill(s) from a SKILL_BUNDLE. Repeatable. Persisted in apm.yml and apm.lock so bare 'apm install' is deterministic. Use --skill '*' to reset to all skills.",
|
|
1054
|
+
help="Install only named skill(s) from a SKILL_BUNDLE. Repeatable. Persisted in apm.yml and apm.lock so bare 'apm install' is deterministic. Additive across installs: a later --skill X adds X to the existing pin (union) rather than replacing it. Use --skill '*' (quote the asterisk in your shell) to reset to all skills; to drop a single skill, edit the skills: list in apm.yml then re-run apm install.",
|
|
1052
1055
|
)
|
|
1053
1056
|
@click.option(
|
|
1054
1057
|
"--no-policy",
|
|
@@ -1384,12 +1387,9 @@ def install( # noqa: PLR0913
|
|
|
1384
1387
|
)
|
|
1385
1388
|
|
|
1386
1389
|
# Normalize --skill: '*' means all (same as absent). Reject with --mcp.
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
raise click.UsageError("--skill cannot be combined with --mcp.")
|
|
1391
|
-
if not any(s == "*" for s in skill_names):
|
|
1392
|
-
_skill_subset = builtins.tuple(skill_names)
|
|
1390
|
+
if skill_names and mcp_name is not None:
|
|
1391
|
+
raise click.UsageError("--skill cannot be combined with --mcp.")
|
|
1392
|
+
_skill_subset = cli_skill_subset(skill_names)
|
|
1393
1393
|
|
|
1394
1394
|
if mcp_name is not None:
|
|
1395
1395
|
_handle_mcp_install(
|
|
@@ -1517,6 +1517,7 @@ def install( # noqa: PLR0913
|
|
|
1517
1517
|
scope=scope,
|
|
1518
1518
|
allow_insecure=allow_insecure,
|
|
1519
1519
|
skill_subset=_skill_subset,
|
|
1520
|
+
skill_subset_from_cli=bool(skill_names),
|
|
1520
1521
|
)
|
|
1521
1522
|
# Short-circuit: all packages failed validation -- nothing to install
|
|
1522
1523
|
if outcome.all_failed:
|
|
@@ -180,6 +180,87 @@ def normalize_and_merge_skill_subset(
|
|
|
180
180
|
return sorted(seen)
|
|
181
181
|
|
|
182
182
|
|
|
183
|
+
def effective_deploy_skill_subset(
|
|
184
|
+
*,
|
|
185
|
+
skill_subset_from_cli: bool,
|
|
186
|
+
cli_subset: builtins.tuple[str, ...] | builtins.list[str] | None,
|
|
187
|
+
persisted_subset: builtins.tuple[str, ...] | builtins.list[str] | None,
|
|
188
|
+
) -> builtins.tuple[str, ...] | None:
|
|
189
|
+
"""Resolve the skill subset to *deploy* for a SKILL_BUNDLE.
|
|
190
|
+
|
|
191
|
+
``--skill`` is additive (issue #1786): a targeted ``--skill B`` install must
|
|
192
|
+
land on top of skills already pinned for the bundle instead of erasing them.
|
|
193
|
+
The deployment therefore uses the union of the persisted manifest subset and
|
|
194
|
+
the current CLI ``--skill`` values -- not the raw CLI subset alone.
|
|
195
|
+
|
|
196
|
+
``--skill '*'`` (signalled by ``skill_subset_from_cli`` True with an empty
|
|
197
|
+
``cli_subset``) resets the bundle to its full set, so this returns ``None``
|
|
198
|
+
meaning "deploy all skills".
|
|
199
|
+
|
|
200
|
+
Returns a sorted, deduplicated tuple, or ``None`` for "deploy all".
|
|
201
|
+
"""
|
|
202
|
+
if skill_subset_from_cli and not cli_subset:
|
|
203
|
+
return None # --skill '*' -> full bundle
|
|
204
|
+
merged: builtins.set[str] = builtins.set()
|
|
205
|
+
if persisted_subset:
|
|
206
|
+
merged.update(persisted_subset)
|
|
207
|
+
if cli_subset:
|
|
208
|
+
merged.update(cli_subset)
|
|
209
|
+
return builtins.tuple(sorted(merged)) or None
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def cli_skill_subset(
|
|
213
|
+
skill_names: builtins.tuple[str, ...],
|
|
214
|
+
) -> builtins.tuple[str, ...] | None:
|
|
215
|
+
"""Resolve raw CLI ``--skill`` names to a subset, or None for absent / ``'*'``.
|
|
216
|
+
|
|
217
|
+
``--skill '*'`` means "all skills" (same as absent); the resolver still
|
|
218
|
+
learns the flag was present via a separate CLI-origin flag, so this
|
|
219
|
+
collapses both the absent and ``'*'`` cases to None.
|
|
220
|
+
"""
|
|
221
|
+
if skill_names and not any(s == "*" for s in skill_names):
|
|
222
|
+
return builtins.tuple(skill_names)
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def apply_cli_skill_pin(
|
|
227
|
+
dep_ref: Any,
|
|
228
|
+
cli_subset: builtins.tuple[str, ...] | None,
|
|
229
|
+
skill_subset_from_cli: bool,
|
|
230
|
+
current_deps: builtins.list,
|
|
231
|
+
apm_yml_entries: dict,
|
|
232
|
+
*,
|
|
233
|
+
dependency_reference_cls: Any,
|
|
234
|
+
logger: Any | None = None,
|
|
235
|
+
) -> None:
|
|
236
|
+
"""Attach, merge, or reset a CLI ``--skill`` pin on ``dep_ref`` in place.
|
|
237
|
+
|
|
238
|
+
With an explicit ``cli_subset``, merge it additively with any persisted
|
|
239
|
+
``skills:`` so repeated ``--skill`` invocations union rather than replace
|
|
240
|
+
(issue #1771). With ``--skill '*'`` (``skill_subset_from_cli`` True and an
|
|
241
|
+
empty ``cli_subset``), reset the pin back to the full bundle and record the
|
|
242
|
+
refreshed plain-string ``apm.yml`` entry under the reference's canonical key
|
|
243
|
+
so manifest and on-disk state agree on the whole bundle (issue #1786 reset).
|
|
244
|
+
"""
|
|
245
|
+
identity = dep_ref.get_identity()
|
|
246
|
+
if cli_subset:
|
|
247
|
+
dep_ref.skill_subset = normalize_and_merge_skill_subset(
|
|
248
|
+
cli_subset,
|
|
249
|
+
current_deps,
|
|
250
|
+
identity,
|
|
251
|
+
dependency_reference_cls=dependency_reference_cls,
|
|
252
|
+
)
|
|
253
|
+
return
|
|
254
|
+
if skill_subset_from_cli:
|
|
255
|
+
dep_ref.skill_subset = None
|
|
256
|
+
apm_yml_entries[dep_ref.to_canonical()] = dep_ref.to_apm_yml_entry()
|
|
257
|
+
if logger:
|
|
258
|
+
logger.verbose_detail(
|
|
259
|
+
f" [i] {identity}: skill pin reset to full bundle "
|
|
260
|
+
"(--skill '*'); a later bare 'apm install' deploys all skills"
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
|
|
183
264
|
def manifest_has_different_entry_for_identity(
|
|
184
265
|
current_deps: builtins.list,
|
|
185
266
|
identity: str,
|
|
@@ -19,6 +19,7 @@ import copy
|
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
from typing import TYPE_CHECKING
|
|
21
21
|
|
|
22
|
+
from apm_cli.install.package_resolution import effective_deploy_skill_subset
|
|
22
23
|
from apm_cli.utils.content_hash import compute_file_hash
|
|
23
24
|
|
|
24
25
|
if TYPE_CHECKING:
|
|
@@ -228,18 +229,31 @@ class LockfileBuilder:
|
|
|
228
229
|
lockfile.dependencies[dep_key].exec_status = status
|
|
229
230
|
|
|
230
231
|
def _attach_skill_subset_override(self, lockfile: LockFile) -> None:
|
|
231
|
-
"""
|
|
232
|
+
"""Union the CLI ``--skill`` values into lockfile skill_bundle entries.
|
|
232
233
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
234
|
+
``--skill`` is additive (issue #1786): a targeted ``apm install bundle
|
|
235
|
+
--skill foo`` must record the UNION of the previously pinned skills and
|
|
236
|
+
``foo`` -- not replace the persisted subset with the raw CLI value. The
|
|
237
|
+
per-entry manifest subset already flows into ``locked_dep.skill_subset``;
|
|
238
|
+
here we fold in the current CLI values so the lockfile matches what was
|
|
239
|
+
deployed.
|
|
240
|
+
|
|
241
|
+
``--skill '*'`` (empty ``ctx.skill_subset``) is a no-op here -- the
|
|
242
|
+
manifest reset already flowed the full-bundle (empty) subset through.
|
|
236
243
|
"""
|
|
237
244
|
if not self.ctx.skill_subset:
|
|
238
|
-
return #
|
|
239
|
-
effective = sorted(set(self.ctx.skill_subset))
|
|
245
|
+
return # bare install or --skill '*'; manifest value already flows through
|
|
240
246
|
for dep_key, locked_dep in lockfile.dependencies.items(): # noqa: B007
|
|
241
247
|
if locked_dep.package_type == "skill_bundle":
|
|
242
|
-
|
|
248
|
+
merged = effective_deploy_skill_subset(
|
|
249
|
+
skill_subset_from_cli=self.ctx.skill_subset_from_cli,
|
|
250
|
+
cli_subset=self.ctx.skill_subset,
|
|
251
|
+
persisted_subset=locked_dep.skill_subset,
|
|
252
|
+
)
|
|
253
|
+
# merged is never None here: the guard above returns for
|
|
254
|
+
# --skill '*' (empty ctx.skill_subset), so a real named
|
|
255
|
+
# subset always survives the union.
|
|
256
|
+
locked_dep.skill_subset = list(merged) if merged else []
|
|
243
257
|
|
|
244
258
|
def _attach_content_hashes(self, lockfile: LockFile) -> None:
|
|
245
259
|
for dep_key, locked_dep in lockfile.dependencies.items():
|
|
@@ -14,6 +14,7 @@ This is the Template Method companion to the Strategy pattern in
|
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
16
|
from apm_cli.install.helpers.security_scan import _pre_deploy_security_scan
|
|
17
|
+
from apm_cli.install.package_resolution import effective_deploy_skill_subset
|
|
17
18
|
from apm_cli.install.services import IntegratorBundle, integrate_package_primitives
|
|
18
19
|
from apm_cli.install.sources import DependencySource, Materialization
|
|
19
20
|
|
|
@@ -128,6 +129,26 @@ def _integrate_materialization(
|
|
|
128
129
|
ctx.package_deployed_files[dep_key] = []
|
|
129
130
|
return deltas
|
|
130
131
|
|
|
132
|
+
# Per-package effective subset: ``--skill`` is additive (issue
|
|
133
|
+
# #1786), so deploy the UNION of the persisted apm.yml ``skills:``
|
|
134
|
+
# and the current CLI ``--skill`` values -- a targeted ``--skill``
|
|
135
|
+
# install lands on top of previously pinned skills instead of
|
|
136
|
+
# erasing them. ``--skill '*'`` resets to the full bundle (None).
|
|
137
|
+
effective_skill_subset = effective_deploy_skill_subset(
|
|
138
|
+
skill_subset_from_cli=ctx.skill_subset_from_cli,
|
|
139
|
+
cli_subset=ctx.skill_subset,
|
|
140
|
+
persisted_subset=dep_ref.skill_subset,
|
|
141
|
+
)
|
|
142
|
+
# When the additive union deploys more skills than the user named on
|
|
143
|
+
# this invocation, name the retained pins so the deployed set is not
|
|
144
|
+
# a silent surprise (verbose only -- the count already renders).
|
|
145
|
+
if logger and ctx.skill_subset and effective_skill_subset:
|
|
146
|
+
retained = sorted(set(effective_skill_subset) - set(ctx.skill_subset))
|
|
147
|
+
if retained:
|
|
148
|
+
logger.verbose_detail(
|
|
149
|
+
f" [i] {dep_key}: retaining previously pinned "
|
|
150
|
+
f"skill(s): {', '.join(retained)}"
|
|
151
|
+
)
|
|
131
152
|
int_result = integrate_package_primitives(
|
|
132
153
|
m.package_info,
|
|
133
154
|
ctx.project_root,
|
|
@@ -147,16 +168,7 @@ def _integrate_materialization(
|
|
|
147
168
|
package_name=dep_key,
|
|
148
169
|
logger=logger,
|
|
149
170
|
scope=ctx.scope,
|
|
150
|
-
|
|
151
|
-
# apm.yml skills:. When CLI is absent (bare reinstall), fall back
|
|
152
|
-
# to the dep_ref's persisted skill_subset.
|
|
153
|
-
# When CLI explicitly provided (even --skill '*'), use ctx value
|
|
154
|
-
# (which is None for '*' = install all).
|
|
155
|
-
skill_subset=(
|
|
156
|
-
ctx.skill_subset
|
|
157
|
-
if ctx.skill_subset_from_cli
|
|
158
|
-
else (tuple(dep_ref.skill_subset) if dep_ref.skill_subset else None)
|
|
159
|
-
),
|
|
171
|
+
skill_subset=effective_skill_subset,
|
|
160
172
|
dep_target_subset=dep_ref.target_subset,
|
|
161
173
|
ctx=ctx,
|
|
162
174
|
allow_executables=_effective_allow(ctx),
|
|
@@ -4,6 +4,7 @@ import hashlib
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
6
|
from apm_cli.install.cache_pin import MARKER_FILENAME as _APM_PIN_MARKER
|
|
7
|
+
from apm_cli.utils.atomic_io import normalize_crlf_to_lf
|
|
7
8
|
|
|
8
9
|
# Directories excluded from hashing (not relevant to package content)
|
|
9
10
|
_EXCLUDED_DIRS = {".git", "__pycache__"}
|
|
@@ -28,6 +29,14 @@ def compute_package_hash(package_path: Path) -> str:
|
|
|
28
29
|
making it independent of filesystem ordering and metadata (timestamps,
|
|
29
30
|
permissions).
|
|
30
31
|
|
|
32
|
+
Note: this whole-tree hash intentionally hashes raw file bytes, unlike
|
|
33
|
+
the per-file :func:`compute_file_hash` which normalizes CRLF->LF for
|
|
34
|
+
text (apm#1952). The package tree is hashed at the git-checkout
|
|
35
|
+
boundary where content is already platform-canonical, and the path is
|
|
36
|
+
bound into the digest, so cross-platform line-ending identity is
|
|
37
|
+
unnecessary here. Do not unify the two without re-checking that
|
|
38
|
+
invariant.
|
|
39
|
+
|
|
31
40
|
Args:
|
|
32
41
|
package_path: Root directory of the installed package.
|
|
33
42
|
|
|
@@ -70,14 +79,58 @@ def compute_package_hash(package_path: Path) -> str:
|
|
|
70
79
|
return f"sha256:{hasher.hexdigest()}"
|
|
71
80
|
|
|
72
81
|
|
|
82
|
+
def _canonical_hash_bytes(raw: bytes) -> bytes:
|
|
83
|
+
"""Return the canonical byte image used for per-file content hashing.
|
|
84
|
+
|
|
85
|
+
Text content (UTF-8-decodable and free of NUL bytes) is line-ending
|
|
86
|
+
normalized CRLF -> LF, with bare CR preserved, so the deployed-file
|
|
87
|
+
hash is platform-invariant (apm#1952): a file that git materializes
|
|
88
|
+
as ``\\r\\n`` on Windows and ``\\n`` on POSIX hashes identically.
|
|
89
|
+
Detection is content-based (not suffix-based) so integrator renames
|
|
90
|
+
such as ``.md`` -> ``.mdc`` are still normalized.
|
|
91
|
+
|
|
92
|
+
Binary content -- anything that is not valid UTF-8, or that contains
|
|
93
|
+
a NUL byte (e.g. UTF-16, images) -- is hashed raw; normalizing it
|
|
94
|
+
would be meaningless and could corrupt the integrity witness.
|
|
95
|
+
|
|
96
|
+
Preserving bare CR (only ``\\r\\n`` collapses to ``\\n``) keeps the
|
|
97
|
+
carriage-return smuggling vector hash-visible: solely the benign
|
|
98
|
+
line-terminator difference is made invisible, never a lone ``\\r``
|
|
99
|
+
that a terminal or parser could interpret as an overwrite. On line
|
|
100
|
+
endings this aligns with the drift-replay normalizer
|
|
101
|
+
(:func:`apm_cli.utils.normalization._normalize_line_endings`), so the
|
|
102
|
+
``content-integrity`` audit and the drift-replay audit no longer
|
|
103
|
+
disagree about whether a CRLF/LF difference is a content change.
|
|
104
|
+
(Drift-replay additionally strips BOM and build-id markers; this
|
|
105
|
+
per-file integrity hash deliberately does not -- those remain
|
|
106
|
+
hash-visible here.)
|
|
107
|
+
"""
|
|
108
|
+
if b"\x00" in raw:
|
|
109
|
+
return raw
|
|
110
|
+
try:
|
|
111
|
+
text = raw.decode("utf-8")
|
|
112
|
+
except UnicodeDecodeError:
|
|
113
|
+
return raw
|
|
114
|
+
return normalize_crlf_to_lf(text).encode("utf-8")
|
|
115
|
+
|
|
116
|
+
|
|
73
117
|
def compute_file_hash(file_path: Path) -> str:
|
|
74
|
-
"""Compute SHA-256 of a single file's
|
|
118
|
+
"""Compute SHA-256 of a single file's content (line-ending-normalized).
|
|
75
119
|
|
|
76
120
|
Used for per-deployed-file provenance checks before APM deletes a
|
|
77
121
|
file recorded in ``deployed_files``. The path itself is not mixed
|
|
78
122
|
in (unlike :func:`compute_package_hash`) because deployed files may
|
|
79
123
|
be renamed by integrators (e.g. ``.md`` -> ``.mdc`` for Cursor).
|
|
80
124
|
|
|
125
|
+
UTF-8 text content is hashed over its CRLF -> LF normalized form
|
|
126
|
+
(bare CR preserved) so the hash is identical on every platform,
|
|
127
|
+
regardless of whether git ``core.autocrlf`` materialized the file
|
|
128
|
+
with ``\\n`` or ``\\r\\n`` (apm#1952). This makes the record side
|
|
129
|
+
(``apm install``) and the verify side (``apm audit``) symmetric by
|
|
130
|
+
construction across operating systems. Binary content (non-UTF-8 or
|
|
131
|
+
containing a NUL byte) is hashed raw. See :func:`_canonical_hash_bytes`
|
|
132
|
+
for the security rationale.
|
|
133
|
+
|
|
81
134
|
Args:
|
|
82
135
|
file_path: File to hash.
|
|
83
136
|
|
|
@@ -89,7 +142,7 @@ def compute_file_hash(file_path: Path) -> str:
|
|
|
89
142
|
if not file_path.is_file() or file_path.is_symlink():
|
|
90
143
|
return _EMPTY_HASH
|
|
91
144
|
hasher = hashlib.sha256()
|
|
92
|
-
hasher.update(file_path.read_bytes())
|
|
145
|
+
hasher.update(_canonical_hash_bytes(file_path.read_bytes()))
|
|
93
146
|
return f"sha256:{hasher.hexdigest()}"
|
|
94
147
|
|
|
95
148
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|