apm-cli 0.33.0__tar.gz → 0.35.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.33.0/src/apm_cli.egg-info → apm_cli-0.35.0}/PKG-INFO +14 -12
- {apm_cli-0.33.0 → apm_cli-0.35.0}/README.md +13 -11
- {apm_cli-0.33.0 → apm_cli-0.35.0}/pyproject.toml +3 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/base.py +114 -3
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/claude.py +94 -12
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/codex.py +132 -12
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/cursor.py +46 -41
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/opencode.py +91 -22
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/lockfile_enrichment.py +22 -19
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/plugin_exporter.py +78 -15
- apm_cli-0.35.0/src/apm_cli/bundle/plugin_hooks.py +236 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cli.py +19 -3
- apm_cli-0.35.0/src/apm_cli/codex_plugins/__init__.py +1 -0
- apm_cli-0.35.0/src/apm_cli/codex_plugins/admission.py +138 -0
- apm_cli-0.35.0/src/apm_cli/codex_plugins/client.py +270 -0
- apm_cli-0.35.0/src/apm_cli/codex_plugins/manifest.py +84 -0
- apm_cli-0.35.0/src/apm_cli/codex_plugins/registrar.py +561 -0
- apm_cli-0.35.0/src/apm_cli/codex_plugins/snapshot.py +190 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/_helpers.py +33 -49
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/audit.py +71 -5
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/compile/cli.py +3 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/deps/cli.py +26 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/deps/why.py +8 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/install.py +64 -77
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/lock.py +5 -5
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/outdated.py +45 -8
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/prune.py +5 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/targets.py +31 -16
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/uninstall/cli.py +42 -13
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/uninstall/engine.py +110 -94
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/uninstall/lockfile_state.py +11 -3
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/update.py +3 -3
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/agents_compiler.py +74 -57
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/build_id.py +24 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/root_context_protection.py +66 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/auth.py +109 -10
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/command_logger.py +28 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/conflict_detector.py +8 -5
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/deployment_ledger.py +582 -23
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/deployment_state.py +124 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/operations.py +4 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/safe_installer.py +8 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/script_executors.py +10 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/target_catalog.py +69 -55
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/target_detection.py +64 -22
- apm_cli-0.35.0/src/apm_cli/core/tls_trust.py +625 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/apm_resolver.py +152 -9
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/bare_cache.py +12 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/git_reference_resolver.py +3 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/git_remote_ops.py +66 -38
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/github_downloader.py +15 -74
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/github_downloader_validation.py +20 -7
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/immutable_requirements.py +17 -4
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/installed_package.py +19 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/lockfile.py +314 -11
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/package_validator.py +3 -3
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/path_anchoring.py +16 -3
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/reachability.py +40 -5
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/revision_pins.py +3 -1
- apm_cli-0.35.0/src/apm_cli/deps/virtual_file.py +73 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/why_walker.py +39 -88
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/drift.py +94 -10
- apm_cli-0.35.0/src/apm_cli/entrypoint.py +34 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/hook_contract.py +9 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/audit_replay.py +19 -11
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/audit_target_roots.py +52 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/context.py +9 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/deployable_source_plan.py +103 -26
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/deployed_paths.py +42 -0
- apm_cli-0.35.0/src/apm_cli/install/deployment_plan.py +114 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/drift.py +242 -260
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/drift_render.py +68 -4
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/dry_run_plan.py +117 -5
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/errors.py +56 -6
- apm_cli-0.35.0/src/apm_cli/install/helpers/absence_observation.py +56 -0
- apm_cli-0.35.0/src/apm_cli/install/helpers/no_work.py +122 -0
- apm_cli-0.35.0/src/apm_cli/install/helpers/plan_inputs.py +28 -0
- apm_cli-0.35.0/src/apm_cli/install/helpers/reconciliation_scope.py +92 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/helpers/ref_reuse.py +2 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/helpers/ref_seed.py +9 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/lsp/integration.py +112 -63
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/manifest_reconcile.py +203 -140
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/command.py +87 -18
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/integration.py +206 -72
- apm_cli-0.35.0/src/apm_cli/install/mcp/ownership.py +278 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/native_plugin_admission.py +45 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/outcome.py +4 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/package_resolution.py +62 -13
- apm_cli-0.35.0/src/apm_cli/install/package_selection.py +108 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/cleanup.py +40 -7
- apm_cli-0.35.0/src/apm_cli/install/phases/codex_plugins.py +49 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/integrate.py +66 -15
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/local_content.py +134 -27
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/lockfile.py +100 -7
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/post_deps_local.py +10 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/resolve.py +64 -84
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/targets.py +5 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/pipeline.py +69 -77
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/plan.py +64 -13
- apm_cli-0.35.0/src/apm_cli/install/presentation/__init__.py +27 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/presentation/dry_run.py +27 -8
- apm_cli-0.35.0/src/apm_cli/install/presentation/resolution.py +48 -0
- apm_cli-0.35.0/src/apm_cli/install/project_package.py +26 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/resolution_staging.py +120 -38
- apm_cli-0.35.0/src/apm_cli/install/service.py +702 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/service_integration.py +79 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/services.py +99 -119
- apm_cli-0.35.0/src/apm_cli/install/source_helpers.py +122 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/sources.py +56 -11
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/target_filter.py +105 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/template.py +100 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/transaction.py +63 -22
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/validation.py +44 -44
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/agent_integrator.py +156 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/base_integrator.py +128 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/cleanup.py +29 -11
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_bundle.py +3 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_command_paths.py +33 -2
- apm_cli-0.35.0/src/apm_cli/integration/hook_cursor_preflight.py +249 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_integrator.py +96 -81
- apm_cli-0.35.0/src/apm_cli/integration/hook_native_formats.py +481 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_ownership.py +32 -9
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_source_selection.py +25 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/mcp_config_view.py +327 -52
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/mcp_integrator.py +112 -25
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/mcp_integrator_install.py +304 -46
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/prompt_integrator.py +107 -20
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/skill_integrator.py +402 -401
- apm_cli-0.35.0/src/apm_cli/integration/skill_preflight.py +198 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/skill_support.py +16 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/targets.py +377 -248
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/builder.py +104 -43
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/client.py +56 -16
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/output_mappers.py +135 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/output_profiles.py +9 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/ref_resolver.py +23 -6
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/resolver.py +43 -6
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/yml_schema.py +42 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/apm_package.py +153 -2
- apm_cli-0.35.0/src/apm_cli/models/dependency/__init__.py +51 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/materialization.py +22 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/reference.py +26 -6
- apm_cli-0.35.0/src/apm_cli/models/dependency/replacement.py +674 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/format_detection.py +2 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/manifest_contract.py +15 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/results.py +2 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/validation.py +78 -12
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/ci_checks.py +94 -33
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/discovery.py +29 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/primitives/models.py +32 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/primitives/parser.py +9 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/registry/operations.py +29 -7
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/manager.py +11 -3
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/options.py +89 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/skillspector.py +17 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/file_scanner.py +5 -7
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/atomic_io.py +11 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/content_hash.py +37 -19
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/file_ops.py +13 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/git_env.py +22 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/github_host.py +48 -13
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/helpers.py +6 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/yaml_io.py +10 -7
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/version.py +38 -6
- apm_cli-0.35.0/src/apm_cli/version_output.py +57 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0/src/apm_cli.egg-info}/PKG-INFO +14 -12
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli.egg-info/SOURCES.txt +20 -0
- apm_cli-0.35.0/src/apm_cli.egg-info/entry_points.txt +2 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_apm_package_models.py +11 -7
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_distributed_compilation.py +2 -1
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_empty_string_and_defaults.py +68 -12
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_github_downloader.py +20 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_lockfile.py +34 -9
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_token_manager.py +1 -1
- apm_cli-0.33.0/src/apm_cli/core/tls_trust.py +0 -343
- apm_cli-0.33.0/src/apm_cli/install/helpers/no_work.py +0 -34
- apm_cli-0.33.0/src/apm_cli/install/mcp/ownership.py +0 -110
- apm_cli-0.33.0/src/apm_cli/install/package_selection.py +0 -45
- apm_cli-0.33.0/src/apm_cli/install/presentation/__init__.py +0 -1
- apm_cli-0.33.0/src/apm_cli/install/service.py +0 -353
- apm_cli-0.33.0/src/apm_cli/install/source_helpers.py +0 -56
- apm_cli-0.33.0/src/apm_cli/integration/hook_native_formats.py +0 -261
- apm_cli-0.33.0/src/apm_cli/models/dependency/__init__.py +0 -23
- apm_cli-0.33.0/src/apm_cli.egg-info/entry_points.txt +0 -2
- {apm_cli-0.33.0 → apm_cli-0.35.0}/AUTHORS +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/LICENSE +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/NOTICE +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/setup.cfg +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/antigravity.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/copilot.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/gemini.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/hermes.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/intellij.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/kiro.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/vscode.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/windsurf.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/package_manager/base.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/discovery.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/manifest_edit.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/materialize.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/render.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/safety.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/assets.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/constants.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/errors.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/io.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/ir.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/loader.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/projection.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/validation.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bootstrap_mirror.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/agent_plugin_exporter.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/attest.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/claude_plugin_exporter.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/export_common.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/formats.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/local_bundle.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/packer.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/plugin_layout.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/reproducible_archive.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/unpacker.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/cleanup.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/git_cache.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/http_cache.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/integrity.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/locking.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/paths.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/url_normalize.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/_apm_yml_writer.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/approve.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/auth.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/cache.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/compile/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/compile/watcher.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/config.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/deps/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/deps/_utils.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/discover.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/doctor.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/experimental.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/find.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/init.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/lifecycle.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/list_cmd.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/audit.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/check.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/doctor.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/init.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/migrate.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/outdated.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/plugin/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/plugin/add.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/plugin/remove.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/validate.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/mcp.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/pack.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/plugin/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/plugin/init.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/policy.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/publish.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/run.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/runtime.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/self_update.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/uninstall/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/view.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/claude_formatter.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/constants.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/constitution.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/constitution_block.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/context_optimizer.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/distributed_compiler.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/footer.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/gemini_formatter.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/injector.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/inventory.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/link_resolver.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/managed_section.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/output_writer.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/template_builder.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/user_root_context.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/config.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/constants.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/capability.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/catalog.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/constants.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/registrar.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/settings.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/_child_tls/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/_child_tls/_apm_tls.pth +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/_child_tls/_apm_tls_bootstrap.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/apm_yml.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/azure_cli.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/build_orchestrator.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/docker_args.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/errors.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/experimental.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/host_providers.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/install_audit.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/lifecycle_scripts.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/null_logger.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/output_mode.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/plugin_manifest.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/project_name.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/scope.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/script_runner.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/script_trust.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/token_manager.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/_shared.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/aggregator.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/artifactory_entry.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/clone_engine.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/dependency_graph.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/download_strategies.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/git_auth_env.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/git_file_transport.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/git_semver_resolver.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/github_rate_limit.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/host_backends.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/outdated_ref_cache.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/outdated_row.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/plugin_parser.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/auth.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/client.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/config_loader.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/extractor.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/feature_gate.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/outdated.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/resolver.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/semver.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry_proxy.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/shared_clone_cache.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/tiered_ref_resolver.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/transport_selection.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/verifier.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/authoring.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/declared_license.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/formats.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/purl.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/sbom.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/spdx.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/spdx_data.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/factory.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/argv.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/artifactory_resolver.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/cache_pin.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/exec_gate.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/finalization.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/gitlab_resolver.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/heals/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/heals/base.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/helpers/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/helpers/security_scan.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/insecure_policy.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/integrity.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/legacy_plugin_compat.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/local_bundle_handler.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/local_bundle_paths.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/locking.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/lsp/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/manifest_helpers.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/args.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/conflicts.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/entry.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/registry.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/warnings.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/writer.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/_redownload.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/_skip_logic.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/audit.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/copilot_plugins.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/download.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/finalize.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/heal.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/policy_gate.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/policy_target_check.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/primitive_classification.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/registry_wiring.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/request.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/root_redirect.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/skill_path_migration.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/summary.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/target_hints.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/target_warnings.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/_hook_dropped_targets.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/_shared.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/canvas_integrator.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/command_integrator.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/copilot_app_db.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/copilot_app_project.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/copilot_app_workflow_integrator.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/copilot_app_ws.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/coverage.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/dispatch.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_command_warnings.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_file_routing.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_ir.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_reintegration.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/instruction_integrator.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/kiro_hook_integrator.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/lsp_integrator.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/skill_package_routing.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/skill_transformer.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/utils.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/_git_utils.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/_io.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/_shared.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/audit.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/auth_helpers.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/diagnostics.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/drift_check.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/errors.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/git_stderr.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/init_template.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/migration.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/models.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/registry.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/semver.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/shadow_detector.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/source_identity.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/tag_pattern.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/validator.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/version_check.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/version_pins.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/version_resolver.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/yml_editor.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/host_virtual.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/identity.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/lsp.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/mcp.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/object_fields.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/provider_coordinates.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/registry_entry.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/selection.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/subsets.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/types.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/plugin.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/output/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/output/formatters.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/output/models.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/output/script_formatters.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/_constraint_pinning.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/_gitlab.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/_help_text.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/_shared.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/inheritance.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/install_preflight.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/matcher.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/models.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/outcome_routing.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/parser.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/policy_checks.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/project_config.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/schema.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/primitives/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/primitives/discovery.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/registry/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/registry/client.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/registry/integration.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/base.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/codex_runtime.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/copilot_runtime.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/factory.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/llm_runtime.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/registry.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/utils.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/audit_report.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/content_scanner.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/executables.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/base.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/gate.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/generic_sarif.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/registry.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/runner.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/sarif_ingest.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/gate.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/primitive_discovery.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/update_policy.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/archive.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/console.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/diagnostics.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/exclude.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/git_sparse.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/guards.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/install_tui.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/net.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/normalization.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/path_security.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/paths.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/patterns.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/perf_stats.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/reflink.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/short_sha.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/staging_guard.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/subprocess_env.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/version_checker.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/workflow/__init__.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/workflow/discovery.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/workflow/parser.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/workflow/runner.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli.egg-info/dependency_links.txt +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli.egg-info/requires.txt +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli.egg-info/top_level.txt +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_apm_resolver.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_codex_docker_args_fix.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_codex_empty_string_and_defaults.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_collision_integration.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_console.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_enhanced_discovery.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_github_downloader_token_precedence.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_gitlab_git_transport.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_runnable_prompts.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_runtime_manager_token_precedence.py +0 -0
- {apm_cli-0.33.0 → apm_cli-0.35.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.35.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
|
|
|
@@ -95,6 +95,8 @@ AI coding agents need context to be useful — standards, prompts, skills, plugi
|
|
|
95
95
|
# apm.yml — ships with your project
|
|
96
96
|
name: your-project
|
|
97
97
|
version: 1.0.0
|
|
98
|
+
targets:
|
|
99
|
+
- copilot # choose the harness(es) this project supports
|
|
98
100
|
dependencies:
|
|
99
101
|
apm:
|
|
100
102
|
# Skills from any repository
|
|
@@ -106,7 +108,7 @@ dependencies:
|
|
|
106
108
|
# A full APM package with instructions, skills, prompts, hooks...
|
|
107
109
|
- microsoft/apm-sample-package#v1.0.0
|
|
108
110
|
mcp:
|
|
109
|
-
# MCP servers -- installed into every
|
|
111
|
+
# MCP servers -- installed into every selected target
|
|
110
112
|
- name: io.github.github/github-mcp-server
|
|
111
113
|
transport: http # MCP transport name, not URL scheme -- connects over HTTPS
|
|
112
114
|
```
|
|
@@ -140,11 +142,11 @@ One command, no configuration -- VS Code and GitHub Copilot read the file automa
|
|
|
140
142
|
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
143
|
|
|
142
144
|
- **[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/
|
|
145
|
+
- **[Install from anywhere](https://microsoft.github.io/apm/consumer/install-packages/)** — GitHub, GitLab, Bitbucket, Azure DevOps, GitHub Enterprise, Gitea, Gogs, any git host
|
|
146
|
+
- **[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
|
|
147
|
+
- **[Author plugins](https://microsoft.github.io/apm/producer/)** — build Copilot, Claude, and Cursor plugins with dependency management, then export standard `plugin.json`
|
|
148
|
+
- **[Marketplaces](https://microsoft.github.io/apm/consumer/installing-from-marketplaces/)** — install plugins from curated registries in one command, deployed across all targets and locked
|
|
149
|
+
- **[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
150
|
- **[CI/CD ready](https://github.com/microsoft/apm-action)** — GitHub Action for automated workflows
|
|
149
151
|
|
|
150
152
|
### 2. Secure by default
|
|
@@ -152,10 +154,10 @@ One `apm.yml` describes every primitive your agents need — instructions, skill
|
|
|
152
154
|
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
155
|
|
|
154
156
|
- **[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/
|
|
157
|
+
- **[Lockfile integrity](https://microsoft.github.io/apm/reference/lockfile-spec/)** — `apm.lock` records resolved sources and content hashes for full provenance
|
|
156
158
|
- **[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/
|
|
159
|
+
- **[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
|
|
160
|
+
- **[MCP trust boundaries](https://microsoft.github.io/apm/consumer/install-mcp-servers/)** — transitive MCP servers require explicit consent
|
|
159
161
|
|
|
160
162
|
### 3. Governed by policy
|
|
161
163
|
|
|
@@ -244,7 +246,7 @@ Or add an MCP server (wired into Copilot, Claude, Cursor, Codex, OpenCode, Gemin
|
|
|
244
246
|
apm install --mcp io.github.github/github-mcp-server --transport http # connects over HTTPS
|
|
245
247
|
```
|
|
246
248
|
|
|
247
|
-
See the **[Getting Started guide](https://microsoft.github.io/apm/
|
|
249
|
+
See the **[Getting Started guide](https://microsoft.github.io/apm/quickstart/)** for the full walkthrough.
|
|
248
250
|
|
|
249
251
|
## Works with agentrc
|
|
250
252
|
|
|
@@ -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
|
|
|
@@ -23,6 +23,8 @@ AI coding agents need context to be useful — standards, prompts, skills, plugi
|
|
|
23
23
|
# apm.yml — ships with your project
|
|
24
24
|
name: your-project
|
|
25
25
|
version: 1.0.0
|
|
26
|
+
targets:
|
|
27
|
+
- copilot # choose the harness(es) this project supports
|
|
26
28
|
dependencies:
|
|
27
29
|
apm:
|
|
28
30
|
# Skills from any repository
|
|
@@ -34,7 +36,7 @@ dependencies:
|
|
|
34
36
|
# A full APM package with instructions, skills, prompts, hooks...
|
|
35
37
|
- microsoft/apm-sample-package#v1.0.0
|
|
36
38
|
mcp:
|
|
37
|
-
# MCP servers -- installed into every
|
|
39
|
+
# MCP servers -- installed into every selected target
|
|
38
40
|
- name: io.github.github/github-mcp-server
|
|
39
41
|
transport: http # MCP transport name, not URL scheme -- connects over HTTPS
|
|
40
42
|
```
|
|
@@ -68,11 +70,11 @@ One command, no configuration -- VS Code and GitHub Copilot read the file automa
|
|
|
68
70
|
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
71
|
|
|
70
72
|
- **[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/
|
|
73
|
+
- **[Install from anywhere](https://microsoft.github.io/apm/consumer/install-packages/)** — GitHub, GitLab, Bitbucket, Azure DevOps, GitHub Enterprise, Gitea, Gogs, any git host
|
|
74
|
+
- **[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
|
|
75
|
+
- **[Author plugins](https://microsoft.github.io/apm/producer/)** — build Copilot, Claude, and Cursor plugins with dependency management, then export standard `plugin.json`
|
|
76
|
+
- **[Marketplaces](https://microsoft.github.io/apm/consumer/installing-from-marketplaces/)** — install plugins from curated registries in one command, deployed across all targets and locked
|
|
77
|
+
- **[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
78
|
- **[CI/CD ready](https://github.com/microsoft/apm-action)** — GitHub Action for automated workflows
|
|
77
79
|
|
|
78
80
|
### 2. Secure by default
|
|
@@ -80,10 +82,10 @@ One `apm.yml` describes every primitive your agents need — instructions, skill
|
|
|
80
82
|
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
83
|
|
|
82
84
|
- **[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/
|
|
85
|
+
- **[Lockfile integrity](https://microsoft.github.io/apm/reference/lockfile-spec/)** — `apm.lock` records resolved sources and content hashes for full provenance
|
|
84
86
|
- **[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/
|
|
87
|
+
- **[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
|
|
88
|
+
- **[MCP trust boundaries](https://microsoft.github.io/apm/consumer/install-mcp-servers/)** — transitive MCP servers require explicit consent
|
|
87
89
|
|
|
88
90
|
### 3. Governed by policy
|
|
89
91
|
|
|
@@ -172,7 +174,7 @@ Or add an MCP server (wired into Copilot, Claude, Cursor, Codex, OpenCode, Gemin
|
|
|
172
174
|
apm install --mcp io.github.github/github-mcp-server --transport http # connects over HTTPS
|
|
173
175
|
```
|
|
174
176
|
|
|
175
|
-
See the **[Getting Started guide](https://microsoft.github.io/apm/
|
|
177
|
+
See the **[Getting Started guide](https://microsoft.github.io/apm/quickstart/)** for the full walkthrough.
|
|
176
178
|
|
|
177
179
|
## Works with agentrc
|
|
178
180
|
|
|
@@ -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.35.0"
|
|
8
8
|
description = "MCP configuration tool"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -60,7 +60,7 @@ build = [
|
|
|
60
60
|
]
|
|
61
61
|
|
|
62
62
|
[project.scripts]
|
|
63
|
-
apm = "apm_cli.
|
|
63
|
+
apm = "apm_cli.entrypoint:main"
|
|
64
64
|
|
|
65
65
|
[tool.setuptools.packages.find]
|
|
66
66
|
where = ["src"]
|
|
@@ -212,6 +212,7 @@ markers = [
|
|
|
212
212
|
"requires_ado_bearer: requires az CLI logged in + APM_TEST_ADO_BEARER=1",
|
|
213
213
|
"requires_network_integration: requires APM_RUN_INTEGRATION_TESTS=1",
|
|
214
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",
|
|
215
216
|
"requires_apm_binary: requires built apm binary on PATH (or APM_BINARY_PATH)",
|
|
216
217
|
"requires_runtime_codex: requires codex runtime installed",
|
|
217
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
|
|
|
@@ -334,6 +337,7 @@ class MCPClientAdapter(ABC):
|
|
|
334
337
|
"""
|
|
335
338
|
self._project_root = Path(project_root) if project_root is not None else None
|
|
336
339
|
self.user_scope = user_scope
|
|
340
|
+
self.written_mcp_hashes: dict[str, str] = {}
|
|
337
341
|
# Per-server tracking populated by the env-resolution helpers and
|
|
338
342
|
# consumed by ``configure_mcp_server`` for the post-install summary
|
|
339
343
|
# and the aggregated legacy-syntax deprecation warning. Defined on
|
|
@@ -364,12 +368,18 @@ class MCPClientAdapter(ABC):
|
|
|
364
368
|
return self._project_root
|
|
365
369
|
return Path(os.getcwd())
|
|
366
370
|
|
|
367
|
-
def render_server_config(
|
|
371
|
+
def render_server_config(
|
|
372
|
+
self,
|
|
373
|
+
server_info: dict,
|
|
374
|
+
*,
|
|
375
|
+
env_overrides: dict | None = None,
|
|
376
|
+
runtime_vars: dict | None = None,
|
|
377
|
+
) -> dict:
|
|
368
378
|
"""Render one native server entry for exact baseline comparisons."""
|
|
369
379
|
rendered = self._format_server_config(
|
|
370
380
|
server_info,
|
|
371
|
-
env_overrides={},
|
|
372
|
-
runtime_vars={},
|
|
381
|
+
env_overrides=env_overrides or {},
|
|
382
|
+
runtime_vars=runtime_vars or {},
|
|
373
383
|
)
|
|
374
384
|
if isinstance(rendered, tuple):
|
|
375
385
|
rendered = rendered[0]
|
|
@@ -377,6 +387,20 @@ class MCPClientAdapter(ABC):
|
|
|
377
387
|
raise ValueError("Adapter did not produce a native MCP server mapping")
|
|
378
388
|
return rendered
|
|
379
389
|
|
|
390
|
+
def matches_managed_server_config(self, native: object, expected: dict) -> bool:
|
|
391
|
+
"""Compare the native connection with the adapter's rendered baseline."""
|
|
392
|
+
return native == expected
|
|
393
|
+
|
|
394
|
+
def managed_server_config(self, native: dict) -> dict:
|
|
395
|
+
"""Return connection data for an actual-write fingerprint."""
|
|
396
|
+
return dict(native)
|
|
397
|
+
|
|
398
|
+
def project_managed_server_config(
|
|
399
|
+
self, native: object, *, baseline: dict, requested: dict
|
|
400
|
+
) -> object:
|
|
401
|
+
"""Return a comparison-only view for an already recorded managed connection."""
|
|
402
|
+
return native
|
|
403
|
+
|
|
380
404
|
@abstractmethod
|
|
381
405
|
def get_config_path(self):
|
|
382
406
|
"""Get the path to the MCP configuration file."""
|
|
@@ -396,6 +420,71 @@ class MCPClientAdapter(ABC):
|
|
|
396
420
|
"""Get the current MCP configuration."""
|
|
397
421
|
pass
|
|
398
422
|
|
|
423
|
+
def validate_config_for_install(self) -> bool:
|
|
424
|
+
"""Allow adapters to refuse unsafe configs before existing-server shortcuts."""
|
|
425
|
+
return True
|
|
426
|
+
|
|
427
|
+
def _read_json_config_for_update(self, config_path: Path) -> dict | None:
|
|
428
|
+
"""Return the JSON object at *config_path* before a merge-and-write.
|
|
429
|
+
|
|
430
|
+
A missing or blank file yields ``{}``. Returns ``None`` after a
|
|
431
|
+
warning when rewriting the file could lose data, so the caller skips
|
|
432
|
+
the write: the existing content is not a JSON object (for example
|
|
433
|
+
JSONC comments), or a user-scope path runs through a symlink, which
|
|
434
|
+
stale cleanup refuses to rewrite later.
|
|
435
|
+
"""
|
|
436
|
+
if self.user_scope and has_symlink_component(Path.home(), config_path):
|
|
437
|
+
_rich_warning(
|
|
438
|
+
f"Skipped {config_path}: APM does not write MCP config through "
|
|
439
|
+
"symlinks. Replace the symlink or configure this server manually.",
|
|
440
|
+
symbol="warning",
|
|
441
|
+
)
|
|
442
|
+
return None
|
|
443
|
+
try:
|
|
444
|
+
raw = config_path.read_text(encoding="utf-8")
|
|
445
|
+
except FileNotFoundError:
|
|
446
|
+
return {}
|
|
447
|
+
except (OSError, UnicodeError) as exc:
|
|
448
|
+
_rich_warning(
|
|
449
|
+
f"Could not read {config_path}: {exc} -- skipping config write; "
|
|
450
|
+
"fix the file's permissions or encoding, or add this server manually",
|
|
451
|
+
symbol="warning",
|
|
452
|
+
)
|
|
453
|
+
return None
|
|
454
|
+
if not raw.strip():
|
|
455
|
+
return {}
|
|
456
|
+
try:
|
|
457
|
+
config = json.loads(raw)
|
|
458
|
+
except json.JSONDecodeError:
|
|
459
|
+
config = None
|
|
460
|
+
if not isinstance(config, dict):
|
|
461
|
+
_rich_warning(
|
|
462
|
+
f"Could not parse {config_path} as a JSON object -- skipping config "
|
|
463
|
+
"write to avoid data loss (comments and trailing commas are not "
|
|
464
|
+
"preserved); fix the file or add this server manually",
|
|
465
|
+
symbol="warning",
|
|
466
|
+
)
|
|
467
|
+
return None
|
|
468
|
+
if self.mcp_servers_key in config and not isinstance(config[self.mcp_servers_key], dict):
|
|
469
|
+
_rich_warning(
|
|
470
|
+
f"Could not parse {config_path}: {self.mcp_servers_key} must be "
|
|
471
|
+
"a JSON object -- skipping config write to avoid data loss; "
|
|
472
|
+
"fix the file or add this server manually",
|
|
473
|
+
symbol="warning",
|
|
474
|
+
)
|
|
475
|
+
return None
|
|
476
|
+
return config
|
|
477
|
+
|
|
478
|
+
@staticmethod
|
|
479
|
+
def _write_json_config(config_path: Path, config: dict) -> None:
|
|
480
|
+
"""Atomically write *config* as JSON and keep the file owner-only.
|
|
481
|
+
|
|
482
|
+
Entries can carry env values resolved at install time.
|
|
483
|
+
"""
|
|
484
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
485
|
+
atomic_write_text(config_path, json.dumps(config, indent=2), new_file_mode=0o600)
|
|
486
|
+
os.chmod(config_path, 0o600)
|
|
487
|
+
|
|
399
488
|
@abstractmethod
|
|
400
489
|
def configure_mcp_server(
|
|
401
490
|
self,
|
|
@@ -1050,6 +1139,28 @@ class MCPClientAdapter(ABC):
|
|
|
1050
1139
|
return True
|
|
1051
1140
|
return not (sys.stdin.isatty() and sys.stdout.isatty())
|
|
1052
1141
|
|
|
1142
|
+
def _resolve_explicit_environment_values(
|
|
1143
|
+
self,
|
|
1144
|
+
env_vars: dict[str, object],
|
|
1145
|
+
env_overrides: dict[str, str] | None = None,
|
|
1146
|
+
) -> dict[str, str]:
|
|
1147
|
+
"""Translate authored references while preserving explicit env literals.
|
|
1148
|
+
|
|
1149
|
+
Resets placeholder tracking; mid-render callers must preserve prior keys.
|
|
1150
|
+
"""
|
|
1151
|
+
resolved: dict[str, str] = {}
|
|
1152
|
+
self._last_env_placeholder_keys = set()
|
|
1153
|
+
for name, value in env_vars.items():
|
|
1154
|
+
if not name or value is None:
|
|
1155
|
+
continue
|
|
1156
|
+
if isinstance(value, TrustedEnvLiteral):
|
|
1157
|
+
resolved[name] = value
|
|
1158
|
+
elif isinstance(value, str):
|
|
1159
|
+
resolved[name] = self._resolve_env_variable(name, value, env_overrides)
|
|
1160
|
+
else:
|
|
1161
|
+
resolved[name] = _stringify_env_literal(value)
|
|
1162
|
+
return resolved
|
|
1163
|
+
|
|
1053
1164
|
def _resolve_environment_variables(self, env_vars, env_overrides=None):
|
|
1054
1165
|
"""Resolve (or translate) declared environment variables.
|
|
1055
1166
|
|
|
@@ -26,7 +26,7 @@ from pathlib import Path
|
|
|
26
26
|
|
|
27
27
|
from ...utils.atomic_io import atomic_write_text
|
|
28
28
|
from ...utils.console import _rich_error, _rich_success, _rich_warning
|
|
29
|
-
from ...utils.path_security import PathTraversalError
|
|
29
|
+
from ...utils.path_security import PathTraversalError, validate_path_segments
|
|
30
30
|
from .copilot import CopilotClientAdapter
|
|
31
31
|
|
|
32
32
|
_log = logging.getLogger(__name__)
|
|
@@ -83,6 +83,51 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
83
83
|
config["command"] = self._rewrite_self_defined_skill_command(config["command"])
|
|
84
84
|
return config
|
|
85
85
|
|
|
86
|
+
def render_server_config(
|
|
87
|
+
self,
|
|
88
|
+
server_info: dict,
|
|
89
|
+
*,
|
|
90
|
+
env_overrides: dict | None = None,
|
|
91
|
+
runtime_vars: dict | None = None,
|
|
92
|
+
) -> dict:
|
|
93
|
+
"""Compare against the normalized shape actually written to Claude."""
|
|
94
|
+
return self._normalize_mcp_entry_for_claude_code(
|
|
95
|
+
super().render_server_config(
|
|
96
|
+
server_info, env_overrides=env_overrides, runtime_vars=runtime_vars
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
def matches_managed_server_config(self, native: object, expected: dict) -> bool:
|
|
101
|
+
"""OAuth metadata is runtime-owned, not part of an APM connection declaration."""
|
|
102
|
+
if not isinstance(native, dict):
|
|
103
|
+
return False
|
|
104
|
+
return self.managed_server_config(native) == expected
|
|
105
|
+
|
|
106
|
+
def managed_server_config(self, native: dict) -> dict:
|
|
107
|
+
"""Exclude only the runtime-owned OAuth account from write fingerprints."""
|
|
108
|
+
return {key: value for key, value in native.items() if key != "oauthAccount"}
|
|
109
|
+
|
|
110
|
+
def project_managed_server_config(
|
|
111
|
+
self, native: object, *, baseline: dict, requested: dict
|
|
112
|
+
) -> object:
|
|
113
|
+
"""Exclude a valid native-only cwd from managed reconciliation, never cleanup."""
|
|
114
|
+
if (
|
|
115
|
+
not isinstance(native, dict)
|
|
116
|
+
or native.get("type") != "stdio"
|
|
117
|
+
or baseline.get("type") != "stdio"
|
|
118
|
+
or "cwd" in baseline
|
|
119
|
+
or "cwd" in requested
|
|
120
|
+
):
|
|
121
|
+
return native
|
|
122
|
+
cwd = native.get("cwd")
|
|
123
|
+
if not isinstance(cwd, str) or not cwd.strip() or "\x00" in cwd:
|
|
124
|
+
return native
|
|
125
|
+
try:
|
|
126
|
+
validate_path_segments(cwd, context="MCP cwd", allow_current_dir=True)
|
|
127
|
+
except PathTraversalError:
|
|
128
|
+
return native
|
|
129
|
+
return {key: value for key, value in native.items() if key != "cwd"}
|
|
130
|
+
|
|
86
131
|
@classmethod
|
|
87
132
|
def _is_remote_mcp_entry(cls, entry: dict) -> bool:
|
|
88
133
|
"""Return whether *entry* describes a remote (URL-addressed) server."""
|
|
@@ -148,7 +193,9 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
148
193
|
}
|
|
149
194
|
|
|
150
195
|
@classmethod
|
|
151
|
-
def _merge_mcp_server_dicts(
|
|
196
|
+
def _merge_mcp_server_dicts(
|
|
197
|
+
cls, existing_servers: dict, config_updates: dict, managed_fields: set[str] | None = None
|
|
198
|
+
) -> None:
|
|
152
199
|
"""Merge *config_updates* into *existing_servers* in place.
|
|
153
200
|
|
|
154
201
|
Per-server entries are shallow-merged: ``{**old, **new}`` so keys present
|
|
@@ -164,15 +211,23 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
164
211
|
continue
|
|
165
212
|
prev = existing_servers.get(name)
|
|
166
213
|
if isinstance(prev, dict):
|
|
214
|
+
if managed_fields:
|
|
215
|
+
prev = {
|
|
216
|
+
key: value
|
|
217
|
+
for key, value in prev.items()
|
|
218
|
+
if key not in managed_fields or key in new_cfg
|
|
219
|
+
}
|
|
167
220
|
merged = {**cls._retained_previous_entry(prev, new_cfg), **new_cfg}
|
|
168
221
|
existing_servers[name] = merged
|
|
169
222
|
else:
|
|
170
223
|
existing_servers[name] = dict(new_cfg)
|
|
171
224
|
|
|
172
|
-
def _merge_and_normalize_updates(
|
|
225
|
+
def _merge_and_normalize_updates(
|
|
226
|
+
self, data: dict, config_updates: dict, managed_fields: set[str] | None = None
|
|
227
|
+
) -> None:
|
|
173
228
|
if "mcpServers" not in data:
|
|
174
229
|
data["mcpServers"] = {}
|
|
175
|
-
self._merge_mcp_server_dicts(data["mcpServers"], config_updates)
|
|
230
|
+
self._merge_mcp_server_dicts(data["mcpServers"], config_updates, managed_fields)
|
|
176
231
|
for name in config_updates:
|
|
177
232
|
ent = data["mcpServers"].get(name)
|
|
178
233
|
if isinstance(ent, dict):
|
|
@@ -184,7 +239,12 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
184
239
|
def _project_mcp_path(self) -> Path:
|
|
185
240
|
return self.project_root / ".mcp.json"
|
|
186
241
|
|
|
187
|
-
|
|
242
|
+
@classmethod
|
|
243
|
+
def resolve_user_claude_unresolved_path(cls) -> Path:
|
|
244
|
+
"""Return the un-normalized path for user-scope Claude Code config.
|
|
245
|
+
|
|
246
|
+
Used for symlink pre-checks before canonical resolution.
|
|
247
|
+
"""
|
|
188
248
|
config_dir = os.environ.get("CLAUDE_CONFIG_DIR", "").strip()
|
|
189
249
|
if config_dir:
|
|
190
250
|
config_path = Path(config_dir).expanduser()
|
|
@@ -193,9 +253,22 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
193
253
|
"CLAUDE_CONFIG_DIR must be an absolute path for user-scope MCP "
|
|
194
254
|
"config; set an absolute path or unset it to use ~/.claude.json."
|
|
195
255
|
)
|
|
196
|
-
return config_path
|
|
256
|
+
return config_path / ".claude.json"
|
|
197
257
|
return Path.home() / ".claude.json"
|
|
198
258
|
|
|
259
|
+
@classmethod
|
|
260
|
+
def resolve_user_claude_json_path(cls, unresolved_path: Path | None = None) -> Path:
|
|
261
|
+
"""Resolve the selected destination, optionally reusing a checked path."""
|
|
262
|
+
path = (
|
|
263
|
+
unresolved_path
|
|
264
|
+
if unresolved_path is not None
|
|
265
|
+
else cls.resolve_user_claude_unresolved_path()
|
|
266
|
+
)
|
|
267
|
+
return path.parent.resolve(strict=False) / path.name
|
|
268
|
+
|
|
269
|
+
def _user_claude_json_path(self) -> Path:
|
|
270
|
+
return self.resolve_user_claude_json_path()
|
|
271
|
+
|
|
199
272
|
def _should_write_project(self) -> bool:
|
|
200
273
|
return (self.project_root / ".claude").is_dir()
|
|
201
274
|
|
|
@@ -216,9 +289,11 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
216
289
|
except (json.JSONDecodeError, OSError):
|
|
217
290
|
return {"mcpServers": {}}
|
|
218
291
|
|
|
219
|
-
def update_config(
|
|
292
|
+
def update_config(
|
|
293
|
+
self, config_updates, enabled=True, *, managed_fields: set[str] | None = None
|
|
294
|
+
):
|
|
220
295
|
if self._is_user_scope():
|
|
221
|
-
return self._merge_user_mcp(config_updates)
|
|
296
|
+
return self._merge_user_mcp(config_updates, managed_fields=managed_fields)
|
|
222
297
|
if not self._should_write_project():
|
|
223
298
|
_rich_warning(
|
|
224
299
|
f"Skipped Claude Code project MCP -- .claude/ not found in {self.project_root}"
|
|
@@ -236,13 +311,13 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
236
311
|
data = {}
|
|
237
312
|
else:
|
|
238
313
|
data = {}
|
|
239
|
-
self._merge_and_normalize_updates(data, config_updates)
|
|
314
|
+
self._merge_and_normalize_updates(data, config_updates, managed_fields)
|
|
240
315
|
path.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
|
|
241
316
|
return True
|
|
242
317
|
except OSError:
|
|
243
318
|
return False
|
|
244
319
|
|
|
245
|
-
def _merge_user_mcp(self, config_updates) -> bool:
|
|
320
|
+
def _merge_user_mcp(self, config_updates, *, managed_fields: set[str] | None = None) -> bool:
|
|
246
321
|
path = self._user_claude_json_path()
|
|
247
322
|
try:
|
|
248
323
|
if path.is_file():
|
|
@@ -255,7 +330,7 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
255
330
|
data = {}
|
|
256
331
|
else:
|
|
257
332
|
data = {}
|
|
258
|
-
self._merge_and_normalize_updates(data, config_updates)
|
|
333
|
+
self._merge_and_normalize_updates(data, config_updates, managed_fields)
|
|
259
334
|
payload = json.dumps(data, indent=2) + "\n"
|
|
260
335
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
261
336
|
atomic_write_text(path, payload, new_file_mode=0o600)
|
|
@@ -272,6 +347,7 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
272
347
|
env_overrides=None,
|
|
273
348
|
server_info_cache=None,
|
|
274
349
|
runtime_vars=None,
|
|
350
|
+
managed_fields: set[str] | None = None,
|
|
275
351
|
):
|
|
276
352
|
if not server_url:
|
|
277
353
|
_rich_error("server_url cannot be empty")
|
|
@@ -296,10 +372,16 @@ class ClaudeClientAdapter(CopilotClientAdapter):
|
|
|
296
372
|
config_key = self._determine_config_key(server_url, server_name)
|
|
297
373
|
|
|
298
374
|
server_config = self._format_server_config(server_info, env_overrides, runtime_vars)
|
|
299
|
-
|
|
375
|
+
from apm_cli.install.mcp.ownership import mcp_native_hash
|
|
376
|
+
|
|
377
|
+
fingerprint = mcp_native_hash(
|
|
378
|
+
self.managed_server_config(self._normalize_mcp_entry_for_claude_code(server_config))
|
|
379
|
+
)
|
|
380
|
+
ok = self.update_config({config_key: server_config}, managed_fields=managed_fields)
|
|
300
381
|
if not ok:
|
|
301
382
|
_rich_error(f"Failed to write MCP config for '{config_key}' to Claude Code")
|
|
302
383
|
return False
|
|
384
|
+
self.written_mcp_hashes[server_url] = fingerprint
|
|
303
385
|
|
|
304
386
|
_rich_success(f"Successfully configured MCP server '{config_key}' for Claude Code")
|
|
305
387
|
return True
|