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.
Files changed (548) hide show
  1. {apm_cli-0.33.0/src/apm_cli.egg-info → apm_cli-0.35.0}/PKG-INFO +14 -12
  2. {apm_cli-0.33.0 → apm_cli-0.35.0}/README.md +13 -11
  3. {apm_cli-0.33.0 → apm_cli-0.35.0}/pyproject.toml +3 -2
  4. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/base.py +114 -3
  5. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/claude.py +94 -12
  6. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/codex.py +132 -12
  7. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/cursor.py +46 -41
  8. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/opencode.py +91 -22
  9. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/lockfile_enrichment.py +22 -19
  10. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/plugin_exporter.py +78 -15
  11. apm_cli-0.35.0/src/apm_cli/bundle/plugin_hooks.py +236 -0
  12. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cli.py +19 -3
  13. apm_cli-0.35.0/src/apm_cli/codex_plugins/__init__.py +1 -0
  14. apm_cli-0.35.0/src/apm_cli/codex_plugins/admission.py +138 -0
  15. apm_cli-0.35.0/src/apm_cli/codex_plugins/client.py +270 -0
  16. apm_cli-0.35.0/src/apm_cli/codex_plugins/manifest.py +84 -0
  17. apm_cli-0.35.0/src/apm_cli/codex_plugins/registrar.py +561 -0
  18. apm_cli-0.35.0/src/apm_cli/codex_plugins/snapshot.py +190 -0
  19. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/_helpers.py +33 -49
  20. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/audit.py +71 -5
  21. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/compile/cli.py +3 -1
  22. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/deps/cli.py +26 -2
  23. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/deps/why.py +8 -1
  24. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/install.py +64 -77
  25. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/lock.py +5 -5
  26. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/outdated.py +45 -8
  27. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/prune.py +5 -1
  28. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/targets.py +31 -16
  29. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/uninstall/cli.py +42 -13
  30. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/uninstall/engine.py +110 -94
  31. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/uninstall/lockfile_state.py +11 -3
  32. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/update.py +3 -3
  33. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/agents_compiler.py +74 -57
  34. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/build_id.py +24 -0
  35. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/root_context_protection.py +66 -1
  36. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/auth.py +109 -10
  37. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/command_logger.py +28 -2
  38. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/conflict_detector.py +8 -5
  39. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/deployment_ledger.py +582 -23
  40. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/deployment_state.py +124 -0
  41. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/operations.py +4 -0
  42. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/safe_installer.py +8 -0
  43. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/script_executors.py +10 -0
  44. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/target_catalog.py +69 -55
  45. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/target_detection.py +64 -22
  46. apm_cli-0.35.0/src/apm_cli/core/tls_trust.py +625 -0
  47. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/apm_resolver.py +152 -9
  48. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/bare_cache.py +12 -2
  49. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/git_reference_resolver.py +3 -0
  50. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/git_remote_ops.py +66 -38
  51. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/github_downloader.py +15 -74
  52. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/github_downloader_validation.py +20 -7
  53. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/immutable_requirements.py +17 -4
  54. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/installed_package.py +19 -2
  55. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/lockfile.py +314 -11
  56. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/package_validator.py +3 -3
  57. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/path_anchoring.py +16 -3
  58. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/reachability.py +40 -5
  59. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/revision_pins.py +3 -1
  60. apm_cli-0.35.0/src/apm_cli/deps/virtual_file.py +73 -0
  61. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/why_walker.py +39 -88
  62. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/drift.py +94 -10
  63. apm_cli-0.35.0/src/apm_cli/entrypoint.py +34 -0
  64. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/hook_contract.py +9 -0
  65. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/audit_replay.py +19 -11
  66. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/audit_target_roots.py +52 -0
  67. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/context.py +9 -1
  68. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/deployable_source_plan.py +103 -26
  69. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/deployed_paths.py +42 -0
  70. apm_cli-0.35.0/src/apm_cli/install/deployment_plan.py +114 -0
  71. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/drift.py +242 -260
  72. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/drift_render.py +68 -4
  73. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/dry_run_plan.py +117 -5
  74. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/errors.py +56 -6
  75. apm_cli-0.35.0/src/apm_cli/install/helpers/absence_observation.py +56 -0
  76. apm_cli-0.35.0/src/apm_cli/install/helpers/no_work.py +122 -0
  77. apm_cli-0.35.0/src/apm_cli/install/helpers/plan_inputs.py +28 -0
  78. apm_cli-0.35.0/src/apm_cli/install/helpers/reconciliation_scope.py +92 -0
  79. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/helpers/ref_reuse.py +2 -0
  80. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/helpers/ref_seed.py +9 -1
  81. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/lsp/integration.py +112 -63
  82. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/manifest_reconcile.py +203 -140
  83. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/command.py +87 -18
  84. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/integration.py +206 -72
  85. apm_cli-0.35.0/src/apm_cli/install/mcp/ownership.py +278 -0
  86. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/native_plugin_admission.py +45 -0
  87. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/outcome.py +4 -0
  88. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/package_resolution.py +62 -13
  89. apm_cli-0.35.0/src/apm_cli/install/package_selection.py +108 -0
  90. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/cleanup.py +40 -7
  91. apm_cli-0.35.0/src/apm_cli/install/phases/codex_plugins.py +49 -0
  92. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/integrate.py +66 -15
  93. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/local_content.py +134 -27
  94. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/lockfile.py +100 -7
  95. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/post_deps_local.py +10 -2
  96. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/resolve.py +64 -84
  97. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/targets.py +5 -1
  98. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/pipeline.py +69 -77
  99. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/plan.py +64 -13
  100. apm_cli-0.35.0/src/apm_cli/install/presentation/__init__.py +27 -0
  101. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/presentation/dry_run.py +27 -8
  102. apm_cli-0.35.0/src/apm_cli/install/presentation/resolution.py +48 -0
  103. apm_cli-0.35.0/src/apm_cli/install/project_package.py +26 -0
  104. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/resolution_staging.py +120 -38
  105. apm_cli-0.35.0/src/apm_cli/install/service.py +702 -0
  106. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/service_integration.py +79 -0
  107. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/services.py +99 -119
  108. apm_cli-0.35.0/src/apm_cli/install/source_helpers.py +122 -0
  109. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/sources.py +56 -11
  110. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/target_filter.py +105 -1
  111. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/template.py +100 -1
  112. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/transaction.py +63 -22
  113. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/validation.py +44 -44
  114. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/agent_integrator.py +156 -2
  115. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/base_integrator.py +128 -0
  116. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/cleanup.py +29 -11
  117. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_bundle.py +3 -1
  118. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_command_paths.py +33 -2
  119. apm_cli-0.35.0/src/apm_cli/integration/hook_cursor_preflight.py +249 -0
  120. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_integrator.py +96 -81
  121. apm_cli-0.35.0/src/apm_cli/integration/hook_native_formats.py +481 -0
  122. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_ownership.py +32 -9
  123. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_source_selection.py +25 -2
  124. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/mcp_config_view.py +327 -52
  125. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/mcp_integrator.py +112 -25
  126. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/mcp_integrator_install.py +304 -46
  127. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/prompt_integrator.py +107 -20
  128. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/skill_integrator.py +402 -401
  129. apm_cli-0.35.0/src/apm_cli/integration/skill_preflight.py +198 -0
  130. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/skill_support.py +16 -2
  131. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/targets.py +377 -248
  132. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/builder.py +104 -43
  133. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/client.py +56 -16
  134. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/output_mappers.py +135 -0
  135. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/output_profiles.py +9 -0
  136. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/ref_resolver.py +23 -6
  137. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/resolver.py +43 -6
  138. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/yml_schema.py +42 -0
  139. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/apm_package.py +153 -2
  140. apm_cli-0.35.0/src/apm_cli/models/dependency/__init__.py +51 -0
  141. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/materialization.py +22 -1
  142. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/reference.py +26 -6
  143. apm_cli-0.35.0/src/apm_cli/models/dependency/replacement.py +674 -0
  144. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/format_detection.py +2 -0
  145. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/manifest_contract.py +15 -2
  146. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/results.py +2 -0
  147. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/validation.py +78 -12
  148. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/ci_checks.py +94 -33
  149. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/discovery.py +29 -2
  150. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/primitives/models.py +32 -0
  151. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/primitives/parser.py +9 -1
  152. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/registry/operations.py +29 -7
  153. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/manager.py +11 -3
  154. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/options.py +89 -0
  155. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/skillspector.py +17 -2
  156. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/file_scanner.py +5 -7
  157. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/atomic_io.py +11 -1
  158. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/content_hash.py +37 -19
  159. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/file_ops.py +13 -2
  160. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/git_env.py +22 -2
  161. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/github_host.py +48 -13
  162. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/helpers.py +6 -1
  163. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/yaml_io.py +10 -7
  164. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/version.py +38 -6
  165. apm_cli-0.35.0/src/apm_cli/version_output.py +57 -0
  166. {apm_cli-0.33.0 → apm_cli-0.35.0/src/apm_cli.egg-info}/PKG-INFO +14 -12
  167. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli.egg-info/SOURCES.txt +20 -0
  168. apm_cli-0.35.0/src/apm_cli.egg-info/entry_points.txt +2 -0
  169. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_apm_package_models.py +11 -7
  170. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_distributed_compilation.py +2 -1
  171. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_empty_string_and_defaults.py +68 -12
  172. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_github_downloader.py +20 -2
  173. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_lockfile.py +34 -9
  174. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_token_manager.py +1 -1
  175. apm_cli-0.33.0/src/apm_cli/core/tls_trust.py +0 -343
  176. apm_cli-0.33.0/src/apm_cli/install/helpers/no_work.py +0 -34
  177. apm_cli-0.33.0/src/apm_cli/install/mcp/ownership.py +0 -110
  178. apm_cli-0.33.0/src/apm_cli/install/package_selection.py +0 -45
  179. apm_cli-0.33.0/src/apm_cli/install/presentation/__init__.py +0 -1
  180. apm_cli-0.33.0/src/apm_cli/install/service.py +0 -353
  181. apm_cli-0.33.0/src/apm_cli/install/source_helpers.py +0 -56
  182. apm_cli-0.33.0/src/apm_cli/integration/hook_native_formats.py +0 -261
  183. apm_cli-0.33.0/src/apm_cli/models/dependency/__init__.py +0 -23
  184. apm_cli-0.33.0/src/apm_cli.egg-info/entry_points.txt +0 -2
  185. {apm_cli-0.33.0 → apm_cli-0.35.0}/AUTHORS +0 -0
  186. {apm_cli-0.33.0 → apm_cli-0.35.0}/LICENSE +0 -0
  187. {apm_cli-0.33.0 → apm_cli-0.35.0}/NOTICE +0 -0
  188. {apm_cli-0.33.0 → apm_cli-0.35.0}/setup.cfg +0 -0
  189. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/__init__.py +0 -0
  190. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/__init__.py +0 -0
  191. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/__init__.py +0 -0
  192. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
  193. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/antigravity.py +0 -0
  194. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/copilot.py +0 -0
  195. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/gemini.py +0 -0
  196. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/hermes.py +0 -0
  197. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/intellij.py +0 -0
  198. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/kiro.py +0 -0
  199. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/vscode.py +0 -0
  200. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/client/windsurf.py +0 -0
  201. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
  202. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/package_manager/base.py +0 -0
  203. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
  204. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/__init__.py +0 -0
  205. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/discovery.py +0 -0
  206. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/manifest_edit.py +0 -0
  207. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/materialize.py +0 -0
  208. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/render.py +0 -0
  209. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/adopt/safety.py +0 -0
  210. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/__init__.py +0 -0
  211. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/assets.py +0 -0
  212. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/constants.py +0 -0
  213. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/errors.py +0 -0
  214. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/io.py +0 -0
  215. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/ir.py +0 -0
  216. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/loader.py +0 -0
  217. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/projection.py +0 -0
  218. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/agent_plugins/validation.py +0 -0
  219. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bootstrap_mirror.py +0 -0
  220. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/__init__.py +0 -0
  221. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/agent_plugin_exporter.py +0 -0
  222. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/attest.py +0 -0
  223. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/claude_plugin_exporter.py +0 -0
  224. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/export_common.py +0 -0
  225. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/formats.py +0 -0
  226. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/local_bundle.py +0 -0
  227. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/packer.py +0 -0
  228. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/plugin_layout.py +0 -0
  229. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/reproducible_archive.py +0 -0
  230. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/bundle/unpacker.py +0 -0
  231. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/__init__.py +0 -0
  232. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/cleanup.py +0 -0
  233. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/git_cache.py +0 -0
  234. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/http_cache.py +0 -0
  235. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/integrity.py +0 -0
  236. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/locking.py +0 -0
  237. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/paths.py +0 -0
  238. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/cache/url_normalize.py +0 -0
  239. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/__init__.py +0 -0
  240. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/_apm_yml_writer.py +0 -0
  241. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/approve.py +0 -0
  242. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/auth.py +0 -0
  243. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/cache.py +0 -0
  244. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/compile/__init__.py +0 -0
  245. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/compile/watcher.py +0 -0
  246. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/config.py +0 -0
  247. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/deps/__init__.py +0 -0
  248. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/deps/_utils.py +0 -0
  249. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/discover.py +0 -0
  250. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/doctor.py +0 -0
  251. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/experimental.py +0 -0
  252. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/find.py +0 -0
  253. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/init.py +0 -0
  254. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/lifecycle.py +0 -0
  255. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/list_cmd.py +0 -0
  256. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/__init__.py +0 -0
  257. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/audit.py +0 -0
  258. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/check.py +0 -0
  259. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/doctor.py +0 -0
  260. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/init.py +0 -0
  261. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/migrate.py +0 -0
  262. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/outdated.py +0 -0
  263. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/plugin/__init__.py +0 -0
  264. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/plugin/add.py +0 -0
  265. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/plugin/remove.py +0 -0
  266. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
  267. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/marketplace/validate.py +0 -0
  268. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/mcp.py +0 -0
  269. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/pack.py +0 -0
  270. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/plugin/__init__.py +0 -0
  271. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/plugin/init.py +0 -0
  272. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/policy.py +0 -0
  273. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/publish.py +0 -0
  274. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/run.py +0 -0
  275. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/runtime.py +0 -0
  276. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/self_update.py +0 -0
  277. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/uninstall/__init__.py +0 -0
  278. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/commands/view.py +0 -0
  279. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/__init__.py +0 -0
  280. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/claude_formatter.py +0 -0
  281. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/constants.py +0 -0
  282. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/constitution.py +0 -0
  283. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/constitution_block.py +0 -0
  284. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/context_optimizer.py +0 -0
  285. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/distributed_compiler.py +0 -0
  286. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/footer.py +0 -0
  287. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/gemini_formatter.py +0 -0
  288. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/injector.py +0 -0
  289. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/inventory.py +0 -0
  290. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/link_resolver.py +0 -0
  291. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/managed_section.py +0 -0
  292. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/output_writer.py +0 -0
  293. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/template_builder.py +0 -0
  294. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/compilation/user_root_context.py +0 -0
  295. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/config.py +0 -0
  296. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/constants.py +0 -0
  297. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/__init__.py +0 -0
  298. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/capability.py +0 -0
  299. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/catalog.py +0 -0
  300. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/constants.py +0 -0
  301. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/registrar.py +0 -0
  302. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/copilot_plugins/settings.py +0 -0
  303. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/__init__.py +0 -0
  304. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/_child_tls/__init__.py +0 -0
  305. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/_child_tls/_apm_tls.pth +0 -0
  306. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/_child_tls/_apm_tls_bootstrap.py +0 -0
  307. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/apm_yml.py +0 -0
  308. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/azure_cli.py +0 -0
  309. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/build_orchestrator.py +0 -0
  310. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/docker_args.py +0 -0
  311. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/errors.py +0 -0
  312. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/experimental.py +0 -0
  313. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/host_providers.py +0 -0
  314. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/install_audit.py +0 -0
  315. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/lifecycle_scripts.py +0 -0
  316. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/null_logger.py +0 -0
  317. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/output_mode.py +0 -0
  318. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/plugin_manifest.py +0 -0
  319. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/project_name.py +0 -0
  320. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/scope.py +0 -0
  321. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/script_runner.py +0 -0
  322. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/script_trust.py +0 -0
  323. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/core/token_manager.py +0 -0
  324. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/__init__.py +0 -0
  325. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/_shared.py +0 -0
  326. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/aggregator.py +0 -0
  327. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/artifactory_entry.py +0 -0
  328. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
  329. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/clone_engine.py +0 -0
  330. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/dependency_graph.py +0 -0
  331. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/download_strategies.py +0 -0
  332. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/git_auth_env.py +0 -0
  333. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/git_file_transport.py +0 -0
  334. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/git_semver_resolver.py +0 -0
  335. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/github_rate_limit.py +0 -0
  336. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/host_backends.py +0 -0
  337. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/outdated_ref_cache.py +0 -0
  338. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/outdated_row.py +0 -0
  339. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/plugin_parser.py +0 -0
  340. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/__init__.py +0 -0
  341. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/auth.py +0 -0
  342. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/client.py +0 -0
  343. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/config_loader.py +0 -0
  344. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/extractor.py +0 -0
  345. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/feature_gate.py +0 -0
  346. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/outdated.py +0 -0
  347. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/resolver.py +0 -0
  348. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry/semver.py +0 -0
  349. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/registry_proxy.py +0 -0
  350. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/shared_clone_cache.py +0 -0
  351. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/tiered_ref_resolver.py +0 -0
  352. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/transport_selection.py +0 -0
  353. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/deps/verifier.py +0 -0
  354. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/__init__.py +0 -0
  355. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/authoring.py +0 -0
  356. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/declared_license.py +0 -0
  357. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/formats.py +0 -0
  358. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/purl.py +0 -0
  359. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/sbom.py +0 -0
  360. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/spdx.py +0 -0
  361. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/export/spdx_data.py +0 -0
  362. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/factory.py +0 -0
  363. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/__init__.py +0 -0
  364. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/argv.py +0 -0
  365. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/artifactory_resolver.py +0 -0
  366. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/cache_pin.py +0 -0
  367. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/exec_gate.py +0 -0
  368. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/finalization.py +0 -0
  369. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/gitlab_resolver.py +0 -0
  370. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/heals/__init__.py +0 -0
  371. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/heals/base.py +0 -0
  372. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
  373. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
  374. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/helpers/__init__.py +0 -0
  375. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/helpers/security_scan.py +0 -0
  376. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/insecure_policy.py +0 -0
  377. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/integrity.py +0 -0
  378. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/legacy_plugin_compat.py +0 -0
  379. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/local_bundle_handler.py +0 -0
  380. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/local_bundle_paths.py +0 -0
  381. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/locking.py +0 -0
  382. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/lsp/__init__.py +0 -0
  383. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/manifest_helpers.py +0 -0
  384. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/__init__.py +0 -0
  385. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/args.py +0 -0
  386. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/conflicts.py +0 -0
  387. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/entry.py +0 -0
  388. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/registry.py +0 -0
  389. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/warnings.py +0 -0
  390. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/mcp/writer.py +0 -0
  391. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/__init__.py +0 -0
  392. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/_redownload.py +0 -0
  393. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/_skip_logic.py +0 -0
  394. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/audit.py +0 -0
  395. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/copilot_plugins.py +0 -0
  396. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/download.py +0 -0
  397. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/finalize.py +0 -0
  398. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/heal.py +0 -0
  399. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/policy_gate.py +0 -0
  400. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/phases/policy_target_check.py +0 -0
  401. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/primitive_classification.py +0 -0
  402. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/registry_wiring.py +0 -0
  403. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/request.py +0 -0
  404. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/root_redirect.py +0 -0
  405. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/skill_path_migration.py +0 -0
  406. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/summary.py +0 -0
  407. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/target_hints.py +0 -0
  408. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/install/target_warnings.py +0 -0
  409. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/__init__.py +0 -0
  410. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/_hook_dropped_targets.py +0 -0
  411. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/_shared.py +0 -0
  412. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/canvas_integrator.py +0 -0
  413. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/command_integrator.py +0 -0
  414. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/copilot_app_db.py +0 -0
  415. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/copilot_app_project.py +0 -0
  416. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/copilot_app_workflow_integrator.py +0 -0
  417. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/copilot_app_ws.py +0 -0
  418. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
  419. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/coverage.py +0 -0
  420. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/dispatch.py +0 -0
  421. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_command_warnings.py +0 -0
  422. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_file_routing.py +0 -0
  423. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_ir.py +0 -0
  424. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/hook_reintegration.py +0 -0
  425. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/instruction_integrator.py +0 -0
  426. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/kiro_hook_integrator.py +0 -0
  427. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/lsp_integrator.py +0 -0
  428. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
  429. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/skill_package_routing.py +0 -0
  430. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/skill_transformer.py +0 -0
  431. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/integration/utils.py +0 -0
  432. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/__init__.py +0 -0
  433. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/_git_utils.py +0 -0
  434. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/_io.py +0 -0
  435. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/_shared.py +0 -0
  436. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/audit.py +0 -0
  437. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/auth_helpers.py +0 -0
  438. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/diagnostics.py +0 -0
  439. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/drift_check.py +0 -0
  440. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/errors.py +0 -0
  441. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/git_stderr.py +0 -0
  442. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/init_template.py +0 -0
  443. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/migration.py +0 -0
  444. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/models.py +0 -0
  445. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/registry.py +0 -0
  446. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/semver.py +0 -0
  447. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/shadow_detector.py +0 -0
  448. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/source_identity.py +0 -0
  449. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/tag_pattern.py +0 -0
  450. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/validator.py +0 -0
  451. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/version_check.py +0 -0
  452. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/version_pins.py +0 -0
  453. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/version_resolver.py +0 -0
  454. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/marketplace/yml_editor.py +0 -0
  455. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/__init__.py +0 -0
  456. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/host_virtual.py +0 -0
  457. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/identity.py +0 -0
  458. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/lsp.py +0 -0
  459. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/mcp.py +0 -0
  460. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/object_fields.py +0 -0
  461. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/provider_coordinates.py +0 -0
  462. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/registry_entry.py +0 -0
  463. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/selection.py +0 -0
  464. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/subsets.py +0 -0
  465. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/dependency/types.py +0 -0
  466. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/models/plugin.py +0 -0
  467. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/output/__init__.py +0 -0
  468. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/output/formatters.py +0 -0
  469. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/output/models.py +0 -0
  470. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/output/script_formatters.py +0 -0
  471. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/__init__.py +0 -0
  472. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/_constraint_pinning.py +0 -0
  473. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/_gitlab.py +0 -0
  474. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/_help_text.py +0 -0
  475. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/_shared.py +0 -0
  476. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/inheritance.py +0 -0
  477. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/install_preflight.py +0 -0
  478. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/matcher.py +0 -0
  479. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/models.py +0 -0
  480. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/outcome_routing.py +0 -0
  481. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/parser.py +0 -0
  482. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/policy_checks.py +0 -0
  483. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/project_config.py +0 -0
  484. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/policy/schema.py +0 -0
  485. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/primitives/__init__.py +0 -0
  486. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/primitives/discovery.py +0 -0
  487. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/registry/__init__.py +0 -0
  488. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/registry/client.py +0 -0
  489. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/registry/integration.py +0 -0
  490. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/__init__.py +0 -0
  491. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/base.py +0 -0
  492. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/codex_runtime.py +0 -0
  493. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/copilot_runtime.py +0 -0
  494. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/factory.py +0 -0
  495. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/llm_runtime.py +0 -0
  496. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/registry.py +0 -0
  497. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/runtime/utils.py +0 -0
  498. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/__init__.py +0 -0
  499. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/audit_report.py +0 -0
  500. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/content_scanner.py +0 -0
  501. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/executables.py +0 -0
  502. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/__init__.py +0 -0
  503. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/base.py +0 -0
  504. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/gate.py +0 -0
  505. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/generic_sarif.py +0 -0
  506. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/registry.py +0 -0
  507. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/runner.py +0 -0
  508. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/external/sarif_ingest.py +0 -0
  509. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/gate.py +0 -0
  510. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/security/primitive_discovery.py +0 -0
  511. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/update_policy.py +0 -0
  512. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/__init__.py +0 -0
  513. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/archive.py +0 -0
  514. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/console.py +0 -0
  515. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/diagnostics.py +0 -0
  516. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/exclude.py +0 -0
  517. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/git_sparse.py +0 -0
  518. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/guards.py +0 -0
  519. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/install_tui.py +0 -0
  520. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/net.py +0 -0
  521. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/normalization.py +0 -0
  522. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/path_security.py +0 -0
  523. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/paths.py +0 -0
  524. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/patterns.py +0 -0
  525. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/perf_stats.py +0 -0
  526. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/reflink.py +0 -0
  527. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/short_sha.py +0 -0
  528. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/staging_guard.py +0 -0
  529. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/subprocess_env.py +0 -0
  530. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/utils/version_checker.py +0 -0
  531. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/workflow/__init__.py +0 -0
  532. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/workflow/discovery.py +0 -0
  533. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/workflow/parser.py +0 -0
  534. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli/workflow/runner.py +0 -0
  535. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli.egg-info/dependency_links.txt +0 -0
  536. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli.egg-info/requires.txt +0 -0
  537. {apm_cli-0.33.0 → apm_cli-0.35.0}/src/apm_cli.egg-info/top_level.txt +0 -0
  538. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_apm_resolver.py +0 -0
  539. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_codex_docker_args_fix.py +0 -0
  540. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_codex_empty_string_and_defaults.py +0 -0
  541. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_collision_integration.py +0 -0
  542. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_console.py +0 -0
  543. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_enhanced_discovery.py +0 -0
  544. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_github_downloader_token_precedence.py +0 -0
  545. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_gitlab_git_transport.py +0 -0
  546. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_runnable_prompts.py +0 -0
  547. {apm_cli-0.33.0 → apm_cli-0.35.0}/tests/test_runtime_manager_token_precedence.py +0 -0
  548. {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.33.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/getting-started/quick-start/)** · **[CLI Reference](https://microsoft.github.io/apm/reference/cli-commands/)** · **[Roadmap](https://github.com/orgs/microsoft/projects/2304/views/5)**
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 detected client
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/guides/dependencies/)** — GitHub, GitLab, Bitbucket, Azure DevOps, GitHub Enterprise, Gitea, Gogs, any git host
144
- - **[Transitive dependencies](https://microsoft.github.io/apm/guides/dependencies/)** — packages can depend on packages; APM resolves the full tree
145
- - **[Author plugins](https://microsoft.github.io/apm/guides/plugins/)** — build Copilot, Claude, and Cursor plugins with dependency management, then export standard `plugin.json`
146
- - **[Marketplaces](https://microsoft.github.io/apm/guides/marketplaces/)** — install plugins from curated registries in one command, deployed across all targets and locked
147
- - **[Pack & distribute](https://microsoft.github.io/apm/guides/pack-distribute/)** — `apm pack` bundles your configuration as a zipped package or a standalone plugin
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/enterprise/governance/)** — `apm.lock` records resolved sources and content hashes for full provenance
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/guides/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/guides/mcp-servers/)** — transitive MCP servers require explicit consent
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/getting-started/quick-start/)** for the full walkthrough.
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/getting-started/quick-start/)** · **[CLI Reference](https://microsoft.github.io/apm/reference/cli-commands/)** · **[Roadmap](https://github.com/orgs/microsoft/projects/2304/views/5)**
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 detected client
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/guides/dependencies/)** — GitHub, GitLab, Bitbucket, Azure DevOps, GitHub Enterprise, Gitea, Gogs, any git host
72
- - **[Transitive dependencies](https://microsoft.github.io/apm/guides/dependencies/)** — packages can depend on packages; APM resolves the full tree
73
- - **[Author plugins](https://microsoft.github.io/apm/guides/plugins/)** — build Copilot, Claude, and Cursor plugins with dependency management, then export standard `plugin.json`
74
- - **[Marketplaces](https://microsoft.github.io/apm/guides/marketplaces/)** — install plugins from curated registries in one command, deployed across all targets and locked
75
- - **[Pack & distribute](https://microsoft.github.io/apm/guides/pack-distribute/)** — `apm pack` bundles your configuration as a zipped package or a standalone plugin
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/enterprise/governance/)** — `apm.lock` records resolved sources and content hashes for full provenance
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/guides/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/guides/mcp-servers/)** — transitive MCP servers require explicit consent
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/getting-started/quick-start/)** for the full walkthrough.
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.33.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.cli:main"
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(self, server_info: dict) -> dict:
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(cls, existing_servers: dict, config_updates: dict) -> None:
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(self, data: dict, config_updates: dict) -> None:
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
- def _user_claude_json_path(self) -> Path:
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.resolve(strict=False) / ".claude.json"
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(self, config_updates, enabled=True):
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
- ok = self.update_config({config_key: server_config})
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