apm-cli 0.32.0__tar.gz → 0.34.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.32.0/src/apm_cli.egg-info → apm_cli-0.34.0}/PKG-INFO +11 -11
- {apm_cli-0.32.0 → apm_cli-0.34.0}/README.md +10 -10
- {apm_cli-0.32.0 → apm_cli-0.34.0}/pyproject.toml +3 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/base.py +105 -10
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/claude.py +69 -12
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/codex.py +63 -5
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/copilot.py +6 -5
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/cursor.py +94 -35
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/opencode.py +58 -21
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/lockfile_enrichment.py +22 -19
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/cli.py +22 -3
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/_helpers.py +31 -4
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/audit.py +106 -60
- apm_cli-0.34.0/src/apm_cli/commands/auth.py +512 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/compile/cli.py +42 -6
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/deps/cli.py +24 -7
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/install.py +31 -13
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/prune.py +5 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/targets.py +31 -16
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/uninstall/engine.py +2 -4
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/uninstall/lockfile_state.py +1 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/agents_compiler.py +74 -57
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/build_id.py +35 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/claude_formatter.py +78 -30
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/root_context_protection.py +108 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/user_root_context.py +86 -17
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/auth.py +129 -10
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/command_logger.py +8 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/conflict_detector.py +19 -3
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/deployment_ledger.py +115 -18
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/deployment_state.py +3 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/host_providers.py +10 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/safe_installer.py +5 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/script_executors.py +10 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/target_catalog.py +69 -55
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/target_detection.py +29 -22
- apm_cli-0.34.0/src/apm_cli/core/tls_trust.py +625 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/token_manager.py +18 -3
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/bare_cache.py +12 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/git_reference_resolver.py +3 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/git_remote_ops.py +66 -38
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/installed_package.py +19 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/lockfile.py +84 -3
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/tiered_ref_resolver.py +59 -13
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/drift.py +37 -12
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/hook_contract.py +34 -10
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/audit_replay.py +3 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/deployable_source_plan.py +50 -17
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/deployed_paths.py +42 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/drift.py +20 -56
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/drift_render.py +47 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/errors.py +31 -12
- apm_cli-0.34.0/src/apm_cli/install/helpers/no_work.py +96 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/helpers/ref_reuse.py +9 -3
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/helpers/ref_seed.py +6 -4
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/manifest_reconcile.py +58 -24
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/mcp/command.py +37 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/mcp/integration.py +26 -14
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/mcp/ownership.py +6 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/integrate.py +29 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/lockfile.py +2 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/post_deps_local.py +10 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/resolve.py +1 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/targets.py +5 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/pipeline.py +21 -5
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/plan.py +24 -3
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/presentation/dry_run.py +13 -4
- apm_cli-0.34.0/src/apm_cli/install/project_package.py +26 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/service.py +161 -36
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/services.py +30 -49
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/sources.py +20 -3
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/target_filter.py +105 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/validation.py +30 -13
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/agent_integrator.py +156 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/cleanup.py +14 -11
- apm_cli-0.34.0/src/apm_cli/integration/hook_cursor_preflight.py +249 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/hook_integrator.py +117 -117
- apm_cli-0.34.0/src/apm_cli/integration/hook_native_formats.py +451 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/hook_ownership.py +32 -9
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/instruction_integrator.py +75 -175
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/mcp_integrator.py +79 -18
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/mcp_integrator_install.py +64 -11
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/skill_integrator.py +92 -106
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/skill_support.py +24 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/targets.py +334 -249
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/builder.py +106 -45
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/client.py +56 -16
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/output_mappers.py +135 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/output_profiles.py +9 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/ref_resolver.py +23 -6
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/resolver.py +95 -14
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/version_resolver.py +18 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/yml_schema.py +42 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/apm_package.py +107 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/materialization.py +20 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/mcp.py +80 -4
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/provider_coordinates.py +4 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/ci_checks.py +72 -13
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/models.py +48 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/primitives/discovery.py +44 -104
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/primitives/models.py +32 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/primitives/parser.py +9 -1
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/registry/operations.py +26 -6
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/runtime/manager.py +11 -3
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/audit_report.py +151 -48
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/content_scanner.py +1 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/external/options.py +89 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/external/skillspector.py +17 -2
- apm_cli-0.34.0/src/apm_cli/security/file_scanner.py +580 -0
- apm_cli-0.34.0/src/apm_cli/security/primitive_discovery.py +189 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/git_env.py +35 -2
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/github_host.py +48 -13
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/path_security.py +13 -4
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/patterns.py +94 -3
- {apm_cli-0.32.0 → apm_cli-0.34.0/src/apm_cli.egg-info}/PKG-INFO +11 -11
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli.egg-info/SOURCES.txt +4 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_lockfile.py +1 -0
- apm_cli-0.32.0/src/apm_cli/core/tls_trust.py +0 -343
- apm_cli-0.32.0/src/apm_cli/install/helpers/no_work.py +0 -34
- apm_cli-0.32.0/src/apm_cli/integration/hook_native_formats.py +0 -109
- apm_cli-0.32.0/src/apm_cli/security/file_scanner.py +0 -275
- {apm_cli-0.32.0 → apm_cli-0.34.0}/AUTHORS +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/LICENSE +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/NOTICE +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/setup.cfg +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/antigravity.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/gemini.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/hermes.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/intellij.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/kiro.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/vscode.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/client/windsurf.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/package_manager/base.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adopt/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adopt/discovery.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adopt/manifest_edit.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adopt/materialize.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adopt/render.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/adopt/safety.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/agent_plugins/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/agent_plugins/assets.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/agent_plugins/constants.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/agent_plugins/errors.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/agent_plugins/io.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/agent_plugins/ir.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/agent_plugins/loader.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/agent_plugins/projection.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/agent_plugins/validation.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bootstrap_mirror.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/agent_plugin_exporter.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/attest.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/claude_plugin_exporter.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/export_common.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/formats.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/local_bundle.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/packer.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/plugin_exporter.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/plugin_layout.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/reproducible_archive.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/bundle/unpacker.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/cache/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/cache/cleanup.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/cache/git_cache.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/cache/http_cache.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/cache/integrity.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/cache/locking.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/cache/paths.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/cache/url_normalize.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/_apm_yml_writer.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/approve.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/cache.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/compile/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/compile/watcher.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/config.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/deps/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/deps/_utils.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/deps/why.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/discover.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/doctor.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/experimental.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/find.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/init.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/lifecycle.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/list_cmd.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/lock.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/audit.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/check.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/doctor.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/init.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/migrate.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/outdated.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/plugin/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/plugin/add.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/plugin/remove.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/marketplace/validate.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/mcp.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/outdated.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/pack.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/plugin/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/plugin/init.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/policy.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/publish.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/run.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/runtime.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/self_update.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/uninstall/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/uninstall/cli.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/update.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/commands/view.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/constants.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/constitution.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/constitution_block.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/context_optimizer.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/distributed_compiler.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/footer.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/gemini_formatter.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/injector.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/inventory.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/link_resolver.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/managed_section.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/output_writer.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/compilation/template_builder.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/config.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/constants.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/copilot_plugins/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/copilot_plugins/capability.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/copilot_plugins/catalog.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/copilot_plugins/constants.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/copilot_plugins/registrar.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/copilot_plugins/settings.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/_child_tls/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/_child_tls/_apm_tls.pth +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/_child_tls/_apm_tls_bootstrap.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/apm_yml.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/azure_cli.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/build_orchestrator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/docker_args.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/errors.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/experimental.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/install_audit.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/lifecycle_scripts.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/null_logger.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/operations.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/output_mode.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/plugin_manifest.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/project_name.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/scope.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/script_runner.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/core/script_trust.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/_shared.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/aggregator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/apm_resolver.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/artifactory_entry.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/clone_engine.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/dependency_graph.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/download_strategies.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/git_auth_env.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/git_file_transport.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/git_semver_resolver.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/github_downloader.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/github_downloader_validation.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/github_rate_limit.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/host_backends.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/immutable_requirements.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/outdated_ref_cache.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/outdated_row.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/package_validator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/path_anchoring.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/plugin_parser.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/reachability.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/registry/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/registry/auth.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/registry/client.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/registry/config_loader.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/registry/extractor.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/registry/feature_gate.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/registry/outdated.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/registry/resolver.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/registry/semver.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/registry_proxy.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/revision_pins.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/shared_clone_cache.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/transport_selection.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/verifier.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/deps/why_walker.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/export/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/export/authoring.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/export/declared_license.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/export/formats.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/export/purl.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/export/sbom.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/export/spdx.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/export/spdx_data.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/factory.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/argv.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/artifactory_resolver.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/audit_target_roots.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/cache_pin.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/context.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/dry_run_plan.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/exec_gate.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/finalization.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/gitlab_resolver.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/heals/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/heals/base.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/helpers/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/helpers/security_scan.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/insecure_policy.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/integrity.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/legacy_plugin_compat.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/local_bundle_handler.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/local_bundle_paths.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/locking.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/lsp/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/lsp/integration.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/manifest_helpers.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/mcp/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/mcp/args.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/mcp/conflicts.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/mcp/entry.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/mcp/registry.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/mcp/warnings.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/mcp/writer.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/native_plugin_admission.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/outcome.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/package_resolution.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/package_selection.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/_redownload.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/_skip_logic.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/audit.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/cleanup.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/copilot_plugins.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/download.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/finalize.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/heal.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/local_content.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/policy_gate.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/phases/policy_target_check.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/presentation/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/primitive_classification.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/registry_wiring.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/request.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/resolution_staging.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/root_redirect.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/service_integration.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/skill_path_migration.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/source_helpers.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/summary.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/target_hints.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/target_warnings.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/template.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/install/transaction.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/_hook_dropped_targets.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/_shared.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/base_integrator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/canvas_integrator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/command_integrator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/copilot_app_db.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/copilot_app_project.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/copilot_app_workflow_integrator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/copilot_app_ws.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/coverage.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/dispatch.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/hook_bundle.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/hook_command_paths.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/hook_command_warnings.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/hook_file_routing.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/hook_ir.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/hook_reintegration.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/hook_source_selection.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/kiro_hook_integrator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/lsp_integrator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/mcp_config_view.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/prompt_integrator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/skill_package_routing.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/skill_transformer.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/integration/utils.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/_git_utils.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/_io.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/_shared.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/audit.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/auth_helpers.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/diagnostics.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/drift_check.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/errors.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/git_stderr.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/init_template.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/migration.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/models.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/registry.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/semver.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/shadow_detector.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/source_identity.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/tag_pattern.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/validator.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/version_check.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/version_pins.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/marketplace/yml_editor.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/host_virtual.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/identity.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/lsp.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/object_fields.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/reference.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/registry_entry.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/selection.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/subsets.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/dependency/types.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/format_detection.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/manifest_contract.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/plugin.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/results.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/models/validation.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/output/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/output/formatters.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/output/models.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/output/script_formatters.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/_constraint_pinning.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/_gitlab.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/_help_text.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/_shared.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/discovery.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/inheritance.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/install_preflight.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/matcher.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/outcome_routing.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/parser.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/policy_checks.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/project_config.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/policy/schema.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/primitives/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/registry/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/registry/client.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/registry/integration.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/runtime/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/runtime/base.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/runtime/codex_runtime.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/runtime/copilot_runtime.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/runtime/factory.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/runtime/llm_runtime.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/runtime/registry.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/runtime/utils.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/executables.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/external/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/external/base.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/external/gate.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/external/generic_sarif.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/external/registry.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/external/runner.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/external/sarif_ingest.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/security/gate.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/update_policy.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/archive.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/atomic_io.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/console.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/content_hash.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/diagnostics.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/exclude.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/file_ops.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/git_sparse.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/guards.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/helpers.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/install_tui.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/net.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/normalization.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/paths.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/perf_stats.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/reflink.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/short_sha.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/staging_guard.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/subprocess_env.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/version_checker.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/utils/yaml_io.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/version.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/workflow/__init__.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/workflow/discovery.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/workflow/parser.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli/workflow/runner.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli.egg-info/dependency_links.txt +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli.egg-info/entry_points.txt +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli.egg-info/requires.txt +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/src/apm_cli.egg-info/top_level.txt +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_apm_package_models.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_apm_resolver.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_codex_docker_args_fix.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_codex_empty_string_and_defaults.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_collision_integration.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_console.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_distributed_compilation.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_empty_string_and_defaults.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_enhanced_discovery.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_github_downloader.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_github_downloader_token_precedence.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_gitlab_git_transport.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_runnable_prompts.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_runtime_manager_token_precedence.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.0}/tests/test_token_manager.py +0 -0
- {apm_cli-0.32.0 → apm_cli-0.34.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.34.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/
|
|
81
|
+
**[Documentation](https://microsoft.github.io/apm/)** · **[Quick Start](https://microsoft.github.io/apm/quickstart/)** · **[CLI Reference](https://microsoft.github.io/apm/reference/)** · **[Roadmap](https://github.com/orgs/microsoft/projects/2304/views/5)**
|
|
82
82
|
|
|
83
83
|
---
|
|
84
84
|
|
|
@@ -140,11 +140,11 @@ One command, no configuration -- VS Code and GitHub Copilot read the file automa
|
|
|
140
140
|
One `apm.yml` describes every primitive your agents need — instructions, skills, prompts, agents, hooks, plugins, MCP servers — and `apm install` reproduces the exact same setup across every client on every machine. `apm.lock.yaml` pins the resolved tree the way `package-lock.json` does for npm.
|
|
141
141
|
|
|
142
142
|
- **[One manifest for everything](https://microsoft.github.io/apm/reference/primitive-types/)** -- declared once, deployed across Copilot, Claude, Grok Build, Cursor, OpenCode, Codex, Gemini, Windsurf, Kiro
|
|
143
|
-
- **[Install from anywhere](https://microsoft.github.io/apm/
|
|
144
|
-
- **[Transitive dependencies](https://microsoft.github.io/apm/
|
|
145
|
-
- **[Author plugins](https://microsoft.github.io/apm/
|
|
146
|
-
- **[Marketplaces](https://microsoft.github.io/apm/
|
|
147
|
-
- **[Pack & distribute](https://microsoft.github.io/apm/
|
|
143
|
+
- **[Install from anywhere](https://microsoft.github.io/apm/consumer/install-packages/)** — GitHub, GitLab, Bitbucket, Azure DevOps, GitHub Enterprise, Gitea, Gogs, any git host
|
|
144
|
+
- **[Transitive dependencies](https://microsoft.github.io/apm/consumer/install-packages/#transitive-dependencies-and-the-lockfile)** — packages can depend on packages; APM resolves the full tree
|
|
145
|
+
- **[Author plugins](https://microsoft.github.io/apm/producer/)** — build Copilot, Claude, and Cursor plugins with dependency management, then export standard `plugin.json`
|
|
146
|
+
- **[Marketplaces](https://microsoft.github.io/apm/consumer/installing-from-marketplaces/)** — install plugins from curated registries in one command, deployed across all targets and locked
|
|
147
|
+
- **[Pack & distribute](https://microsoft.github.io/apm/producer/pack-a-bundle/)** — `apm pack` bundles your configuration as a zipped package or a standalone plugin
|
|
148
148
|
- **[CI/CD ready](https://github.com/microsoft/apm-action)** — GitHub Action for automated workflows
|
|
149
149
|
|
|
150
150
|
### 2. Secure by default
|
|
@@ -152,10 +152,10 @@ One `apm.yml` describes every primitive your agents need — instructions, skill
|
|
|
152
152
|
Agent context is executable in effect — a prompt is a program for an LLM. APM treats it that way. Every install scans for hidden Unicode that can hijack agent behavior; the lockfile pins integrity hashes; transitive MCP servers are gated by trust prompts.
|
|
153
153
|
|
|
154
154
|
- **[Content security](https://microsoft.github.io/apm/enterprise/security/)** — `apm install` blocks compromised packages before agents read them; `apm audit` runs the same checks on demand
|
|
155
|
-
- **[Lockfile integrity](https://microsoft.github.io/apm/
|
|
155
|
+
- **[Lockfile integrity](https://microsoft.github.io/apm/reference/lockfile-spec/)** — `apm.lock` records resolved sources and content hashes for full provenance
|
|
156
156
|
- **[SBOM export](https://microsoft.github.io/apm/reference/cli/lock/)** — `apm lock export --format cyclonedx|spdx` emits a standard inventory of what reached disk, straight from the lockfile — provenance for procurement, not a compliance attestation
|
|
157
|
-
- **[Drift detection](https://microsoft.github.io/apm/
|
|
158
|
-
- **[MCP trust boundaries](https://microsoft.github.io/apm/
|
|
157
|
+
- **[Drift detection](https://microsoft.github.io/apm/enterprise/drift-detection/)** — `apm audit` rebuilds your agent context in scratch and diffs it against your working tree to catch hand-edits before they ship
|
|
158
|
+
- **[MCP trust boundaries](https://microsoft.github.io/apm/consumer/install-mcp-servers/)** — transitive MCP servers require explicit consent
|
|
159
159
|
|
|
160
160
|
### 3. Governed by policy
|
|
161
161
|
|
|
@@ -244,7 +244,7 @@ Or add an MCP server (wired into Copilot, Claude, Cursor, Codex, OpenCode, Gemin
|
|
|
244
244
|
apm install --mcp io.github.github/github-mcp-server --transport http # connects over HTTPS
|
|
245
245
|
```
|
|
246
246
|
|
|
247
|
-
See the **[Getting Started guide](https://microsoft.github.io/apm/
|
|
247
|
+
See the **[Getting Started guide](https://microsoft.github.io/apm/quickstart/)** for the full walkthrough.
|
|
248
248
|
|
|
249
249
|
## Works with agentrc
|
|
250
250
|
|
|
@@ -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/
|
|
9
|
+
**[Documentation](https://microsoft.github.io/apm/)** · **[Quick Start](https://microsoft.github.io/apm/quickstart/)** · **[CLI Reference](https://microsoft.github.io/apm/reference/)** · **[Roadmap](https://github.com/orgs/microsoft/projects/2304/views/5)**
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -68,11 +68,11 @@ One command, no configuration -- VS Code and GitHub Copilot read the file automa
|
|
|
68
68
|
One `apm.yml` describes every primitive your agents need — instructions, skills, prompts, agents, hooks, plugins, MCP servers — and `apm install` reproduces the exact same setup across every client on every machine. `apm.lock.yaml` pins the resolved tree the way `package-lock.json` does for npm.
|
|
69
69
|
|
|
70
70
|
- **[One manifest for everything](https://microsoft.github.io/apm/reference/primitive-types/)** -- declared once, deployed across Copilot, Claude, Grok Build, Cursor, OpenCode, Codex, Gemini, Windsurf, Kiro
|
|
71
|
-
- **[Install from anywhere](https://microsoft.github.io/apm/
|
|
72
|
-
- **[Transitive dependencies](https://microsoft.github.io/apm/
|
|
73
|
-
- **[Author plugins](https://microsoft.github.io/apm/
|
|
74
|
-
- **[Marketplaces](https://microsoft.github.io/apm/
|
|
75
|
-
- **[Pack & distribute](https://microsoft.github.io/apm/
|
|
71
|
+
- **[Install from anywhere](https://microsoft.github.io/apm/consumer/install-packages/)** — GitHub, GitLab, Bitbucket, Azure DevOps, GitHub Enterprise, Gitea, Gogs, any git host
|
|
72
|
+
- **[Transitive dependencies](https://microsoft.github.io/apm/consumer/install-packages/#transitive-dependencies-and-the-lockfile)** — packages can depend on packages; APM resolves the full tree
|
|
73
|
+
- **[Author plugins](https://microsoft.github.io/apm/producer/)** — build Copilot, Claude, and Cursor plugins with dependency management, then export standard `plugin.json`
|
|
74
|
+
- **[Marketplaces](https://microsoft.github.io/apm/consumer/installing-from-marketplaces/)** — install plugins from curated registries in one command, deployed across all targets and locked
|
|
75
|
+
- **[Pack & distribute](https://microsoft.github.io/apm/producer/pack-a-bundle/)** — `apm pack` bundles your configuration as a zipped package or a standalone plugin
|
|
76
76
|
- **[CI/CD ready](https://github.com/microsoft/apm-action)** — GitHub Action for automated workflows
|
|
77
77
|
|
|
78
78
|
### 2. Secure by default
|
|
@@ -80,10 +80,10 @@ One `apm.yml` describes every primitive your agents need — instructions, skill
|
|
|
80
80
|
Agent context is executable in effect — a prompt is a program for an LLM. APM treats it that way. Every install scans for hidden Unicode that can hijack agent behavior; the lockfile pins integrity hashes; transitive MCP servers are gated by trust prompts.
|
|
81
81
|
|
|
82
82
|
- **[Content security](https://microsoft.github.io/apm/enterprise/security/)** — `apm install` blocks compromised packages before agents read them; `apm audit` runs the same checks on demand
|
|
83
|
-
- **[Lockfile integrity](https://microsoft.github.io/apm/
|
|
83
|
+
- **[Lockfile integrity](https://microsoft.github.io/apm/reference/lockfile-spec/)** — `apm.lock` records resolved sources and content hashes for full provenance
|
|
84
84
|
- **[SBOM export](https://microsoft.github.io/apm/reference/cli/lock/)** — `apm lock export --format cyclonedx|spdx` emits a standard inventory of what reached disk, straight from the lockfile — provenance for procurement, not a compliance attestation
|
|
85
|
-
- **[Drift detection](https://microsoft.github.io/apm/
|
|
86
|
-
- **[MCP trust boundaries](https://microsoft.github.io/apm/
|
|
85
|
+
- **[Drift detection](https://microsoft.github.io/apm/enterprise/drift-detection/)** — `apm audit` rebuilds your agent context in scratch and diffs it against your working tree to catch hand-edits before they ship
|
|
86
|
+
- **[MCP trust boundaries](https://microsoft.github.io/apm/consumer/install-mcp-servers/)** — transitive MCP servers require explicit consent
|
|
87
87
|
|
|
88
88
|
### 3. Governed by policy
|
|
89
89
|
|
|
@@ -172,7 +172,7 @@ Or add an MCP server (wired into Copilot, Claude, Cursor, Codex, OpenCode, Gemin
|
|
|
172
172
|
apm install --mcp io.github.github/github-mcp-server --transport http # connects over HTTPS
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
-
See the **[Getting Started guide](https://microsoft.github.io/apm/
|
|
175
|
+
See the **[Getting Started guide](https://microsoft.github.io/apm/quickstart/)** for the full walkthrough.
|
|
176
176
|
|
|
177
177
|
## Works with agentrc
|
|
178
178
|
|
|
@@ -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.34.0"
|
|
8
8
|
description = "MCP configuration tool"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -205,12 +205,14 @@ markers = [
|
|
|
205
205
|
"slow: marks tests as slow running tests",
|
|
206
206
|
"benchmark: marks performance benchmark tests (deselected by default, run with -m benchmark)",
|
|
207
207
|
"windows_compat: load-bearing cross-platform regression contract family (CRLF-safe atomic writes, portable path formatting, git-executable resolution, socket/thread shutdown); runs on every OS and is additionally selected by the PR-time Windows Compatibility Gate -- NOT a requires_windows skip-gate, do not use requires_windows for this",
|
|
208
|
+
"trusted_executable: native trusted git/gh discovery and real consumer regressions; additionally selected on Windows Python 3.10 and 3.11",
|
|
208
209
|
"requires_e2e_mode: requires APM_E2E_TESTS=1",
|
|
209
210
|
"requires_github_token: requires GITHUB_APM_PAT or GITHUB_TOKEN",
|
|
210
211
|
"requires_ado_pat: requires ADO_APM_PAT",
|
|
211
212
|
"requires_ado_bearer: requires az CLI logged in + APM_TEST_ADO_BEARER=1",
|
|
212
213
|
"requires_network_integration: requires APM_RUN_INTEGRATION_TESTS=1",
|
|
213
214
|
"requires_windows: requires a Windows host",
|
|
215
|
+
"requires_windows_native_standard_user: requires the disposable Windows runner's verified non-admin token and symlink denial",
|
|
214
216
|
"requires_apm_binary: requires built apm binary on PATH (or APM_BINARY_PATH)",
|
|
215
217
|
"requires_runtime_codex: requires codex runtime installed",
|
|
216
218
|
"requires_runtime_copilot: requires GitHub Copilot CLI runtime installed",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Base adapter interface for MCP clients."""
|
|
2
2
|
|
|
3
|
+
import json
|
|
3
4
|
import os
|
|
4
5
|
import re
|
|
5
6
|
from abc import ABC, abstractmethod
|
|
@@ -8,7 +9,9 @@ from pathlib import Path
|
|
|
8
9
|
from typing import Any, ClassVar
|
|
9
10
|
|
|
10
11
|
from ...models.dependency.mcp import _EXTRA_DENYLIST, TrustedEnvLiteral
|
|
12
|
+
from ...utils.atomic_io import atomic_write_text
|
|
11
13
|
from ...utils.console import _rich_error, _rich_warning
|
|
14
|
+
from ...utils.path_security import has_symlink_component
|
|
12
15
|
|
|
13
16
|
_INPUT_VAR_RE = re.compile(r"\$\{input:([^}]+)\}")
|
|
14
17
|
|
|
@@ -396,6 +399,71 @@ class MCPClientAdapter(ABC):
|
|
|
396
399
|
"""Get the current MCP configuration."""
|
|
397
400
|
pass
|
|
398
401
|
|
|
402
|
+
def validate_config_for_install(self) -> bool:
|
|
403
|
+
"""Allow adapters to refuse unsafe configs before existing-server shortcuts."""
|
|
404
|
+
return True
|
|
405
|
+
|
|
406
|
+
def _read_json_config_for_update(self, config_path: Path) -> dict | None:
|
|
407
|
+
"""Return the JSON object at *config_path* before a merge-and-write.
|
|
408
|
+
|
|
409
|
+
A missing or blank file yields ``{}``. Returns ``None`` after a
|
|
410
|
+
warning when rewriting the file could lose data, so the caller skips
|
|
411
|
+
the write: the existing content is not a JSON object (for example
|
|
412
|
+
JSONC comments), or a user-scope path runs through a symlink, which
|
|
413
|
+
stale cleanup refuses to rewrite later.
|
|
414
|
+
"""
|
|
415
|
+
if self.user_scope and has_symlink_component(Path.home(), config_path):
|
|
416
|
+
_rich_warning(
|
|
417
|
+
f"Skipped {config_path}: APM does not write MCP config through "
|
|
418
|
+
"symlinks. Replace the symlink or configure this server manually.",
|
|
419
|
+
symbol="warning",
|
|
420
|
+
)
|
|
421
|
+
return None
|
|
422
|
+
try:
|
|
423
|
+
raw = config_path.read_text(encoding="utf-8")
|
|
424
|
+
except FileNotFoundError:
|
|
425
|
+
return {}
|
|
426
|
+
except (OSError, UnicodeError) as exc:
|
|
427
|
+
_rich_warning(
|
|
428
|
+
f"Could not read {config_path}: {exc} -- skipping config write; "
|
|
429
|
+
"fix the file's permissions or encoding, or add this server manually",
|
|
430
|
+
symbol="warning",
|
|
431
|
+
)
|
|
432
|
+
return None
|
|
433
|
+
if not raw.strip():
|
|
434
|
+
return {}
|
|
435
|
+
try:
|
|
436
|
+
config = json.loads(raw)
|
|
437
|
+
except json.JSONDecodeError:
|
|
438
|
+
config = None
|
|
439
|
+
if not isinstance(config, dict):
|
|
440
|
+
_rich_warning(
|
|
441
|
+
f"Could not parse {config_path} as a JSON object -- skipping config "
|
|
442
|
+
"write to avoid data loss (comments and trailing commas are not "
|
|
443
|
+
"preserved); fix the file or add this server manually",
|
|
444
|
+
symbol="warning",
|
|
445
|
+
)
|
|
446
|
+
return None
|
|
447
|
+
if self.mcp_servers_key in config and not isinstance(config[self.mcp_servers_key], dict):
|
|
448
|
+
_rich_warning(
|
|
449
|
+
f"Could not parse {config_path}: {self.mcp_servers_key} must be "
|
|
450
|
+
"a JSON object -- skipping config write to avoid data loss; "
|
|
451
|
+
"fix the file or add this server manually",
|
|
452
|
+
symbol="warning",
|
|
453
|
+
)
|
|
454
|
+
return None
|
|
455
|
+
return config
|
|
456
|
+
|
|
457
|
+
@staticmethod
|
|
458
|
+
def _write_json_config(config_path: Path, config: dict) -> None:
|
|
459
|
+
"""Atomically write *config* as JSON and keep the file owner-only.
|
|
460
|
+
|
|
461
|
+
Entries can carry env values resolved at install time.
|
|
462
|
+
"""
|
|
463
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
464
|
+
atomic_write_text(config_path, json.dumps(config, indent=2), new_file_mode=0o600)
|
|
465
|
+
os.chmod(config_path, 0o600)
|
|
466
|
+
|
|
399
467
|
@abstractmethod
|
|
400
468
|
def configure_mcp_server(
|
|
401
469
|
self,
|
|
@@ -1424,7 +1492,7 @@ class MCPClientAdapter(ABC):
|
|
|
1424
1492
|
|
|
1425
1493
|
Args:
|
|
1426
1494
|
config: Mutable config dict updated in place.
|
|
1427
|
-
remote: Registry remote entry (may
|
|
1495
|
+
remote: Registry remote entry (headers may be records or a mapping).
|
|
1428
1496
|
server_info: Registry server metadata used for name / URL lookup.
|
|
1429
1497
|
env_overrides: Caller-supplied env-var override mapping.
|
|
1430
1498
|
runtime_label: Label for diagnostic messages.
|
|
@@ -1432,18 +1500,38 @@ class MCPClientAdapter(ABC):
|
|
|
1432
1500
|
instantiate. Passed by the caller so tests can patch the right
|
|
1433
1501
|
module-level name.
|
|
1434
1502
|
"""
|
|
1503
|
+
from ...core.auth import AuthResolver
|
|
1504
|
+
from ...models.dependency.mcp import ManifestHeaderValue
|
|
1505
|
+
|
|
1435
1506
|
server_name = server_info.get("name", "")
|
|
1436
1507
|
is_github_server = self._is_github_server(server_name, remote.get("url", ""))
|
|
1437
1508
|
local_token_injected = False
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1509
|
+
headers = remote.get("headers", []) or []
|
|
1510
|
+
if isinstance(headers, dict):
|
|
1511
|
+
headers = [{"name": name, "value": value} for name, value in headers.items()]
|
|
1512
|
+
explicit_authorization = any(
|
|
1513
|
+
isinstance(header, dict)
|
|
1514
|
+
and isinstance(header.get("name"), str)
|
|
1515
|
+
and header["name"].casefold() == "authorization"
|
|
1516
|
+
and isinstance(header.get("value"), ManifestHeaderValue)
|
|
1517
|
+
and bool(header.get("value"))
|
|
1518
|
+
for header in headers
|
|
1519
|
+
)
|
|
1520
|
+
if is_github_server and not explicit_authorization:
|
|
1521
|
+
resolver = AuthResolver(
|
|
1522
|
+
token_manager=token_manager_class(), allow_external_fallback=False
|
|
1442
1523
|
)
|
|
1443
|
-
|
|
1444
|
-
|
|
1524
|
+
selected = resolver.resolve_github_mcp_token(
|
|
1525
|
+
source_only=self._supports_runtime_env_substitution
|
|
1526
|
+
)
|
|
1527
|
+
if selected:
|
|
1528
|
+
credential = (
|
|
1529
|
+
self._format_runtime_env_placeholder(selected)
|
|
1530
|
+
if self._supports_runtime_env_substitution
|
|
1531
|
+
else selected
|
|
1532
|
+
)
|
|
1533
|
+
config.setdefault("headers", {})["Authorization"] = f"Bearer {credential}"
|
|
1445
1534
|
local_token_injected = True
|
|
1446
|
-
headers = remote.get("headers", [])
|
|
1447
1535
|
if headers:
|
|
1448
1536
|
if "headers" not in config:
|
|
1449
1537
|
config["headers"] = {}
|
|
@@ -1451,8 +1539,15 @@ class MCPClientAdapter(ABC):
|
|
|
1451
1539
|
header_name = header.get("name", "")
|
|
1452
1540
|
header_value = header.get("value", "")
|
|
1453
1541
|
if header_name and header_value:
|
|
1454
|
-
if header_name == "
|
|
1455
|
-
|
|
1542
|
+
if header_name.casefold() == "authorization":
|
|
1543
|
+
if local_token_injected or (
|
|
1544
|
+
explicit_authorization
|
|
1545
|
+
and not isinstance(header_value, ManifestHeaderValue)
|
|
1546
|
+
):
|
|
1547
|
+
continue
|
|
1548
|
+
for key in list(config["headers"]):
|
|
1549
|
+
if key.casefold() == "authorization":
|
|
1550
|
+
del config["headers"][key]
|
|
1456
1551
|
resolved_value = self._resolve_env_variable(
|
|
1457
1552
|
header_name, header_value, env_overrides
|
|
1458
1553
|
)
|
|
@@ -63,6 +63,14 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
63
63
|
_CONVERGED_SKILL_PREFIX = ".agents/skills/"
|
|
64
64
|
_CLAUDE_SKILL_PREFIX = ".claude/skills/"
|
|
65
65
|
|
|
66
|
+
# Entry ``type`` values Claude Code uses for URL-addressed servers.
|
|
67
|
+
_REMOTE_TYPES = ("http", "sse", "streamable-http")
|
|
68
|
+
|
|
69
|
+
# Transport fields are replaced across families; a partial update can
|
|
70
|
+
# retain an omitted type only when it still belongs to the selected family.
|
|
71
|
+
_REMOTE_TRANSPORT_KEYS = frozenset({"type", "url", "headers"})
|
|
72
|
+
_STDIO_TRANSPORT_KEYS = frozenset({"type", "command", "args", "env", "cwd"})
|
|
73
|
+
|
|
66
74
|
@classmethod
|
|
67
75
|
def _rewrite_self_defined_skill_command(cls, command: str) -> str:
|
|
68
76
|
if isinstance(command, str) and command.startswith(cls._CONVERGED_SKILL_PREFIX):
|
|
@@ -75,8 +83,13 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
75
83
|
config["command"] = self._rewrite_self_defined_skill_command(config["command"])
|
|
76
84
|
return config
|
|
77
85
|
|
|
78
|
-
@
|
|
79
|
-
def
|
|
86
|
+
@classmethod
|
|
87
|
+
def _is_remote_mcp_entry(cls, entry: dict) -> bool:
|
|
88
|
+
"""Return whether *entry* describes a remote (URL-addressed) server."""
|
|
89
|
+
return bool(entry.get("url")) or entry.get("type") in cls._REMOTE_TYPES
|
|
90
|
+
|
|
91
|
+
@classmethod
|
|
92
|
+
def _normalize_mcp_entry_for_claude_code(cls, entry: dict) -> dict:
|
|
80
93
|
"""Normalize a server entry to Claude Code's on-disk shape.
|
|
81
94
|
|
|
82
95
|
For remote servers, keep ``type``/``url``/``headers`` per Claude
|
|
@@ -91,11 +104,8 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
91
104
|
if not isinstance(entry, dict):
|
|
92
105
|
return entry
|
|
93
106
|
out = dict(entry)
|
|
94
|
-
url = out.get("url")
|
|
95
|
-
t = out.get("type")
|
|
96
|
-
is_remote = bool(url) or t in ("http", "sse", "streamable-http")
|
|
97
107
|
|
|
98
|
-
if
|
|
108
|
+
if cls._is_remote_mcp_entry(out):
|
|
99
109
|
if out.get("id") in ("", None):
|
|
100
110
|
out.pop("id", None)
|
|
101
111
|
if out.get("tools") == ["*"]:
|
|
@@ -110,14 +120,43 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
110
120
|
out.pop("id", None)
|
|
111
121
|
return out
|
|
112
122
|
|
|
113
|
-
@
|
|
114
|
-
def
|
|
123
|
+
@classmethod
|
|
124
|
+
def _retained_previous_entry(cls, prev: dict, new_cfg: dict) -> dict:
|
|
125
|
+
"""Return *prev* without the keys of the transport *new_cfg* is not.
|
|
126
|
+
|
|
127
|
+
A redeclaration that switches transport must not leave the previous
|
|
128
|
+
transport's keys behind. A surviving ``url`` keeps the entry
|
|
129
|
+
classified as remote, so the stdio shape never wins and a stale
|
|
130
|
+
``Authorization`` header stays in the Claude Code config.
|
|
131
|
+
|
|
132
|
+
The keys are selected from the update rather than from a comparison
|
|
133
|
+
of the two entries, so an entry already carrying both transports --
|
|
134
|
+
written by a release that merged them unconditionally -- is repaired
|
|
135
|
+
by the next install that writes it instead of matching its own mixed shape and
|
|
136
|
+
surviving. Keys APM does not manage (hand-authored OAuth blocks and
|
|
137
|
+
the like) describe no transport and are retained either way.
|
|
138
|
+
"""
|
|
139
|
+
declares_transport = any(new_cfg.get(key) for key in ("type", "url", "command"))
|
|
140
|
+
is_remote = cls._is_remote_mcp_entry(new_cfg if declares_transport else prev)
|
|
141
|
+
stale = cls._STDIO_TRANSPORT_KEYS if is_remote else cls._REMOTE_TRANSPORT_KEYS
|
|
142
|
+
compatible_types = cls._REMOTE_TYPES if is_remote else ("local", "stdio")
|
|
143
|
+
# Keep a compatible type in place so repeated writes retain field order.
|
|
144
|
+
return {
|
|
145
|
+
key: value
|
|
146
|
+
for key, value in prev.items()
|
|
147
|
+
if key not in stale or (key == "type" and value in compatible_types)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@classmethod
|
|
151
|
+
def _merge_mcp_server_dicts(cls, existing_servers: dict, config_updates: dict) -> None:
|
|
115
152
|
"""Merge *config_updates* into *existing_servers* in place.
|
|
116
153
|
|
|
117
154
|
Per-server entries are shallow-merged: ``{**old, **new}`` so keys present
|
|
118
|
-
only on plugin- or hand-authored configs (e.g.
|
|
155
|
+
only on plugin- or hand-authored configs (e.g. OAuth blocks)
|
|
119
156
|
survive when an update omits them. Keys in *new* overwrite *old* on
|
|
120
157
|
conflict so APM/registry installs still refresh ``command``/``args``/etc.
|
|
158
|
+
The previous entry first drops the keys of the transport the update
|
|
159
|
+
does not declare, so the merged entry describes exactly one.
|
|
121
160
|
"""
|
|
122
161
|
for name, new_cfg in config_updates.items():
|
|
123
162
|
if not isinstance(new_cfg, dict):
|
|
@@ -125,7 +164,7 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
125
164
|
continue
|
|
126
165
|
prev = existing_servers.get(name)
|
|
127
166
|
if isinstance(prev, dict):
|
|
128
|
-
merged = {**prev, **new_cfg}
|
|
167
|
+
merged = {**cls._retained_previous_entry(prev, new_cfg), **new_cfg}
|
|
129
168
|
existing_servers[name] = merged
|
|
130
169
|
else:
|
|
131
170
|
existing_servers[name] = dict(new_cfg)
|
|
@@ -145,7 +184,12 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
145
184
|
def _project_mcp_path(self) -> Path:
|
|
146
185
|
return self.project_root / ".mcp.json"
|
|
147
186
|
|
|
148
|
-
|
|
187
|
+
@classmethod
|
|
188
|
+
def resolve_user_claude_unresolved_path(cls) -> Path:
|
|
189
|
+
"""Return the un-normalized path for user-scope Claude Code config.
|
|
190
|
+
|
|
191
|
+
Used for symlink pre-checks before canonical resolution.
|
|
192
|
+
"""
|
|
149
193
|
config_dir = os.environ.get("CLAUDE_CONFIG_DIR", "").strip()
|
|
150
194
|
if config_dir:
|
|
151
195
|
config_path = Path(config_dir).expanduser()
|
|
@@ -154,9 +198,22 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
154
198
|
"CLAUDE_CONFIG_DIR must be an absolute path for user-scope MCP "
|
|
155
199
|
"config; set an absolute path or unset it to use ~/.claude.json."
|
|
156
200
|
)
|
|
157
|
-
return config_path
|
|
201
|
+
return config_path / ".claude.json"
|
|
158
202
|
return Path.home() / ".claude.json"
|
|
159
203
|
|
|
204
|
+
@classmethod
|
|
205
|
+
def resolve_user_claude_json_path(cls, unresolved_path: Path | None = None) -> Path:
|
|
206
|
+
"""Resolve the selected destination, optionally reusing a checked path."""
|
|
207
|
+
path = (
|
|
208
|
+
unresolved_path
|
|
209
|
+
if unresolved_path is not None
|
|
210
|
+
else cls.resolve_user_claude_unresolved_path()
|
|
211
|
+
)
|
|
212
|
+
return path.parent.resolve(strict=False) / path.name
|
|
213
|
+
|
|
214
|
+
def _user_claude_json_path(self) -> Path:
|
|
215
|
+
return self.resolve_user_claude_json_path()
|
|
216
|
+
|
|
160
217
|
def _should_write_project(self) -> bool:
|
|
161
218
|
return (self.project_root / ".claude").is_dir()
|
|
162
219
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
import os
|
|
5
|
+
import re
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
from urllib.parse import urlparse
|
|
7
8
|
|
|
@@ -15,10 +16,34 @@ from ...utils.console import _rich_success, _rich_warning
|
|
|
15
16
|
from ...utils.net import is_loopback_host
|
|
16
17
|
from ...utils.path_security import PathTraversalError
|
|
17
18
|
from ._mcp_runtime_args import process_v01_value_hint_arg
|
|
18
|
-
from .base import MCPClientAdapter
|
|
19
|
+
from .base import _ENV_VAR_RE, MCPClientAdapter
|
|
19
20
|
|
|
20
21
|
_log = logging.getLogger(__name__)
|
|
21
22
|
|
|
23
|
+
# Codex documents ``http_headers`` as a map of header names to STATIC values,
|
|
24
|
+
# so a ``${VAR}`` written there reaches the server as that literal text. An
|
|
25
|
+
# environment-sourced header has two dedicated fields instead:
|
|
26
|
+
# ``env_http_headers`` maps a header name to the variable holding its whole
|
|
27
|
+
# value, and ``bearer_token_env_var`` names the variable holding an
|
|
28
|
+
# Authorization bearer token. Codex resolves both at server start, which is
|
|
29
|
+
# what the declared ``${VAR}`` asks for -- this adapter does not support
|
|
30
|
+
# runtime substitution itself, so the placeholder survives
|
|
31
|
+
# ``_resolve_variable_placeholders`` untouched.
|
|
32
|
+
# See https://learn.chatgpt.com/docs/extend/mcp?surface=cli
|
|
33
|
+
_CODEX_BEARER_HEADER = "authorization"
|
|
34
|
+
# Reuse the canonical placeholder syntax so the two spellings APM accepts
|
|
35
|
+
# (``${VAR}`` and ``${env:VAR}``) cannot drift apart here. The auth scheme is
|
|
36
|
+
# case-insensitive per RFC 7235; Codex always writes it as ``Bearer``.
|
|
37
|
+
_CODEX_BEARER_VALUE_RE = re.compile(rf"(?i:Bearer) +{_ENV_VAR_RE.pattern}")
|
|
38
|
+
# Any reference still standing in a resolved value, deliberately wider than the
|
|
39
|
+
# canonical parser: a spelling it does not model, such as the shell default in
|
|
40
|
+
# ``${VAR:-}``, is no more static than a ``${VAR}`` Codex could resolve, and
|
|
41
|
+
# writing it to ``http_headers`` sends the braces to the server. Widening the
|
|
42
|
+
# report here, rather than the parser, keeps every other adapter's placeholder
|
|
43
|
+
# semantics untouched. ``${input:...}`` is excluded: input variables are
|
|
44
|
+
# collected elsewhere and carry their own warning.
|
|
45
|
+
_CODEX_UNSUPPORTED_REFERENCE_RE = re.compile(r"\$\{(?!input:)")
|
|
46
|
+
|
|
22
47
|
|
|
23
48
|
class CodexClientAdapter(MCPClientAdapter):
|
|
24
49
|
"""Codex CLI implementation of MCP client adapter.
|
|
@@ -293,16 +318,49 @@ class CodexClientAdapter(MCPClientAdapter):
|
|
|
293
318
|
"id": server_info.get("id", ""),
|
|
294
319
|
}
|
|
295
320
|
http_headers: dict[str, str] = {}
|
|
321
|
+
env_http_headers: dict[str, str] = {}
|
|
322
|
+
bearer_token_env_var = ""
|
|
323
|
+
unsupported_headers: list[str] = []
|
|
296
324
|
for header in remote.get("headers", []):
|
|
297
325
|
h_name = header.get("name", "")
|
|
298
326
|
h_value = header.get("value", "")
|
|
299
|
-
if h_name and h_value:
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
327
|
+
if not (h_name and h_value):
|
|
328
|
+
continue
|
|
329
|
+
resolved = self._resolve_variable_placeholders(
|
|
330
|
+
h_value, env_overrides or {}, runtime_vars or {}
|
|
331
|
+
)
|
|
332
|
+
bearer = _CODEX_BEARER_VALUE_RE.fullmatch(resolved)
|
|
333
|
+
if bearer and h_name.lower() == _CODEX_BEARER_HEADER:
|
|
334
|
+
bearer_token_env_var = bearer.group(1)
|
|
335
|
+
continue
|
|
336
|
+
env_header = _ENV_VAR_RE.fullmatch(resolved)
|
|
337
|
+
if env_header:
|
|
338
|
+
env_http_headers[h_name] = env_header.group(1)
|
|
339
|
+
continue
|
|
340
|
+
if _CODEX_UNSUPPORTED_REFERENCE_RE.search(resolved):
|
|
341
|
+
unsupported_headers.append(h_name)
|
|
342
|
+
continue
|
|
343
|
+
http_headers[h_name] = resolved
|
|
344
|
+
if unsupported_headers:
|
|
345
|
+
safe_headers = ", ".join(ascii(name)[1:-1] for name in unsupported_headers)
|
|
346
|
+
safe_server = ascii(server_name)[1:-1]
|
|
347
|
+
_rich_warning(
|
|
348
|
+
f"Skipping header(s) {safe_headers} of MCP server "
|
|
349
|
+
f"'{safe_server}' for Codex CLI: Codex reads a header from the "
|
|
350
|
+
"environment only when the value is exactly ${VAR} or, for "
|
|
351
|
+
"Authorization, `Bearer ${VAR}`. Literal text around the "
|
|
352
|
+
"reference, or a shell-style default such as ${VAR:-}, has no "
|
|
353
|
+
"Codex equivalent; export the whole header value as one variable.",
|
|
354
|
+
symbol="warning",
|
|
355
|
+
)
|
|
356
|
+
# Scalars precede the sub-tables tomlkit renders for the dict values.
|
|
357
|
+
if bearer_token_env_var:
|
|
358
|
+
remote_config["bearer_token_env_var"] = bearer_token_env_var
|
|
303
359
|
if http_headers:
|
|
304
360
|
remote_config["http_headers"] = http_headers
|
|
305
361
|
self._warn_input_variables(http_headers, server_name, "Codex CLI")
|
|
362
|
+
if env_http_headers:
|
|
363
|
+
remote_config["env_http_headers"] = env_http_headers
|
|
306
364
|
self._merge_extra(remote_config, server_info)
|
|
307
365
|
return remote_config
|
|
308
366
|
|
|
@@ -55,11 +55,12 @@ class CopilotClientAdapter(MCPClientAdapter):
|
|
|
55
55
|
# environment and the literal value is baked into the config file
|
|
56
56
|
# (legacy pre-#1152 behaviour).
|
|
57
57
|
#
|
|
58
|
-
# Subclasses (
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
# resolving at install
|
|
58
|
+
# Subclasses (Windsurf / OpenCode / Claude / Gemini) override this to
|
|
59
|
+
# ``False`` until their respective config formats are individually audited
|
|
60
|
+
# for runtime-substitution support. Cursor has audited native
|
|
61
|
+
# ``${env:VAR}`` support. Critically, Claude Desktop's config format does
|
|
62
|
+
# NOT support runtime substitution -- it MUST keep resolving at install
|
|
63
|
+
# time.
|
|
63
64
|
_supports_runtime_env_substitution: bool = True
|
|
64
65
|
|
|
65
66
|
# Process-wide aggregation of legacy ``<VAR>`` offenders, keyed by
|