apm-cli 0.29.1__tar.gz → 0.30.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.
- {apm_cli-0.29.1/src/apm_cli.egg-info → apm_cli-0.30.0}/PKG-INFO +19 -7
- {apm_cli-0.29.1 → apm_cli-0.30.0}/README.md +18 -6
- {apm_cli-0.29.1 → apm_cli-0.30.0}/pyproject.toml +2 -1
- apm_cli-0.30.0/src/apm_cli/cache/cleanup.py +51 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/cache/git_cache.py +51 -27
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/cache/http_cache.py +12 -7
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/cache.py +41 -26
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/config.py +22 -3
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/prune.py +13 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/self_update.py +18 -4
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/uninstall/cli.py +53 -19
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/uninstall/engine.py +87 -74
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/context_optimizer.py +3 -5
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/github_rate_limit.py +15 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/discovery.py +1 -3
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/policy_checks.py +28 -6
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/project_config.py +12 -4
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/version_checker.py +131 -18
- {apm_cli-0.29.1 → apm_cli-0.30.0/src/apm_cli.egg-info}/PKG-INFO +19 -7
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli.egg-info/SOURCES.txt +1 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/AUTHORS +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/LICENSE +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/NOTICE +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/setup.cfg +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/antigravity.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/base.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/claude.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/codex.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/copilot.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/cursor.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/gemini.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/hermes.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/intellij.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/kiro.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/opencode.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/vscode.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/client/windsurf.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/package_manager/base.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/agent_plugins/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/agent_plugins/assets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/agent_plugins/constants.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/agent_plugins/errors.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/agent_plugins/io.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/agent_plugins/ir.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/agent_plugins/loader.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/agent_plugins/projection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/agent_plugins/validation.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bootstrap_mirror.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/agent_plugin_exporter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/attest.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/claude_plugin_exporter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/export_common.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/formats.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/local_bundle.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/lockfile_enrichment.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/packer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/plugin_exporter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/plugin_layout.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/reproducible_archive.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/bundle/unpacker.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/cache/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/cache/integrity.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/cache/locking.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/cache/paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/cache/url_normalize.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/cli.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/_apm_yml_writer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/_helpers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/approve.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/audit.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/compile/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/compile/cli.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/compile/watcher.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/deps/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/deps/_utils.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/deps/cli.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/deps/why.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/doctor.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/experimental.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/find.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/init.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/install.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/lifecycle.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/list_cmd.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/lock.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/audit.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/check.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/doctor.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/init.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/migrate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/outdated.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/plugin/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/plugin/add.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/plugin/remove.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/marketplace/validate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/mcp.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/outdated.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/pack.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/plugin/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/plugin/init.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/policy.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/publish.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/run.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/runtime.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/targets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/uninstall/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/uninstall/lockfile_state.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/update.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/commands/view.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/agents_compiler.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/build_id.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/claude_formatter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/constants.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/constitution.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/constitution_block.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/distributed_compiler.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/footer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/gemini_formatter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/injector.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/inventory.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/link_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/managed_section.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/output_writer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/root_context_protection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/template_builder.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/compilation/user_root_context.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/config.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/constants.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/copilot_plugins/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/copilot_plugins/capability.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/copilot_plugins/catalog.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/copilot_plugins/constants.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/copilot_plugins/registrar.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/copilot_plugins/settings.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/_child_tls/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/_child_tls/_apm_tls.pth +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/_child_tls/_apm_tls_bootstrap.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/apm_yml.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/auth.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/azure_cli.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/build_orchestrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/command_logger.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/conflict_detector.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/deployment_ledger.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/deployment_state.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/docker_args.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/errors.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/experimental.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/host_providers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/install_audit.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/lifecycle_scripts.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/null_logger.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/operations.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/output_mode.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/plugin_manifest.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/project_name.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/safe_installer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/scope.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/script_executors.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/script_runner.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/script_trust.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/target_catalog.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/target_detection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/tls_trust.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/core/token_manager.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/_shared.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/aggregator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/apm_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/artifactory_entry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/bare_cache.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/clone_engine.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/dependency_graph.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/download_strategies.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/git_auth_env.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/git_file_transport.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/git_reference_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/git_remote_ops.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/git_semver_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/github_downloader.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/github_downloader_validation.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/host_backends.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/installed_package.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/lockfile.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/outdated_ref_cache.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/outdated_row.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/package_validator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/path_anchoring.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/plugin_parser.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/reachability.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/registry/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/registry/auth.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/registry/client.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/registry/config_loader.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/registry/extractor.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/registry/feature_gate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/registry/outdated.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/registry/resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/registry/semver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/registry_proxy.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/revision_pins.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/shared_clone_cache.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/tiered_ref_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/transport_selection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/verifier.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/deps/why_walker.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/drift.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/export/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/export/authoring.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/export/declared_license.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/export/formats.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/export/purl.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/export/sbom.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/export/spdx.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/export/spdx_data.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/factory.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/hook_contract.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/argv.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/artifactory_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/audit_replay.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/audit_target_roots.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/cache_pin.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/context.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/deployable_source_plan.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/deployed_paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/drift.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/drift_render.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/dry_run_plan.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/errors.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/exec_gate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/finalization.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/gitlab_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/heals/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/heals/base.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/helpers/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/helpers/no_work.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/helpers/ref_reuse.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/helpers/ref_seed.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/helpers/security_scan.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/insecure_policy.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/integrity.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/legacy_plugin_compat.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/local_bundle_handler.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/local_bundle_paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/locking.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/lsp/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/lsp/integration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/manifest_helpers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/manifest_reconcile.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/mcp/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/mcp/args.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/mcp/command.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/mcp/conflicts.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/mcp/entry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/mcp/integration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/mcp/ownership.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/mcp/registry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/mcp/warnings.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/mcp/writer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/native_plugin_admission.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/outcome.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/package_resolution.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/package_selection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/_redownload.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/_skip_logic.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/audit.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/cleanup.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/copilot_plugins.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/download.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/finalize.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/heal.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/integrate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/local_content.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/lockfile.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/policy_gate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/policy_target_check.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/post_deps_local.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/resolve.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/phases/targets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/pipeline.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/plan.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/presentation/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/presentation/dry_run.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/primitive_classification.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/registry_wiring.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/request.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/resolution_staging.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/root_redirect.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/service.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/service_integration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/services.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/skill_path_migration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/source_helpers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/sources.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/summary.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/target_filter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/target_hints.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/target_warnings.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/template.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/transaction.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/install/validation.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/_hook_dropped_targets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/_shared.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/agent_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/base_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/canvas_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/cleanup.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/command_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/copilot_app_db.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/copilot_app_project.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/copilot_app_workflow_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/copilot_app_ws.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/coverage.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/dispatch.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/hook_bundle.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/hook_command_paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/hook_command_warnings.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/hook_file_routing.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/hook_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/hook_ir.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/hook_native_formats.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/hook_ownership.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/hook_reintegration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/hook_source_selection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/instruction_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/kiro_hook_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/lsp_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/mcp_config_view.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/mcp_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/mcp_integrator_install.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/prompt_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/skill_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/skill_package_routing.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/skill_support.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/skill_transformer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/targets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/integration/utils.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/_git_utils.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/_io.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/_shared.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/audit.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/auth_helpers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/builder.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/client.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/diagnostics.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/drift_check.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/errors.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/git_stderr.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/init_template.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/migration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/models.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/output_mappers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/output_profiles.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/ref_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/registry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/semver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/shadow_detector.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/source_identity.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/tag_pattern.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/validator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/version_check.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/version_pins.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/version_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/yml_editor.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/marketplace/yml_schema.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/apm_package.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/host_virtual.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/identity.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/lsp.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/materialization.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/mcp.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/object_fields.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/provider_coordinates.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/reference.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/registry_entry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/selection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/subsets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/dependency/types.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/format_detection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/manifest_contract.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/plugin.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/results.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/models/validation.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/output/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/output/formatters.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/output/models.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/output/script_formatters.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/_constraint_pinning.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/_gitlab.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/_help_text.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/_shared.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/ci_checks.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/inheritance.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/install_preflight.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/matcher.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/models.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/outcome_routing.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/parser.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/policy/schema.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/primitives/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/primitives/discovery.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/primitives/models.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/primitives/parser.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/registry/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/registry/client.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/registry/integration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/registry/operations.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/runtime/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/runtime/base.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/runtime/codex_runtime.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/runtime/copilot_runtime.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/runtime/factory.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/runtime/llm_runtime.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/runtime/manager.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/runtime/registry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/runtime/utils.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/audit_report.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/content_scanner.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/executables.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/external/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/external/base.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/external/gate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/external/generic_sarif.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/external/options.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/external/registry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/external/runner.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/external/sarif_ingest.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/external/skillspector.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/file_scanner.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/security/gate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/update_policy.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/archive.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/atomic_io.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/console.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/content_hash.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/diagnostics.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/exclude.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/file_ops.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/git_env.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/git_sparse.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/github_host.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/guards.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/helpers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/install_tui.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/net.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/normalization.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/path_security.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/patterns.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/perf_stats.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/reflink.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/short_sha.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/staging_guard.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/subprocess_env.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/utils/yaml_io.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/version.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/workflow/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/workflow/discovery.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/workflow/parser.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli/workflow/runner.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli.egg-info/dependency_links.txt +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli.egg-info/entry_points.txt +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli.egg-info/requires.txt +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/src/apm_cli.egg-info/top_level.txt +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_apm_package_models.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_apm_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_codex_docker_args_fix.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_codex_empty_string_and_defaults.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_collision_integration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_console.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_distributed_compilation.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_empty_string_and_defaults.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_enhanced_discovery.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_github_downloader.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_github_downloader_token_precedence.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_gitlab_git_transport.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_lockfile.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_runnable_prompts.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_runtime_manager_token_precedence.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_token_manager.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.30.0}/tests/test_virtual_package_multi_install.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apm-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.30.0
|
|
4
4
|
Summary: MCP configuration tool
|
|
5
5
|
Author-email: Daniel Meppiel <user@example.com>
|
|
6
6
|
License: MIT License
|
|
@@ -170,7 +170,16 @@ apm-policy.yml governs what gets installed; your agent harness governs what runs
|
|
|
170
170
|
|
|
171
171
|
## Get Started
|
|
172
172
|
|
|
173
|
-
####
|
|
173
|
+
#### macOS with Homebrew
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
brew install apm
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
No custom tap is required. Homebrew manages installation and updates:
|
|
180
|
+
use `brew upgrade apm`, not `apm self-update`.
|
|
181
|
+
|
|
182
|
+
#### Linux / macOS without Homebrew
|
|
174
183
|
|
|
175
184
|
```bash
|
|
176
185
|
curl -sSL https://aka.ms/apm-unix | sh
|
|
@@ -182,17 +191,17 @@ curl -sSL https://aka.ms/apm-unix | sh
|
|
|
182
191
|
irm https://aka.ms/apm-windows | iex
|
|
183
192
|
```
|
|
184
193
|
|
|
185
|
-
Native release binaries are published for macOS, Linux, and Windows x86_64.
|
|
194
|
+
Native release binaries are published for macOS, Linux, and Windows x86_64.
|
|
195
|
+
For standalone installations, `apm self-update` reuses the matching platform installer.
|
|
196
|
+
You do not need Homebrew to use APM.
|
|
186
197
|
|
|
187
198
|
<details>
|
|
188
|
-
<summary>Other install methods</summary>
|
|
199
|
+
<summary>Other install methods: pip and Scoop</summary>
|
|
189
200
|
|
|
190
201
|
#### Linux / macOS
|
|
191
202
|
|
|
192
203
|
```bash
|
|
193
|
-
#
|
|
194
|
-
brew install microsoft/apm/apm
|
|
195
|
-
# pip
|
|
204
|
+
# pip (Python 3.10+)
|
|
196
205
|
pip install apm-cli
|
|
197
206
|
```
|
|
198
207
|
|
|
@@ -208,6 +217,9 @@ pip install apm-cli
|
|
|
208
217
|
|
|
209
218
|
</details>
|
|
210
219
|
|
|
220
|
+
Already using the Microsoft Homebrew tap? See the
|
|
221
|
+
[migration guide](https://microsoft.github.io/apm/getting-started/installation/#migrate-from-the-microsoft-tap).
|
|
222
|
+
|
|
211
223
|
Then start adding packages:
|
|
212
224
|
|
|
213
225
|
```bash
|
|
@@ -98,7 +98,16 @@ apm-policy.yml governs what gets installed; your agent harness governs what runs
|
|
|
98
98
|
|
|
99
99
|
## Get Started
|
|
100
100
|
|
|
101
|
-
####
|
|
101
|
+
#### macOS with Homebrew
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
brew install apm
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
No custom tap is required. Homebrew manages installation and updates:
|
|
108
|
+
use `brew upgrade apm`, not `apm self-update`.
|
|
109
|
+
|
|
110
|
+
#### Linux / macOS without Homebrew
|
|
102
111
|
|
|
103
112
|
```bash
|
|
104
113
|
curl -sSL https://aka.ms/apm-unix | sh
|
|
@@ -110,17 +119,17 @@ curl -sSL https://aka.ms/apm-unix | sh
|
|
|
110
119
|
irm https://aka.ms/apm-windows | iex
|
|
111
120
|
```
|
|
112
121
|
|
|
113
|
-
Native release binaries are published for macOS, Linux, and Windows x86_64.
|
|
122
|
+
Native release binaries are published for macOS, Linux, and Windows x86_64.
|
|
123
|
+
For standalone installations, `apm self-update` reuses the matching platform installer.
|
|
124
|
+
You do not need Homebrew to use APM.
|
|
114
125
|
|
|
115
126
|
<details>
|
|
116
|
-
<summary>Other install methods</summary>
|
|
127
|
+
<summary>Other install methods: pip and Scoop</summary>
|
|
117
128
|
|
|
118
129
|
#### Linux / macOS
|
|
119
130
|
|
|
120
131
|
```bash
|
|
121
|
-
#
|
|
122
|
-
brew install microsoft/apm/apm
|
|
123
|
-
# pip
|
|
132
|
+
# pip (Python 3.10+)
|
|
124
133
|
pip install apm-cli
|
|
125
134
|
```
|
|
126
135
|
|
|
@@ -136,6 +145,9 @@ pip install apm-cli
|
|
|
136
145
|
|
|
137
146
|
</details>
|
|
138
147
|
|
|
148
|
+
Already using the Microsoft Homebrew tap? See the
|
|
149
|
+
[migration guide](https://microsoft.github.io/apm/getting-started/installation/#migrate-from-the-microsoft-tap).
|
|
150
|
+
|
|
139
151
|
Then start adding packages:
|
|
140
152
|
|
|
141
153
|
```bash
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "apm-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.30.0"
|
|
8
8
|
description = "MCP configuration tool"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -219,4 +219,5 @@ markers = [
|
|
|
219
219
|
"req: binds a test to one or more OpenAPM req-XXX ids (spec-conformance suite)",
|
|
220
220
|
"lifecycle_smoke: promoted to the required PR-time Lifecycle Smoke (Linux) job -- see ci.yml's lifecycle-smoke job and docs/src/content/docs/contributing/integration-testing.md",
|
|
221
221
|
"lifecycle_merge_group: unique lifecycle contracts retained in the full merge-group integration suite",
|
|
222
|
+
"xdist_group(name): assigns HOME-mutating tests to one pytest-xdist loadgroup for process-level serialization",
|
|
222
223
|
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Verified, best-effort removal outcomes for explicit cache cleaning."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from collections.abc import Iterable
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from ..utils import file_ops
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def clean_cache_buckets(buckets: Iterable[Path]) -> list[str]:
|
|
13
|
+
"""Remove bucket children without following links; return all failure details.
|
|
14
|
+
|
|
15
|
+
Successful removals are not rolled back. The residual check is essential:
|
|
16
|
+
the read-only recovery callback in robust_rmtree can swallow OS errors.
|
|
17
|
+
"""
|
|
18
|
+
failures: list[str] = []
|
|
19
|
+
for bucket in buckets:
|
|
20
|
+
try:
|
|
21
|
+
if bucket.is_symlink():
|
|
22
|
+
failures.append(f"{bucket}: refusing to traverse a symlinked cache bucket")
|
|
23
|
+
continue
|
|
24
|
+
with os.scandir(bucket) as entries:
|
|
25
|
+
for entry in entries:
|
|
26
|
+
path = Path(entry.path)
|
|
27
|
+
try:
|
|
28
|
+
if entry.is_dir(follow_symlinks=False):
|
|
29
|
+
file_ops.robust_rmtree(path)
|
|
30
|
+
else:
|
|
31
|
+
path.unlink()
|
|
32
|
+
except FileNotFoundError:
|
|
33
|
+
pass
|
|
34
|
+
except OSError as exc:
|
|
35
|
+
failures.append(f"{path}: {exc}")
|
|
36
|
+
continue
|
|
37
|
+
try:
|
|
38
|
+
# lstat distinguishes a removed entry from an unreadable
|
|
39
|
+
# one and also detects dangling symlinks.
|
|
40
|
+
path.lstat()
|
|
41
|
+
except FileNotFoundError:
|
|
42
|
+
continue
|
|
43
|
+
except OSError as exc:
|
|
44
|
+
failures.append(f"{path}: {exc}")
|
|
45
|
+
else:
|
|
46
|
+
failures.append(f"{path}: entry remains after deletion")
|
|
47
|
+
except FileNotFoundError:
|
|
48
|
+
continue
|
|
49
|
+
except OSError as exc:
|
|
50
|
+
failures.append(f"{bucket}: {exc}")
|
|
51
|
+
return failures
|
|
@@ -16,6 +16,7 @@ Resolution flow:
|
|
|
16
16
|
On every cache HIT:
|
|
17
17
|
- Run integrity check (verify HEAD == expected SHA)
|
|
18
18
|
- Mismatch -> evict shard, fall through to fresh fetch, log warning
|
|
19
|
+
- Refresh the SHA directory's access timestamp after successful validation
|
|
19
20
|
|
|
20
21
|
Concurrency:
|
|
21
22
|
- Per-shard file locks (via filelock) for atomic operations
|
|
@@ -24,7 +25,6 @@ Concurrency:
|
|
|
24
25
|
|
|
25
26
|
from __future__ import annotations
|
|
26
27
|
|
|
27
|
-
import contextlib
|
|
28
28
|
import hashlib
|
|
29
29
|
import json
|
|
30
30
|
import logging
|
|
@@ -50,6 +50,15 @@ _FALLBACK_REFSPECS = (
|
|
|
50
50
|
)
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
class CachePruneError(OSError):
|
|
54
|
+
"""Incomplete prune with completed-removal count and per-entry failures."""
|
|
55
|
+
|
|
56
|
+
def __init__(self, pruned: int, failures: list[tuple[Path, OSError]]) -> None:
|
|
57
|
+
self.pruned = pruned
|
|
58
|
+
self.failures = tuple(failures)
|
|
59
|
+
super().__init__(f"Pruned {pruned} SHA group(s); {len(failures)} failed.")
|
|
60
|
+
|
|
61
|
+
|
|
53
62
|
def _safe_git_args() -> list[str]:
|
|
54
63
|
"""Return hardening ``-c`` args prepended to every git subprocess.
|
|
55
64
|
|
|
@@ -195,11 +204,8 @@ class GitCache:
|
|
|
195
204
|
if verify_checkout_sha(checkout_dir, sha):
|
|
196
205
|
_log.debug("Cache HIT: %s @ %s [%s]", _sanitize_url(url), sha[:12], variant)
|
|
197
206
|
with shard_lock(checkout_dir):
|
|
198
|
-
return self.
|
|
199
|
-
url,
|
|
200
|
-
checkout_dir,
|
|
201
|
-
sparse_paths,
|
|
202
|
-
env=env,
|
|
207
|
+
return self._record_checkout_access(
|
|
208
|
+
self._finalize_sparse_checkout(url, checkout_dir, sparse_paths, env=env)
|
|
203
209
|
)
|
|
204
210
|
else:
|
|
205
211
|
# Integrity failure -- evict
|
|
@@ -226,6 +232,21 @@ class GitCache:
|
|
|
226
232
|
promisor_url=url if use_partial else None,
|
|
227
233
|
)
|
|
228
234
|
|
|
235
|
+
def _record_checkout_access(self, checkout_dir: Path) -> Path:
|
|
236
|
+
"""Record successful reuse of a finalized checkout under its shard lock."""
|
|
237
|
+
# Pruning ages the shared SHA root, not individual checkout variants.
|
|
238
|
+
try:
|
|
239
|
+
os.utime(checkout_dir.parent, None)
|
|
240
|
+
except PermissionError as exc:
|
|
241
|
+
_log.warning(
|
|
242
|
+
"[!] Cannot update Git cache recency for %s: %s. "
|
|
243
|
+
"Continuing with validated checkout; cache prune may evict it. "
|
|
244
|
+
"Check cache permissions or set APM_CACHE_DIR to a writable directory.",
|
|
245
|
+
checkout_dir.parent,
|
|
246
|
+
exc,
|
|
247
|
+
)
|
|
248
|
+
return checkout_dir
|
|
249
|
+
|
|
229
250
|
def _finalize_sparse_checkout(
|
|
230
251
|
self,
|
|
231
252
|
url: str,
|
|
@@ -600,11 +621,8 @@ class GitCache:
|
|
|
600
621
|
sha[:12],
|
|
601
622
|
variant,
|
|
602
623
|
)
|
|
603
|
-
return self.
|
|
604
|
-
url,
|
|
605
|
-
final_dir,
|
|
606
|
-
sparse_paths,
|
|
607
|
-
env=env,
|
|
624
|
+
return self._record_checkout_access(
|
|
625
|
+
self._finalize_sparse_checkout(url, final_dir, sparse_paths, env=env)
|
|
608
626
|
)
|
|
609
627
|
|
|
610
628
|
staged = stage_path(final_dir)
|
|
@@ -873,33 +891,37 @@ class GitCache:
|
|
|
873
891
|
"total_size_bytes": total_size,
|
|
874
892
|
}
|
|
875
893
|
|
|
876
|
-
def clean_all(self) ->
|
|
877
|
-
"""Remove
|
|
878
|
-
from
|
|
894
|
+
def clean_all(self) -> list[str]:
|
|
895
|
+
"""Remove db and checkouts, returning details of every incomplete removal."""
|
|
896
|
+
from .cleanup import clean_cache_buckets
|
|
879
897
|
|
|
880
|
-
|
|
881
|
-
if bucket.is_dir():
|
|
882
|
-
for entry in os.scandir(str(bucket)):
|
|
883
|
-
if entry.is_dir(follow_symlinks=False):
|
|
884
|
-
robust_rmtree(Path(entry.path), ignore_errors=True)
|
|
885
|
-
elif entry.is_file(follow_symlinks=False):
|
|
886
|
-
with contextlib.suppress(OSError):
|
|
887
|
-
os.unlink(entry.path)
|
|
898
|
+
return clean_cache_buckets((self._db_root, self._checkouts_root))
|
|
888
899
|
|
|
889
900
|
def prune(self, *, max_age_days: int = 30) -> int:
|
|
890
901
|
"""Remove checkout entries older than *max_age_days*.
|
|
891
902
|
|
|
892
|
-
Uses mtime of the
|
|
903
|
+
Uses mtime of the shared SHA directory as the access indicator.
|
|
904
|
+
Successfully reusing any checkout variant refreshes that timestamp.
|
|
893
905
|
|
|
894
906
|
Returns:
|
|
895
|
-
Number of
|
|
907
|
+
Number of SHA groups successfully removed.
|
|
908
|
+
|
|
909
|
+
Raises:
|
|
910
|
+
ValueError: If max_age_days is negative.
|
|
911
|
+
CachePruneError: Some entries could not be inspected or removed.
|
|
912
|
+
Other stale entries are still attempted. Completed removals
|
|
913
|
+
and partially deleted entries are not rolled back.
|
|
896
914
|
"""
|
|
897
915
|
import time
|
|
898
916
|
|
|
899
917
|
from ..utils.file_ops import robust_rmtree
|
|
900
918
|
|
|
919
|
+
if max_age_days < 0:
|
|
920
|
+
raise ValueError("max_age_days must be nonnegative; use 0 or a positive number of days")
|
|
921
|
+
|
|
901
922
|
cutoff = time.time() - (max_age_days * 86400)
|
|
902
923
|
pruned = 0
|
|
924
|
+
failures: list[tuple[Path, OSError]] = []
|
|
903
925
|
|
|
904
926
|
if not self._checkouts_root.is_dir():
|
|
905
927
|
return 0
|
|
@@ -913,11 +935,13 @@ class GitCache:
|
|
|
913
935
|
try:
|
|
914
936
|
stat = sha_entry.stat(follow_symlinks=False)
|
|
915
937
|
if stat.st_mtime < cutoff:
|
|
916
|
-
robust_rmtree(Path(sha_entry.path)
|
|
938
|
+
robust_rmtree(Path(sha_entry.path))
|
|
917
939
|
pruned += 1
|
|
918
|
-
except OSError:
|
|
919
|
-
|
|
940
|
+
except OSError as exc:
|
|
941
|
+
failures.append((Path(sha_entry.path), exc))
|
|
920
942
|
|
|
943
|
+
if failures:
|
|
944
|
+
raise CachePruneError(pruned, failures)
|
|
921
945
|
return pruned
|
|
922
946
|
|
|
923
947
|
|
|
@@ -121,6 +121,13 @@ class HttpCache:
|
|
|
121
121
|
robust_rmtree(entry_path, ignore_errors=True)
|
|
122
122
|
return None
|
|
123
123
|
|
|
124
|
+
# Recency is independent of TTL. A concurrent eviction or read-only
|
|
125
|
+
# cache must not discard the response we have already verified.
|
|
126
|
+
try:
|
|
127
|
+
os.utime(str(entry_path), None)
|
|
128
|
+
except OSError as exc:
|
|
129
|
+
_log.debug("Failed to update HTTP cache recency for %s: %s", url, exc)
|
|
130
|
+
|
|
124
131
|
return CacheEntry(
|
|
125
132
|
body=body,
|
|
126
133
|
etag=meta.get("etag"),
|
|
@@ -270,14 +277,12 @@ class HttpCache:
|
|
|
270
277
|
except (json.JSONDecodeError, OSError) as exc:
|
|
271
278
|
_log.debug("Failed to refresh HTTP cache entry for %s: %s", url, exc)
|
|
272
279
|
|
|
273
|
-
def clean_all(self) ->
|
|
274
|
-
"""Remove
|
|
275
|
-
from
|
|
280
|
+
def clean_all(self) -> list[str]:
|
|
281
|
+
"""Remove HTTP entries, returning details of every incomplete removal."""
|
|
282
|
+
from .cleanup import clean_cache_buckets
|
|
276
283
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if entry.is_dir(follow_symlinks=False):
|
|
280
|
-
robust_rmtree(Path(entry.path), ignore_errors=True)
|
|
284
|
+
self._tracked_size = None
|
|
285
|
+
return clean_cache_buckets((self._cache_dir,))
|
|
281
286
|
|
|
282
287
|
def get_stats(self) -> dict[str, int]:
|
|
283
288
|
"""Return cache statistics.
|
|
@@ -60,43 +60,51 @@ def info() -> None:
|
|
|
60
60
|
def clean(force: bool, yes: bool) -> None:
|
|
61
61
|
"""Remove all cache content (git repos, checkouts, HTTP responses)."""
|
|
62
62
|
from ..cache.paths import get_cache_root
|
|
63
|
-
from ..
|
|
63
|
+
from ..core.command_logger import CommandLogger
|
|
64
64
|
|
|
65
|
+
logger = CommandLogger("cache clean")
|
|
65
66
|
try:
|
|
66
67
|
root = get_cache_root()
|
|
67
68
|
except (ValueError, OSError) as exc:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
_rich_error(f"Cannot resolve cache root: {exc}", symbol="error")
|
|
69
|
+
logger.error(f"Cannot resolve cache root: {exc}")
|
|
71
70
|
raise SystemExit(1) from exc
|
|
72
71
|
|
|
73
72
|
if not force and not yes:
|
|
74
73
|
confirmed = click.confirm(f"Remove all cache content in {root}?", default=False)
|
|
75
74
|
if not confirmed:
|
|
76
|
-
|
|
75
|
+
logger.progress("Aborted.")
|
|
77
76
|
return
|
|
78
77
|
|
|
79
|
-
|
|
78
|
+
logger.start("Cleaning cache...", symbol="gear")
|
|
80
79
|
|
|
81
80
|
from ..cache.git_cache import GitCache
|
|
82
81
|
from ..cache.http_cache import HttpCache
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
83
|
+
failures: list[str] = []
|
|
84
|
+
for cache_type in (GitCache, HttpCache):
|
|
85
|
+
try:
|
|
86
|
+
failures.extend(cache_type(root).clean_all())
|
|
87
|
+
except OSError as exc:
|
|
88
|
+
failures.append(f"{cache_type.__name__}: {exc}")
|
|
89
|
+
if failures:
|
|
90
|
+
logger.error("Cache cleanup incomplete; some cached content could not be removed.")
|
|
91
|
+
for failure in failures:
|
|
92
|
+
logger.error(failure)
|
|
93
|
+
logger.error(
|
|
94
|
+
"Close processes using the cache, check permissions, then retry apm cache clean."
|
|
95
|
+
)
|
|
96
|
+
raise SystemExit(1)
|
|
97
|
+
|
|
98
|
+
logger.success("Cache cleaned.", symbol="check")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@cache.command(help="Remove Git checkout SHA groups older than N days")
|
|
94
102
|
@click.option(
|
|
95
103
|
"--days",
|
|
96
|
-
type=
|
|
104
|
+
type=click.IntRange(min=0),
|
|
97
105
|
default=30,
|
|
98
106
|
show_default=True,
|
|
99
|
-
help="Remove
|
|
107
|
+
help="Remove SHA groups not accessed within this many days",
|
|
100
108
|
)
|
|
101
109
|
def prune(days: int) -> None:
|
|
102
110
|
"""Remove stale cache entries based on last access time.
|
|
@@ -105,24 +113,31 @@ def prune(days: int) -> None:
|
|
|
105
113
|
referenced by project lockfiles are NOT exempt -- freshness is
|
|
106
114
|
determined solely by filesystem timestamps.
|
|
107
115
|
"""
|
|
108
|
-
from ..cache.git_cache import GitCache
|
|
116
|
+
from ..cache.git_cache import CachePruneError, GitCache
|
|
109
117
|
from ..cache.paths import get_cache_root
|
|
110
|
-
from ..
|
|
118
|
+
from ..core.command_logger import CommandLogger
|
|
119
|
+
|
|
120
|
+
logger = CommandLogger("cache prune")
|
|
111
121
|
|
|
112
122
|
try:
|
|
113
123
|
root = get_cache_root()
|
|
114
124
|
except (ValueError, OSError) as exc:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
_rich_error(f"Cannot resolve cache root: {exc}", symbol="error")
|
|
125
|
+
logger.error(f"Cannot resolve cache root: {exc}")
|
|
118
126
|
raise SystemExit(1) from exc
|
|
119
127
|
|
|
120
|
-
|
|
128
|
+
logger.start(f"Pruning SHA groups older than {days} days...", symbol="gear")
|
|
121
129
|
|
|
122
130
|
git_cache = GitCache(root)
|
|
123
|
-
|
|
131
|
+
try:
|
|
132
|
+
pruned = git_cache.prune(max_age_days=days)
|
|
133
|
+
except CachePruneError as exc:
|
|
134
|
+
logger.error(str(exc))
|
|
135
|
+
for path, error in exc.failures:
|
|
136
|
+
logger.error(f"Could not prune {path}: {error}")
|
|
137
|
+
logger.error("Check permissions or close programs using the cache, then retry.")
|
|
138
|
+
raise SystemExit(1) from exc
|
|
124
139
|
|
|
125
|
-
|
|
140
|
+
logger.success(f"Pruned {pruned} SHA group(s).", symbol="check")
|
|
126
141
|
|
|
127
142
|
|
|
128
143
|
def _format_size(size_bytes: int) -> str:
|
|
@@ -12,6 +12,7 @@ from ..constants import APM_YML_FILENAME
|
|
|
12
12
|
from ..core.command_logger import CommandLogger
|
|
13
13
|
from ..install.locking import serialized_lifecycle
|
|
14
14
|
from ..version import get_version
|
|
15
|
+
from . import self_update as self_update_command
|
|
15
16
|
from ._helpers import HIGHLIGHT, RESET, _get_console, _load_apm_config
|
|
16
17
|
|
|
17
18
|
# Restore builtin since a subcommand is named ``set``
|
|
@@ -473,7 +474,13 @@ def set(key, value): # noqa: F811
|
|
|
473
474
|
|
|
474
475
|
try:
|
|
475
476
|
install_dir = set_self_update_install_dir(value)
|
|
476
|
-
|
|
477
|
+
if self_update_command._is_windows_platform():
|
|
478
|
+
logger.success(f"Self-update install directory saved: {install_dir}")
|
|
479
|
+
else:
|
|
480
|
+
logger.success(
|
|
481
|
+
f"Self-update launcher directory preference saved: {install_dir} "
|
|
482
|
+
"(must match the existing Unix installation)"
|
|
483
|
+
)
|
|
477
484
|
except ValueError as exc:
|
|
478
485
|
logger.error(str(exc))
|
|
479
486
|
sys.exit(1)
|
|
@@ -636,7 +643,13 @@ def get(key):
|
|
|
636
643
|
|
|
637
644
|
value = get_self_update_install_dir()
|
|
638
645
|
if value is None:
|
|
639
|
-
|
|
646
|
+
if self_update_command._is_windows_platform():
|
|
647
|
+
click.echo("self-update.install-dir: Not set (using installer default)")
|
|
648
|
+
else:
|
|
649
|
+
click.echo(
|
|
650
|
+
"self-update.install-dir: Not set "
|
|
651
|
+
"(preserving the detected Unix installation)"
|
|
652
|
+
)
|
|
640
653
|
else:
|
|
641
654
|
click.echo(f"self-update.install-dir: {value}")
|
|
642
655
|
return
|
|
@@ -766,7 +779,13 @@ def unset(key):
|
|
|
766
779
|
from ..config import unset_self_update_install_dir
|
|
767
780
|
|
|
768
781
|
unset_self_update_install_dir()
|
|
769
|
-
|
|
782
|
+
if self_update_command._is_windows_platform():
|
|
783
|
+
logger.success("Self-update install directory removed (will use installer default)")
|
|
784
|
+
else:
|
|
785
|
+
logger.success(
|
|
786
|
+
"Self-update launcher directory preference removed "
|
|
787
|
+
"(will preserve the detected Unix installation)"
|
|
788
|
+
)
|
|
770
789
|
return
|
|
771
790
|
|
|
772
791
|
if key == "mcp-registry-url":
|
|
@@ -241,6 +241,7 @@ def prune(ctx, dry_run):
|
|
|
241
241
|
return
|
|
242
242
|
|
|
243
243
|
removed_count = 0
|
|
244
|
+
failed_count = 0
|
|
244
245
|
removed_packages: list[str] = []
|
|
245
246
|
pruned_keys = list(missing_orphaned_keys)
|
|
246
247
|
pruned_key_set = set(pruned_keys)
|
|
@@ -263,6 +264,7 @@ def prune(ctx, dry_run):
|
|
|
263
264
|
pruned_key_set.add(dep_key)
|
|
264
265
|
deleted_pkg_paths.append(pkg_path)
|
|
265
266
|
except Exception as e:
|
|
267
|
+
failed_count += 1
|
|
266
268
|
logger.error(f"Failed to remove {org_repo_name}: {e}")
|
|
267
269
|
|
|
268
270
|
BaseIntegrator.cleanup_empty_parents(deleted_pkg_paths, stop_at=apm_modules_dir)
|
|
@@ -397,6 +399,17 @@ def prune(ctx, dry_run):
|
|
|
397
399
|
"stale -- run 'apm install' to rebuild hook configuration."
|
|
398
400
|
)
|
|
399
401
|
|
|
402
|
+
if failed_count:
|
|
403
|
+
logger.error(
|
|
404
|
+
f"Prune incomplete: removed {removed_count} orphaned package(s); "
|
|
405
|
+
f"failed to remove {failed_count} package(s)."
|
|
406
|
+
)
|
|
407
|
+
logger.error_detail(
|
|
408
|
+
"Filesystem cleanup may be partial. Resolve the removal errors, "
|
|
409
|
+
"then rerun 'apm prune'."
|
|
410
|
+
)
|
|
411
|
+
sys.exit(1)
|
|
412
|
+
|
|
400
413
|
if removed_count > 0:
|
|
401
414
|
message = f"Pruned {removed_count} orphaned package(s)"
|
|
402
415
|
if owner_violations:
|
|
@@ -170,7 +170,9 @@ def get_latest_version_for_self_update(channel: str) -> str | None:
|
|
|
170
170
|
"""Return the latest version for a supported self-update channel."""
|
|
171
171
|
from ..utils.version_checker import get_latest_version_from_github
|
|
172
172
|
|
|
173
|
-
return get_latest_version_from_github(
|
|
173
|
+
return get_latest_version_from_github(
|
|
174
|
+
include_prerelease=(channel == "prerelease"), raise_errors=True
|
|
175
|
+
)
|
|
174
176
|
|
|
175
177
|
|
|
176
178
|
def _build_self_update_installer_env(
|
|
@@ -194,6 +196,11 @@ def _build_self_update_installer_env(
|
|
|
194
196
|
if _ENV_SELF_UPDATE_CHANNEL not in env:
|
|
195
197
|
env[_ENV_SELF_UPDATE_CHANNEL] = channel
|
|
196
198
|
env[_ENV_VERSION] = release.tag
|
|
199
|
+
if not _is_windows_platform():
|
|
200
|
+
# Pass identity, not a second destination policy: install.sh owns routing.
|
|
201
|
+
env["APM_SELF_UPDATE_SOURCE"] = os.path.abspath(
|
|
202
|
+
sys.executable if getattr(sys, "frozen", False) else sys.argv[0]
|
|
203
|
+
)
|
|
197
204
|
return env
|
|
198
205
|
|
|
199
206
|
|
|
@@ -266,7 +273,13 @@ def self_update(check: bool) -> None:
|
|
|
266
273
|
sys.exit(1)
|
|
267
274
|
|
|
268
275
|
# Check for latest version
|
|
269
|
-
|
|
276
|
+
from ..utils.version_checker import ReleaseMetadataError
|
|
277
|
+
|
|
278
|
+
try:
|
|
279
|
+
latest_version = get_latest_version_for_self_update(_channel)
|
|
280
|
+
except ReleaseMetadataError as exc:
|
|
281
|
+
logger.error(str(exc))
|
|
282
|
+
sys.exit(1)
|
|
270
283
|
|
|
271
284
|
if not latest_version:
|
|
272
285
|
if _pinned:
|
|
@@ -352,7 +365,7 @@ def self_update(check: bool) -> None:
|
|
|
352
365
|
|
|
353
366
|
# Note: We don't capture output so the installer can prompt when needed.
|
|
354
367
|
# Sanitise the environment so the installer (and the system binaries
|
|
355
|
-
# it spawns -- curl
|
|
368
|
+
# it spawns -- curl and tar) do not inherit the PyInstaller
|
|
356
369
|
# bootloader's LD_LIBRARY_PATH / DYLD_* overrides, which would
|
|
357
370
|
# otherwise redirect system linkers at this binary's bundled
|
|
358
371
|
# _internal directory. See issue #894.
|
|
@@ -373,7 +386,8 @@ def self_update(check: bool) -> None:
|
|
|
373
386
|
logger.success(
|
|
374
387
|
f"Successfully updated to version {release.version}!",
|
|
375
388
|
)
|
|
376
|
-
|
|
389
|
+
if _is_windows_platform():
|
|
390
|
+
logger.progress("Please restart your terminal or run 'apm --version' to verify")
|
|
377
391
|
else:
|
|
378
392
|
logger.error("Installation failed - see output above for details")
|
|
379
393
|
sys.exit(1)
|