apm-cli 0.29.1__tar.gz → 0.31.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.31.0}/PKG-INFO +26 -9
- {apm_cli-0.29.1 → apm_cli-0.31.0}/README.md +25 -8
- {apm_cli-0.29.1 → apm_cli-0.31.0}/pyproject.toml +2 -1
- apm_cli-0.31.0/src/apm_cli/adopt/__init__.py +1 -0
- apm_cli-0.31.0/src/apm_cli/adopt/discovery.py +248 -0
- apm_cli-0.31.0/src/apm_cli/adopt/manifest_edit.py +76 -0
- apm_cli-0.31.0/src/apm_cli/adopt/materialize.py +32 -0
- apm_cli-0.31.0/src/apm_cli/adopt/render.py +35 -0
- apm_cli-0.31.0/src/apm_cli/adopt/safety.py +51 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/agent_plugins/projection.py +5 -1
- apm_cli-0.31.0/src/apm_cli/cache/cleanup.py +51 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/cache/git_cache.py +140 -32
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/cache/http_cache.py +12 -7
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/cli.py +8 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/cache.py +41 -26
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/config.py +22 -3
- apm_cli-0.31.0/src/apm_cli/commands/discover.py +94 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/init.py +39 -3
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/outdated.py +34 -12
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/prune.py +13 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/self_update.py +18 -4
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/uninstall/cli.py +53 -19
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/uninstall/engine.py +90 -75
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/context_optimizer.py +3 -5
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/auth.py +3 -2
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/output_mode.py +1 -1
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/apm_resolver.py +1 -1
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/clone_engine.py +11 -33
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/download_strategies.py +184 -72
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/git_reference_resolver.py +2 -5
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/github_rate_limit.py +15 -0
- apm_cli-0.31.0/src/apm_cli/deps/outdated_row.py +25 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/registry/outdated.py +21 -18
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/registry/resolver.py +19 -9
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/transport_selection.py +61 -10
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/deployed_paths.py +4 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/outcome.py +16 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/template.py +84 -12
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/validation.py +2 -4
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/cleanup.py +5 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/skill_integrator.py +32 -31
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/identity.py +101 -10
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/reference.py +13 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/validation.py +33 -11
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/discovery.py +1 -3
- apm_cli-0.31.0/src/apm_cli/policy/matcher.py +213 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/policy_checks.py +65 -18
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/project_config.py +12 -4
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/gate.py +21 -4
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/diagnostics.py +33 -2
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/file_ops.py +4 -4
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/git_env.py +14 -9
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/version_checker.py +131 -18
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/yaml_io.py +6 -1
- {apm_cli-0.29.1 → apm_cli-0.31.0/src/apm_cli.egg-info}/PKG-INFO +26 -9
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli.egg-info/SOURCES.txt +8 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_github_downloader.py +3 -2
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_gitlab_git_transport.py +7 -3
- apm_cli-0.29.1/src/apm_cli/deps/outdated_row.py +0 -17
- apm_cli-0.29.1/src/apm_cli/policy/matcher.py +0 -96
- {apm_cli-0.29.1 → apm_cli-0.31.0}/AUTHORS +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/LICENSE +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/NOTICE +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/setup.cfg +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/antigravity.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/base.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/claude.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/codex.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/copilot.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/cursor.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/gemini.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/hermes.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/intellij.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/kiro.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/opencode.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/vscode.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/client/windsurf.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/package_manager/base.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/agent_plugins/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/agent_plugins/assets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/agent_plugins/constants.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/agent_plugins/errors.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/agent_plugins/io.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/agent_plugins/ir.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/agent_plugins/loader.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/agent_plugins/validation.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bootstrap_mirror.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/agent_plugin_exporter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/attest.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/claude_plugin_exporter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/export_common.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/formats.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/local_bundle.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/lockfile_enrichment.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/packer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/plugin_exporter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/plugin_layout.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/reproducible_archive.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/bundle/unpacker.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/cache/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/cache/integrity.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/cache/locking.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/cache/paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/cache/url_normalize.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/_apm_yml_writer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/_helpers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/approve.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/audit.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/compile/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/compile/cli.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/compile/watcher.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/deps/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/deps/_utils.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/deps/cli.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/deps/why.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/doctor.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/experimental.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/find.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/install.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/lifecycle.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/list_cmd.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/lock.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/audit.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/check.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/doctor.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/init.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/migrate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/outdated.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/plugin/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/plugin/add.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/plugin/remove.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/marketplace/validate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/mcp.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/pack.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/plugin/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/plugin/init.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/policy.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/publish.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/run.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/runtime.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/targets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/uninstall/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/uninstall/lockfile_state.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/update.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/commands/view.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/agents_compiler.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/build_id.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/claude_formatter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/constants.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/constitution.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/constitution_block.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/distributed_compiler.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/footer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/gemini_formatter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/injector.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/inventory.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/link_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/managed_section.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/output_writer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/root_context_protection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/template_builder.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/compilation/user_root_context.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/config.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/constants.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/copilot_plugins/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/copilot_plugins/capability.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/copilot_plugins/catalog.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/copilot_plugins/constants.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/copilot_plugins/registrar.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/copilot_plugins/settings.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/_child_tls/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/_child_tls/_apm_tls.pth +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/_child_tls/_apm_tls_bootstrap.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/apm_yml.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/azure_cli.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/build_orchestrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/command_logger.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/conflict_detector.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/deployment_ledger.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/deployment_state.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/docker_args.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/errors.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/experimental.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/host_providers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/install_audit.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/lifecycle_scripts.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/null_logger.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/operations.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/plugin_manifest.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/project_name.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/safe_installer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/scope.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/script_executors.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/script_runner.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/script_trust.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/target_catalog.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/target_detection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/tls_trust.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/core/token_manager.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/_shared.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/aggregator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/artifactory_entry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/bare_cache.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/dependency_graph.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/git_auth_env.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/git_file_transport.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/git_remote_ops.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/git_semver_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/github_downloader.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/github_downloader_validation.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/host_backends.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/installed_package.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/lockfile.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/outdated_ref_cache.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/package_validator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/path_anchoring.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/plugin_parser.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/reachability.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/registry/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/registry/auth.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/registry/client.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/registry/config_loader.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/registry/extractor.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/registry/feature_gate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/registry/semver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/registry_proxy.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/revision_pins.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/shared_clone_cache.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/tiered_ref_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/verifier.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/deps/why_walker.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/drift.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/export/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/export/authoring.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/export/declared_license.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/export/formats.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/export/purl.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/export/sbom.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/export/spdx.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/export/spdx_data.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/factory.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/hook_contract.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/argv.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/artifactory_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/audit_replay.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/audit_target_roots.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/cache_pin.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/context.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/deployable_source_plan.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/drift.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/drift_render.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/dry_run_plan.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/errors.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/exec_gate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/finalization.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/gitlab_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/heals/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/heals/base.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/helpers/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/helpers/no_work.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/helpers/ref_reuse.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/helpers/ref_seed.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/helpers/security_scan.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/insecure_policy.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/integrity.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/legacy_plugin_compat.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/local_bundle_handler.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/local_bundle_paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/locking.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/lsp/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/lsp/integration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/manifest_helpers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/manifest_reconcile.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/mcp/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/mcp/args.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/mcp/command.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/mcp/conflicts.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/mcp/entry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/mcp/integration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/mcp/ownership.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/mcp/registry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/mcp/warnings.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/mcp/writer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/native_plugin_admission.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/package_resolution.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/package_selection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/_redownload.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/_skip_logic.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/audit.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/cleanup.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/copilot_plugins.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/download.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/finalize.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/heal.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/integrate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/local_content.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/lockfile.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/policy_gate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/policy_target_check.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/post_deps_local.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/resolve.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/phases/targets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/pipeline.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/plan.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/presentation/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/presentation/dry_run.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/primitive_classification.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/registry_wiring.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/request.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/resolution_staging.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/root_redirect.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/service.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/service_integration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/services.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/skill_path_migration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/source_helpers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/sources.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/summary.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/target_filter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/target_hints.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/target_warnings.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/install/transaction.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/_hook_dropped_targets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/_shared.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/agent_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/base_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/canvas_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/command_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/copilot_app_db.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/copilot_app_project.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/copilot_app_workflow_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/copilot_app_ws.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/coverage.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/dispatch.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/hook_bundle.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/hook_command_paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/hook_command_warnings.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/hook_file_routing.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/hook_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/hook_ir.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/hook_native_formats.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/hook_ownership.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/hook_reintegration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/hook_source_selection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/instruction_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/kiro_hook_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/lsp_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/mcp_config_view.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/mcp_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/mcp_integrator_install.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/prompt_integrator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/skill_package_routing.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/skill_support.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/skill_transformer.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/targets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/integration/utils.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/_git_utils.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/_io.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/_shared.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/audit.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/auth_helpers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/builder.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/client.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/diagnostics.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/drift_check.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/errors.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/git_stderr.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/init_template.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/migration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/models.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/output_mappers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/output_profiles.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/ref_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/registry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/semver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/shadow_detector.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/source_identity.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/tag_pattern.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/validator.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/version_check.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/version_pins.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/version_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/yml_editor.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/marketplace/yml_schema.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/apm_package.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/host_virtual.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/lsp.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/materialization.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/mcp.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/object_fields.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/provider_coordinates.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/registry_entry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/selection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/subsets.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/dependency/types.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/format_detection.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/manifest_contract.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/plugin.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/models/results.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/output/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/output/formatters.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/output/models.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/output/script_formatters.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/_constraint_pinning.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/_gitlab.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/_help_text.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/_shared.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/ci_checks.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/inheritance.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/install_preflight.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/models.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/outcome_routing.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/parser.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/policy/schema.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/primitives/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/primitives/discovery.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/primitives/models.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/primitives/parser.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/registry/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/registry/client.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/registry/integration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/registry/operations.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/runtime/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/runtime/base.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/runtime/codex_runtime.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/runtime/copilot_runtime.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/runtime/factory.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/runtime/llm_runtime.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/runtime/manager.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/runtime/registry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/runtime/utils.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/audit_report.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/content_scanner.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/executables.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/external/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/external/base.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/external/gate.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/external/generic_sarif.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/external/options.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/external/registry.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/external/runner.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/external/sarif_ingest.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/external/skillspector.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/security/file_scanner.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/update_policy.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/archive.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/atomic_io.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/console.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/content_hash.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/exclude.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/git_sparse.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/github_host.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/guards.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/helpers.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/install_tui.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/net.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/normalization.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/path_security.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/paths.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/patterns.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/perf_stats.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/reflink.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/short_sha.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/staging_guard.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/utils/subprocess_env.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/version.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/workflow/__init__.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/workflow/discovery.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/workflow/parser.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli/workflow/runner.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli.egg-info/dependency_links.txt +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli.egg-info/entry_points.txt +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli.egg-info/requires.txt +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/src/apm_cli.egg-info/top_level.txt +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_apm_package_models.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_apm_resolver.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_codex_docker_args_fix.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_codex_empty_string_and_defaults.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_collision_integration.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_console.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_distributed_compilation.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_empty_string_and_defaults.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_enhanced_discovery.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_github_downloader_token_precedence.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_lockfile.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_runnable_prompts.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_runtime_manager_token_precedence.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.0}/tests/test_token_manager.py +0 -0
- {apm_cli-0.29.1 → apm_cli-0.31.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.31.0
|
|
4
4
|
Summary: MCP configuration tool
|
|
5
5
|
Author-email: Daniel Meppiel <user@example.com>
|
|
6
6
|
License: MIT License
|
|
@@ -78,7 +78,7 @@ Think `package.json`, `requirements.txt`, or `Cargo.toml` — but for AI agent c
|
|
|
78
78
|
|
|
79
79
|
GitHub Copilot | Claude Code | Grok Build | Cursor | OpenCode | Codex | Gemini | Windsurf | Kiro
|
|
80
80
|
|
|
81
|
-
**[Documentation](https://microsoft.github.io/apm/)** · **[Quick Start](https://microsoft.github.io/apm/getting-started/quick-start/)** · **[CLI Reference](https://microsoft.github.io/apm/reference/cli-commands/)** · **[
|
|
81
|
+
**[Documentation](https://microsoft.github.io/apm/)** · **[Quick Start](https://microsoft.github.io/apm/getting-started/quick-start/)** · **[CLI Reference](https://microsoft.github.io/apm/reference/cli-commands/)** · **[Roadmap](https://github.com/orgs/microsoft/projects/2304/views/5)**
|
|
82
82
|
|
|
83
83
|
---
|
|
84
84
|
|
|
@@ -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,22 +191,27 @@ 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, WinGet, 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
|
|
|
199
208
|
#### Windows
|
|
200
209
|
|
|
210
|
+
```powershell
|
|
211
|
+
# WinGet
|
|
212
|
+
winget install --id Microsoft.APM --exact --source winget
|
|
213
|
+
```
|
|
214
|
+
|
|
201
215
|
```powershell
|
|
202
216
|
# Scoop
|
|
203
217
|
scoop bucket add apm https://github.com/microsoft/scoop-apm
|
|
@@ -208,6 +222,9 @@ pip install apm-cli
|
|
|
208
222
|
|
|
209
223
|
</details>
|
|
210
224
|
|
|
225
|
+
Already using the Microsoft Homebrew tap? See the
|
|
226
|
+
[migration guide](https://microsoft.github.io/apm/getting-started/installation/#migrate-from-the-microsoft-tap).
|
|
227
|
+
|
|
211
228
|
Then start adding packages:
|
|
212
229
|
|
|
213
230
|
```bash
|
|
@@ -239,7 +256,7 @@ Use agentrc to author high-quality instructions, then package them with APM to s
|
|
|
239
256
|
|
|
240
257
|
Created by [@danielmeppiel](https://github.com/danielmeppiel). Maintained by [@danielmeppiel](https://github.com/danielmeppiel) and [@sergio-sisternes-epam](https://github.com/sergio-sisternes-epam).
|
|
241
258
|
|
|
242
|
-
- [
|
|
259
|
+
- [Roadmap](https://github.com/orgs/microsoft/projects/2304/views/5)
|
|
243
260
|
- [Discussions](https://github.com/microsoft/apm/discussions)
|
|
244
261
|
- [Contributing](CONTRIBUTING.md)
|
|
245
262
|
- [AI Native Development guide](https://danielmeppiel.github.io/awesome-ai-native) — a practical learning path for AI-native development
|
|
@@ -6,7 +6,7 @@ Think `package.json`, `requirements.txt`, or `Cargo.toml` — but for AI agent c
|
|
|
6
6
|
|
|
7
7
|
GitHub Copilot | Claude Code | Grok Build | Cursor | OpenCode | Codex | Gemini | Windsurf | Kiro
|
|
8
8
|
|
|
9
|
-
**[Documentation](https://microsoft.github.io/apm/)** · **[Quick Start](https://microsoft.github.io/apm/getting-started/quick-start/)** · **[CLI Reference](https://microsoft.github.io/apm/reference/cli-commands/)** · **[
|
|
9
|
+
**[Documentation](https://microsoft.github.io/apm/)** · **[Quick Start](https://microsoft.github.io/apm/getting-started/quick-start/)** · **[CLI Reference](https://microsoft.github.io/apm/reference/cli-commands/)** · **[Roadmap](https://github.com/orgs/microsoft/projects/2304/views/5)**
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -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,22 +119,27 @@ 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, WinGet, 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
|
|
|
127
136
|
#### Windows
|
|
128
137
|
|
|
138
|
+
```powershell
|
|
139
|
+
# WinGet
|
|
140
|
+
winget install --id Microsoft.APM --exact --source winget
|
|
141
|
+
```
|
|
142
|
+
|
|
129
143
|
```powershell
|
|
130
144
|
# Scoop
|
|
131
145
|
scoop bucket add apm https://github.com/microsoft/scoop-apm
|
|
@@ -136,6 +150,9 @@ pip install apm-cli
|
|
|
136
150
|
|
|
137
151
|
</details>
|
|
138
152
|
|
|
153
|
+
Already using the Microsoft Homebrew tap? See the
|
|
154
|
+
[migration guide](https://microsoft.github.io/apm/getting-started/installation/#migrate-from-the-microsoft-tap).
|
|
155
|
+
|
|
139
156
|
Then start adding packages:
|
|
140
157
|
|
|
141
158
|
```bash
|
|
@@ -167,7 +184,7 @@ Use agentrc to author high-quality instructions, then package them with APM to s
|
|
|
167
184
|
|
|
168
185
|
Created by [@danielmeppiel](https://github.com/danielmeppiel). Maintained by [@danielmeppiel](https://github.com/danielmeppiel) and [@sergio-sisternes-epam](https://github.com/sergio-sisternes-epam).
|
|
169
186
|
|
|
170
|
-
- [
|
|
187
|
+
- [Roadmap](https://github.com/orgs/microsoft/projects/2304/views/5)
|
|
171
188
|
- [Discussions](https://github.com/microsoft/apm/discussions)
|
|
172
189
|
- [Contributing](CONTRIBUTING.md)
|
|
173
190
|
- [AI Native Development guide](https://danielmeppiel.github.io/awesome-ai-native) — a practical learning path for AI-native development
|
|
@@ -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.31.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 @@
|
|
|
1
|
+
"""Metadata-only onboarding of existing local packages."""
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""Read native target locations without importing, converting, or executing content.
|
|
2
|
+
|
|
3
|
+
The profile inversion follows @chkp-roniz's discovery work in PR #2857; the
|
|
4
|
+
onboarding result is restricted to existing installable local package roots.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from apm_cli.compilation.root_context_protection import catalog_root_context_markers
|
|
13
|
+
from apm_cli.core.deployment_ledger import DeploymentLedgerCodec
|
|
14
|
+
from apm_cli.core.deployment_state import LocatorKind
|
|
15
|
+
from apm_cli.core.target_detection import SIGNAL_WHITELIST
|
|
16
|
+
from apm_cli.deps.lockfile import LockFile, resolve_lockfile_path_for_read
|
|
17
|
+
from apm_cli.integration.targets import (
|
|
18
|
+
KNOWN_TARGETS,
|
|
19
|
+
active_targets,
|
|
20
|
+
active_targets_user_scope,
|
|
21
|
+
apply_legacy_skill_paths,
|
|
22
|
+
)
|
|
23
|
+
from apm_cli.models.dependency import DependencyReference
|
|
24
|
+
from apm_cli.models.validation import validate_apm_package
|
|
25
|
+
|
|
26
|
+
from .manifest_edit import local_directory, package_entry, read_manifest
|
|
27
|
+
from .safety import MAX_DEPTH, MAX_ENTRIES, checked_file, checked_path, checked_tree
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _inventory(root: Path, *, user_scope: bool) -> list[tuple[Path, str]]:
|
|
31
|
+
"""Invert scope-resolved profiles, including legacy skill roots, once per path."""
|
|
32
|
+
profiles = (
|
|
33
|
+
active_targets_user_scope("all", create_config=False)
|
|
34
|
+
if user_scope
|
|
35
|
+
else active_targets(root, "all", create_config=False)
|
|
36
|
+
)
|
|
37
|
+
profiles = profiles + apply_legacy_skill_paths(profiles)
|
|
38
|
+
directories: dict[Path, str] = {}
|
|
39
|
+
shallow: set[Path] = set()
|
|
40
|
+
for profile in profiles:
|
|
41
|
+
base = root / profile.root_dir
|
|
42
|
+
shallow.add(base)
|
|
43
|
+
for primitive, mapping in profile.primitives.items():
|
|
44
|
+
directory = root / (mapping.deploy_root or profile.root_dir) / mapping.subdir
|
|
45
|
+
if mapping.subdir:
|
|
46
|
+
directories[directory] = primitive
|
|
47
|
+
else:
|
|
48
|
+
shallow.add(directory)
|
|
49
|
+
found: dict[Path, str] = {}
|
|
50
|
+
for _, kind, relative in SIGNAL_WHITELIST:
|
|
51
|
+
if kind == "file":
|
|
52
|
+
candidate = root / relative
|
|
53
|
+
if candidate.exists() or candidate.is_symlink():
|
|
54
|
+
found[candidate] = "native"
|
|
55
|
+
for name in catalog_root_context_markers():
|
|
56
|
+
candidate = root / name
|
|
57
|
+
if candidate.exists() or candidate.is_symlink():
|
|
58
|
+
found[candidate] = "native"
|
|
59
|
+
if (root / "SKILL.md").exists():
|
|
60
|
+
found[root] = "package"
|
|
61
|
+
count = 0
|
|
62
|
+
pending = [(directory, kind, 0) for directory, kind in directories.items()]
|
|
63
|
+
pending.extend((directory, "native", MAX_DEPTH) for directory in shallow)
|
|
64
|
+
visited: set[Path] = set()
|
|
65
|
+
while pending:
|
|
66
|
+
directory, kind, depth = pending.pop()
|
|
67
|
+
if directory in visited:
|
|
68
|
+
continue
|
|
69
|
+
visited.add(directory)
|
|
70
|
+
try:
|
|
71
|
+
checked_path(directory, root)
|
|
72
|
+
except ValueError:
|
|
73
|
+
if directory.exists() or directory.is_symlink():
|
|
74
|
+
found[directory] = "unsafe"
|
|
75
|
+
continue
|
|
76
|
+
if not directory.is_dir():
|
|
77
|
+
continue
|
|
78
|
+
if (directory / "SKILL.md").exists() or (directory / "apm.yml").exists():
|
|
79
|
+
found[directory] = "package"
|
|
80
|
+
continue
|
|
81
|
+
for child in directory.iterdir():
|
|
82
|
+
count += 1
|
|
83
|
+
if count > MAX_ENTRIES:
|
|
84
|
+
raise ValueError(
|
|
85
|
+
"Discovery entry limit exceeded. Narrow the project before retrying."
|
|
86
|
+
)
|
|
87
|
+
if child.is_symlink():
|
|
88
|
+
found[child] = "unsafe"
|
|
89
|
+
elif child.is_file():
|
|
90
|
+
found[child] = kind
|
|
91
|
+
elif child.is_dir() and depth < MAX_DEPTH:
|
|
92
|
+
pending.append((child, kind, depth + 1))
|
|
93
|
+
elif not child.is_dir() or kind != "native":
|
|
94
|
+
found[child] = "unsafe"
|
|
95
|
+
return sorted(found.items(), key=lambda item: item[0].as_posix())
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _managed_paths(consumer: Path, root: Path) -> set[Path]:
|
|
99
|
+
"""Read actual deployment claims through the canonical ledger codec."""
|
|
100
|
+
path = resolve_lockfile_path_for_read(consumer, read_only=True)
|
|
101
|
+
checked_path(path, root)
|
|
102
|
+
if not path.exists():
|
|
103
|
+
return set()
|
|
104
|
+
checked_file(path, root)
|
|
105
|
+
lockfile = LockFile.read(path)
|
|
106
|
+
if lockfile is None:
|
|
107
|
+
return set()
|
|
108
|
+
result: set[Path] = set()
|
|
109
|
+
for record in DeploymentLedgerCodec.from_lockfile(lockfile).records.values():
|
|
110
|
+
if record.locator.kind is LocatorKind.URI:
|
|
111
|
+
continue
|
|
112
|
+
profile = KNOWN_TARGETS.get(record.locator.target, next(iter(KNOWN_TARGETS.values())))
|
|
113
|
+
if record.locator.kind is LocatorKind.TARGET_RELATIVE:
|
|
114
|
+
profile = profile.for_scope(user_scope=True)
|
|
115
|
+
if profile is None:
|
|
116
|
+
continue
|
|
117
|
+
candidate = DeploymentLedgerCodec.resolve_locator(
|
|
118
|
+
record.locator, project_root=root, target=profile
|
|
119
|
+
)
|
|
120
|
+
checked_path(candidate, root)
|
|
121
|
+
result.add(candidate)
|
|
122
|
+
return result
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def discover(root: Path, manifest: Path, *, user_scope: bool = False) -> dict[str, Any]:
|
|
126
|
+
"""Build a read-only report using normal package admission and identities."""
|
|
127
|
+
_, references, _ = read_manifest(manifest, root)
|
|
128
|
+
consumer = manifest.parent
|
|
129
|
+
declared = {local_directory(ref, consumer) for ref in references if ref.is_local}
|
|
130
|
+
slots: dict[Path, set[Path | str]] = {}
|
|
131
|
+
for ref in references:
|
|
132
|
+
if not ref.is_marketplace:
|
|
133
|
+
identity = local_directory(ref, consumer) if ref.is_local else ref.get_unique_key()
|
|
134
|
+
slot = ref.get_install_path(consumer / "apm_modules")
|
|
135
|
+
slots.setdefault(slot, set()).add(identity)
|
|
136
|
+
managed = _managed_paths(consumer, root)
|
|
137
|
+
findings: list[dict[str, Any]] = []
|
|
138
|
+
for slot, identities in slots.items():
|
|
139
|
+
if len(identities) > 1:
|
|
140
|
+
findings.append(
|
|
141
|
+
{
|
|
142
|
+
"path": manifest.relative_to(root).as_posix(),
|
|
143
|
+
"kind": "manifest",
|
|
144
|
+
"status": "unsafe",
|
|
145
|
+
"reason": (
|
|
146
|
+
"Existing dependency install identity collision at "
|
|
147
|
+
f"{slot.relative_to(consumer).as_posix()}. "
|
|
148
|
+
"Remove conflicting references and retry."
|
|
149
|
+
),
|
|
150
|
+
"dependency": None,
|
|
151
|
+
}
|
|
152
|
+
)
|
|
153
|
+
supported: list[tuple[dict[str, Any], Path, Path]] = []
|
|
154
|
+
for path, kind in _inventory(root, user_scope=user_scope):
|
|
155
|
+
finding = {
|
|
156
|
+
"path": path.relative_to(root).as_posix() if path.is_relative_to(root) else str(path),
|
|
157
|
+
"kind": kind,
|
|
158
|
+
"status": "unsupported",
|
|
159
|
+
"reason": "Loose native content is not a package. Prepare a supported package manually.",
|
|
160
|
+
"dependency": None,
|
|
161
|
+
}
|
|
162
|
+
findings.append(finding)
|
|
163
|
+
try:
|
|
164
|
+
checked_path(path, root)
|
|
165
|
+
if kind == "unsafe":
|
|
166
|
+
raise ValueError("Unsafe path; use a regular directory within the discovery root.")
|
|
167
|
+
if any(path == owned or path.is_relative_to(owned) for owned in managed) or (
|
|
168
|
+
path.is_dir() and any(owned.is_relative_to(path) for owned in managed)
|
|
169
|
+
):
|
|
170
|
+
finding.update(
|
|
171
|
+
status="managed", reason="Already managed by the installation ledger."
|
|
172
|
+
)
|
|
173
|
+
continue
|
|
174
|
+
if kind != "package":
|
|
175
|
+
checked_file(path, root)
|
|
176
|
+
continue
|
|
177
|
+
if path == consumer or consumer.is_relative_to(path):
|
|
178
|
+
finding.update(
|
|
179
|
+
status="unsafe",
|
|
180
|
+
reason="Source contains the consumer; self-dependencies are refused.",
|
|
181
|
+
)
|
|
182
|
+
continue
|
|
183
|
+
checked_tree(path, root)
|
|
184
|
+
if (path / "apm.yml").exists():
|
|
185
|
+
read_manifest(path / "apm.yml", root)
|
|
186
|
+
admission = validate_apm_package(path, read_only=True)
|
|
187
|
+
if not admission.is_valid:
|
|
188
|
+
finding["reason"] = (
|
|
189
|
+
"Existing package admission rejected this directory. Prepare it manually."
|
|
190
|
+
)
|
|
191
|
+
continue
|
|
192
|
+
entry = package_entry(path, consumer, user_scope=user_scope)
|
|
193
|
+
finding["dependency"] = entry
|
|
194
|
+
if path.resolve() in declared:
|
|
195
|
+
finding.update(
|
|
196
|
+
status="already-declared", reason="Existing dependency and options preserved."
|
|
197
|
+
)
|
|
198
|
+
continue
|
|
199
|
+
if any(path.is_relative_to(other) or other.is_relative_to(path) for other in declared):
|
|
200
|
+
finding.update(
|
|
201
|
+
status="unsafe", reason="Package overlaps an existing dependency source."
|
|
202
|
+
)
|
|
203
|
+
continue
|
|
204
|
+
ref = DependencyReference.parse_from_dict(entry)
|
|
205
|
+
slot = ref.get_install_path(consumer / "apm_modules")
|
|
206
|
+
finding.update(
|
|
207
|
+
status="supported",
|
|
208
|
+
reason="Existing local package; only a dependency will be added.",
|
|
209
|
+
)
|
|
210
|
+
supported.append((finding, path, slot))
|
|
211
|
+
except (ValueError, OSError) as exc:
|
|
212
|
+
finding.update(
|
|
213
|
+
status="unsafe",
|
|
214
|
+
reason=f"{type(exc).__name__}: package/path rejected. Repair it and retry.",
|
|
215
|
+
)
|
|
216
|
+
by_slot: dict[Path, list[dict[str, Any]]] = {}
|
|
217
|
+
for finding, path, slot in supported:
|
|
218
|
+
by_slot.setdefault(slot, []).append(finding)
|
|
219
|
+
if slot in slots and slots[slot] != {path.resolve()}:
|
|
220
|
+
finding.update(
|
|
221
|
+
status="unsafe", reason="Install identity collision with an existing dependency."
|
|
222
|
+
)
|
|
223
|
+
for group in by_slot.values():
|
|
224
|
+
if len(group) > 1:
|
|
225
|
+
for finding in group:
|
|
226
|
+
finding.update(
|
|
227
|
+
status="unsafe",
|
|
228
|
+
reason="Install identity collision: packages share an install path.",
|
|
229
|
+
)
|
|
230
|
+
for index, (finding, path, _) in enumerate(supported):
|
|
231
|
+
for other_finding, other, _ in supported[index + 1 :]:
|
|
232
|
+
if path.is_relative_to(other) or other.is_relative_to(path):
|
|
233
|
+
finding.update(
|
|
234
|
+
status="unsafe",
|
|
235
|
+
reason="Overlapping package roots cannot be onboarded together.",
|
|
236
|
+
)
|
|
237
|
+
other_finding.update(
|
|
238
|
+
status="unsafe",
|
|
239
|
+
reason="Overlapping package roots cannot be onboarded together.",
|
|
240
|
+
)
|
|
241
|
+
return {
|
|
242
|
+
"scope": "global" if user_scope else "project",
|
|
243
|
+
"root": str(root),
|
|
244
|
+
"manifest": str(manifest),
|
|
245
|
+
"findings": findings,
|
|
246
|
+
"additions": [item["dependency"] for item in findings if item["status"] == "supported"],
|
|
247
|
+
"applied": False,
|
|
248
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Consumer manifest planning: preserve author metadata; never edit sources."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from apm_cli.deps.path_anchoring import _join
|
|
9
|
+
from apm_cli.models.apm_package import APMPackage
|
|
10
|
+
from apm_cli.models.dependency import DependencyReference
|
|
11
|
+
from apm_cli.models.dependency.object_fields import local_path_apm_yml_entry
|
|
12
|
+
from apm_cli.utils.yaml_io import (
|
|
13
|
+
load_yaml_roundtrip,
|
|
14
|
+
write_yaml_text_atomic,
|
|
15
|
+
yaml_roundtrip_to_str,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from .safety import checked_file, checked_path
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def read_manifest(path: Path, root: Path) -> tuple[Any, list[DependencyReference], bytes | None]:
|
|
22
|
+
"""Read and validate existing metadata; do not silently replace invalid YAML."""
|
|
23
|
+
checked_path(path, root)
|
|
24
|
+
if not path.exists():
|
|
25
|
+
return {"name": "onboarded-project", "version": "1.0.0"}, [], None
|
|
26
|
+
checked_file(path, root)
|
|
27
|
+
original = path.read_bytes()
|
|
28
|
+
data = load_yaml_roundtrip(path)
|
|
29
|
+
if not isinstance(data, dict):
|
|
30
|
+
raise ValueError("Invalid apm.yml: expected a mapping. Repair the manifest and retry.")
|
|
31
|
+
for group in ("dependencies", "devDependencies"):
|
|
32
|
+
dependencies = data.get(group, {})
|
|
33
|
+
if not isinstance(dependencies, dict):
|
|
34
|
+
raise ValueError(f"Invalid apm.yml: {group} must be a mapping.")
|
|
35
|
+
for kind, entries in dependencies.items():
|
|
36
|
+
if not isinstance(entries, list) or any(
|
|
37
|
+
not isinstance(entry, (str, dict)) for entry in entries
|
|
38
|
+
):
|
|
39
|
+
raise ValueError(f"Invalid apm.yml: {group}.{kind} must be a list of references.")
|
|
40
|
+
package = APMPackage.from_mapping(data, package_path=path.parent, create_config=False)
|
|
41
|
+
references = package.get_all_apm_dependencies()
|
|
42
|
+
return data, references, original
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def local_directory(reference: DependencyReference, consumer: Path) -> Path:
|
|
46
|
+
"""Resolve a direct local reference through the existing path anchoring owner."""
|
|
47
|
+
return _join(consumer, reference.local_path)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def package_entry(source: Path, consumer: Path, *, user_scope: bool) -> dict[str, object]:
|
|
51
|
+
"""Emit the canonical local object form, absolute at user scope."""
|
|
52
|
+
raw = source.as_posix() if user_scope else "./" + source.relative_to(consumer).as_posix()
|
|
53
|
+
reference = DependencyReference.parse(raw)
|
|
54
|
+
return local_path_apm_yml_entry(reference.local_path, None, None, None)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def write_manifest(
|
|
58
|
+
path: Path,
|
|
59
|
+
root: Path,
|
|
60
|
+
data: Any,
|
|
61
|
+
additions: list[dict[str, object]],
|
|
62
|
+
original: bytes | None,
|
|
63
|
+
) -> bool:
|
|
64
|
+
"""Commit only missing dependency entries, atomically, after revalidation."""
|
|
65
|
+
if not additions:
|
|
66
|
+
return False
|
|
67
|
+
checked_path(path, root)
|
|
68
|
+
current = path.read_bytes() if path.exists() else None
|
|
69
|
+
if current != original:
|
|
70
|
+
raise ValueError("apm.yml changed during discovery. Review and retry.")
|
|
71
|
+
data.setdefault("dependencies", {}).setdefault("apm", []).extend(additions)
|
|
72
|
+
content = yaml_roundtrip_to_str(data)
|
|
73
|
+
checked_path(path.parent, root)
|
|
74
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
75
|
+
write_yaml_text_atomic(path, content)
|
|
76
|
+
return True
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Apply an approved manifest delta, never source or deployment content."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from apm_cli.install.locking import lifecycle_operation
|
|
9
|
+
|
|
10
|
+
from .discovery import discover
|
|
11
|
+
from .manifest_edit import read_manifest, write_manifest
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def apply_report(report: dict[str, Any]) -> dict[str, Any]:
|
|
15
|
+
"""Revalidate the consented plan under the normal lifecycle lock."""
|
|
16
|
+
if any(item["status"] == "unsafe" for item in report["findings"]):
|
|
17
|
+
raise ValueError(
|
|
18
|
+
"Unsafe paths or install identity collisions found. Repair them and rediscover."
|
|
19
|
+
)
|
|
20
|
+
if not report["additions"]:
|
|
21
|
+
return report
|
|
22
|
+
root = Path(report["root"])
|
|
23
|
+
manifest = Path(report["manifest"])
|
|
24
|
+
with lifecycle_operation():
|
|
25
|
+
data, _, original = read_manifest(manifest, root)
|
|
26
|
+
current = discover(root, manifest, user_scope=report["scope"] == "global")
|
|
27
|
+
if current != report:
|
|
28
|
+
raise ValueError(
|
|
29
|
+
"Discovery changed since the preview. Review the new report and retry."
|
|
30
|
+
)
|
|
31
|
+
current["applied"] = write_manifest(manifest, root, data, current["additions"], original)
|
|
32
|
+
return current
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Onboarding presentation at the CommandLogger boundary."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import sys
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from apm_cli.core.command_logger import CommandLogger
|
|
10
|
+
from apm_cli.utils.yaml_io import yaml_to_str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DiscoveryLogger(CommandLogger):
|
|
14
|
+
"""Render inventory without exposing file contents or native secrets."""
|
|
15
|
+
|
|
16
|
+
def report(self, report: dict[str, Any], fmt: str) -> None:
|
|
17
|
+
"""Render one complete report; machine stdout contains only data."""
|
|
18
|
+
if fmt != "text":
|
|
19
|
+
content = json.dumps(report, indent=2) + "\n" if fmt == "json" else yaml_to_str(report)
|
|
20
|
+
sys.stdout.write(content)
|
|
21
|
+
return
|
|
22
|
+
self.info(f"Discovery ({report['scope']}): {report['root']}")
|
|
23
|
+
for finding in report["findings"]:
|
|
24
|
+
self.info(f"{finding['status']}: {finding['path']} -- {finding['reason']}")
|
|
25
|
+
for entry in report["additions"]:
|
|
26
|
+
self.info(f"apm.yml dependencies.apm: path: {entry['path']}")
|
|
27
|
+
if report["applied"]:
|
|
28
|
+
install = "apm install --global" if report["scope"] == "global" else "apm install"
|
|
29
|
+
self.success(f"Updated consumer apm.yml. Run '{install}' separately.")
|
|
30
|
+
elif report["additions"]:
|
|
31
|
+
self.info(
|
|
32
|
+
"Read-only preview. Use --apply to add these dependencies after confirmation."
|
|
33
|
+
)
|
|
34
|
+
else:
|
|
35
|
+
self.info("No missing supported package dependencies; no manifest changes.")
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Bounded, non-following filesystem reads for onboarding."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import stat
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from apm_cli.utils.path_security import ensure_path_within, has_symlink_component
|
|
9
|
+
|
|
10
|
+
MAX_ENTRIES = 2000
|
|
11
|
+
MAX_FILE_BYTES = 1024 * 1024
|
|
12
|
+
MAX_DEPTH = 16
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def checked_path(path: Path, root: Path) -> Path:
|
|
16
|
+
"""Reject symlinks and escapes before inspecting a discovery path."""
|
|
17
|
+
if has_symlink_component(root, path):
|
|
18
|
+
raise ValueError("Symlinked paths are not onboarded; use a regular directory.")
|
|
19
|
+
return ensure_path_within(path, root)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def checked_file(path: Path, root: Path) -> None:
|
|
23
|
+
"""Bound parser inputs and reject device files without opening them."""
|
|
24
|
+
checked_path(path, root)
|
|
25
|
+
info = path.stat()
|
|
26
|
+
if not stat.S_ISREG(info.st_mode) or info.st_size > MAX_FILE_BYTES:
|
|
27
|
+
raise ValueError("Not a regular file or exceeds the 1 MiB discovery read limit.")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def checked_tree(path: Path, root: Path) -> None:
|
|
31
|
+
"""Validate package trees without reading payloads or following symlinks."""
|
|
32
|
+
checked_path(path, root)
|
|
33
|
+
pending = [(path, 0)]
|
|
34
|
+
count = 0
|
|
35
|
+
while pending:
|
|
36
|
+
directory, depth = pending.pop()
|
|
37
|
+
if depth > MAX_DEPTH:
|
|
38
|
+
raise ValueError(
|
|
39
|
+
"Package exceeds the discovery depth limit; prepare a smaller package."
|
|
40
|
+
)
|
|
41
|
+
for child in directory.iterdir():
|
|
42
|
+
count += 1
|
|
43
|
+
if count > MAX_ENTRIES:
|
|
44
|
+
raise ValueError(
|
|
45
|
+
"Package exceeds the discovery entry limit; prepare a smaller package."
|
|
46
|
+
)
|
|
47
|
+
checked_path(child, root)
|
|
48
|
+
if child.is_dir():
|
|
49
|
+
pending.append((child, depth + 1))
|
|
50
|
+
else:
|
|
51
|
+
checked_file(child, root)
|
|
@@ -10,13 +10,16 @@ from .errors import AgentPluginManifestAuthorityError
|
|
|
10
10
|
from .ir import AgentPlugin, thaw_frozen_json
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def project_agent_plugin_package(plugin: AgentPlugin) -> APMPackage:
|
|
13
|
+
def project_agent_plugin_package(plugin: AgentPlugin, *, create_config: bool = True) -> APMPackage:
|
|
14
14
|
"""Project canonical Agent Plugin facts into the compatibility package model.
|
|
15
15
|
|
|
16
16
|
Portable identity comes only from ``plugin.identity``. APM-owned manifest
|
|
17
17
|
fields come only from ``plugin.apm_configuration``. Component facts remain
|
|
18
18
|
attached through the canonical frozen IR rather than being reparsed from
|
|
19
19
|
``plugin.json``, ``mcp.json``, or the package filesystem.
|
|
20
|
+
|
|
21
|
+
Read-only admission passes ``create_config=False`` to avoid initializing
|
|
22
|
+
user configuration while projecting existing source metadata.
|
|
20
23
|
"""
|
|
21
24
|
data = _project_apm_configuration(plugin)
|
|
22
25
|
identity = plugin.identity
|
|
@@ -41,6 +44,7 @@ def project_agent_plugin_package(plugin: AgentPlugin) -> APMPackage:
|
|
|
41
44
|
package_path=plugin.root,
|
|
42
45
|
source_path=plugin.root,
|
|
43
46
|
manifest_path=manifest_path,
|
|
47
|
+
create_config=create_config,
|
|
44
48
|
)
|
|
45
49
|
except (TargetResolutionError, ValueError) as exc:
|
|
46
50
|
raise AgentPluginManifestAuthorityError(
|