apm-cli 0.24.0__tar.gz → 0.24.1__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 (424) hide show
  1. {apm_cli-0.24.0 → apm_cli-0.24.1}/NOTICE +35 -0
  2. {apm_cli-0.24.0/src/apm_cli.egg-info → apm_cli-0.24.1}/PKG-INFO +2 -1
  3. {apm_cli-0.24.0 → apm_cli-0.24.1}/pyproject.toml +2 -2
  4. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/claude.py +20 -5
  5. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/codex.py +13 -10
  6. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/_helpers.py +1 -1
  7. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/deps/cli.py +82 -19
  8. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/install.py +40 -113
  9. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/prune.py +1 -1
  10. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/publish.py +7 -1
  11. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/update.py +114 -0
  12. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/lockfile.py +23 -0
  13. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/mcp/__init__.py +5 -0
  14. apm_cli-0.24.1/src/apm_cli/install/mcp/integration.py +198 -0
  15. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/package_resolution.py +10 -1
  16. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/lockfile.py +45 -0
  17. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/validation.py +41 -1
  18. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/mcp_integrator.py +56 -6
  19. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/skill_integrator.py +26 -7
  20. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/apm_package.py +8 -0
  21. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/dependency/identity.py +36 -0
  22. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/dependency/mcp.py +13 -0
  23. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/dependency/reference.py +12 -0
  24. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/ci_checks.py +14 -8
  25. {apm_cli-0.24.0 → apm_cli-0.24.1/src/apm_cli.egg-info}/PKG-INFO +2 -1
  26. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli.egg-info/SOURCES.txt +1 -0
  27. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli.egg-info/requires.txt +1 -0
  28. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_apm_package_models.py +33 -0
  29. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_lockfile.py +15 -0
  30. {apm_cli-0.24.0 → apm_cli-0.24.1}/AUTHORS +0 -0
  31. {apm_cli-0.24.0 → apm_cli-0.24.1}/LICENSE +0 -0
  32. {apm_cli-0.24.0 → apm_cli-0.24.1}/README.md +0 -0
  33. {apm_cli-0.24.0 → apm_cli-0.24.1}/setup.cfg +0 -0
  34. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/__init__.py +0 -0
  35. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/__init__.py +0 -0
  36. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/__init__.py +0 -0
  37. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
  38. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/antigravity.py +0 -0
  39. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/base.py +0 -0
  40. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/copilot.py +0 -0
  41. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/cursor.py +0 -0
  42. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/gemini.py +0 -0
  43. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/hermes.py +0 -0
  44. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/intellij.py +0 -0
  45. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/kiro.py +0 -0
  46. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/opencode.py +0 -0
  47. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/vscode.py +0 -0
  48. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/client/windsurf.py +0 -0
  49. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
  50. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/package_manager/base.py +0 -0
  51. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
  52. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/bootstrap_mirror.py +0 -0
  53. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/bundle/__init__.py +0 -0
  54. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/bundle/attest.py +0 -0
  55. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/bundle/local_bundle.py +0 -0
  56. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/bundle/lockfile_enrichment.py +0 -0
  57. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/bundle/packer.py +0 -0
  58. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/bundle/plugin_exporter.py +0 -0
  59. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/bundle/unpacker.py +0 -0
  60. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/cache/__init__.py +0 -0
  61. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/cache/git_cache.py +0 -0
  62. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/cache/http_cache.py +0 -0
  63. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/cache/integrity.py +0 -0
  64. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/cache/locking.py +0 -0
  65. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/cache/paths.py +0 -0
  66. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/cache/url_normalize.py +0 -0
  67. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/cli.py +0 -0
  68. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/__init__.py +0 -0
  69. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/_apm_yml_writer.py +0 -0
  70. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/approve.py +0 -0
  71. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/audit.py +0 -0
  72. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/cache.py +0 -0
  73. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/compile/__init__.py +0 -0
  74. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/compile/cli.py +0 -0
  75. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/compile/watcher.py +0 -0
  76. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/config.py +0 -0
  77. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/deps/__init__.py +0 -0
  78. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/deps/_utils.py +0 -0
  79. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/deps/why.py +0 -0
  80. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/doctor.py +0 -0
  81. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/experimental.py +0 -0
  82. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/find.py +0 -0
  83. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/init.py +0 -0
  84. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/lifecycle.py +0 -0
  85. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/list_cmd.py +0 -0
  86. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/lock.py +0 -0
  87. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/__init__.py +0 -0
  88. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/audit.py +0 -0
  89. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/check.py +0 -0
  90. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/doctor.py +0 -0
  91. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/init.py +0 -0
  92. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/migrate.py +0 -0
  93. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/outdated.py +0 -0
  94. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/plugin/__init__.py +0 -0
  95. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/plugin/add.py +0 -0
  96. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/plugin/remove.py +0 -0
  97. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
  98. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/marketplace/validate.py +0 -0
  99. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/mcp.py +0 -0
  100. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/outdated.py +0 -0
  101. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/pack.py +0 -0
  102. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/plugin/__init__.py +0 -0
  103. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/plugin/init.py +0 -0
  104. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/policy.py +0 -0
  105. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/run.py +0 -0
  106. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/runtime.py +0 -0
  107. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/self_update.py +0 -0
  108. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/targets.py +0 -0
  109. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/uninstall/__init__.py +0 -0
  110. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/uninstall/cli.py +0 -0
  111. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/uninstall/engine.py +0 -0
  112. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/commands/view.py +0 -0
  113. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/__init__.py +0 -0
  114. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/agents_compiler.py +0 -0
  115. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/build_id.py +0 -0
  116. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/claude_formatter.py +0 -0
  117. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/constants.py +0 -0
  118. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/constitution.py +0 -0
  119. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/constitution_block.py +0 -0
  120. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/context_optimizer.py +0 -0
  121. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/distributed_compiler.py +0 -0
  122. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/gemini_formatter.py +0 -0
  123. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/injector.py +0 -0
  124. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/link_resolver.py +0 -0
  125. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/managed_section.py +0 -0
  126. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/output_writer.py +0 -0
  127. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/template_builder.py +0 -0
  128. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/compilation/user_root_context.py +0 -0
  129. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/config.py +0 -0
  130. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/constants.py +0 -0
  131. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/__init__.py +0 -0
  132. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/apm_yml.py +0 -0
  133. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/auth.py +0 -0
  134. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/azure_cli.py +0 -0
  135. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/build_orchestrator.py +0 -0
  136. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/command_logger.py +0 -0
  137. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/conflict_detector.py +0 -0
  138. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/docker_args.py +0 -0
  139. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/errors.py +0 -0
  140. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/experimental.py +0 -0
  141. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/install_audit.py +0 -0
  142. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/lifecycle_scripts.py +0 -0
  143. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/null_logger.py +0 -0
  144. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/operations.py +0 -0
  145. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/plugin_manifest.py +0 -0
  146. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/safe_installer.py +0 -0
  147. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/scope.py +0 -0
  148. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/script_executors.py +0 -0
  149. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/script_runner.py +0 -0
  150. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/script_trust.py +0 -0
  151. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/target_detection.py +0 -0
  152. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/core/token_manager.py +0 -0
  153. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/__init__.py +0 -0
  154. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/_shared.py +0 -0
  155. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/aggregator.py +0 -0
  156. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/apm_resolver.py +0 -0
  157. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/artifactory_entry.py +0 -0
  158. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
  159. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/bare_cache.py +0 -0
  160. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/clone_engine.py +0 -0
  161. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/dependency_graph.py +0 -0
  162. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/download_strategies.py +0 -0
  163. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/git_auth_env.py +0 -0
  164. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/git_file_transport.py +0 -0
  165. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/git_reference_resolver.py +0 -0
  166. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/git_remote_ops.py +0 -0
  167. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/git_semver_resolver.py +0 -0
  168. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/github_downloader.py +0 -0
  169. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/github_downloader_validation.py +0 -0
  170. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/host_backends.py +0 -0
  171. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/installed_package.py +0 -0
  172. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/outdated_ref_cache.py +0 -0
  173. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/outdated_row.py +0 -0
  174. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/package_validator.py +0 -0
  175. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/path_anchoring.py +0 -0
  176. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/plugin_parser.py +0 -0
  177. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/registry/__init__.py +0 -0
  178. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/registry/auth.py +0 -0
  179. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/registry/client.py +0 -0
  180. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/registry/config_loader.py +0 -0
  181. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/registry/extractor.py +0 -0
  182. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/registry/feature_gate.py +0 -0
  183. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/registry/outdated.py +0 -0
  184. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/registry/resolver.py +0 -0
  185. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/registry/semver.py +0 -0
  186. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/registry_proxy.py +0 -0
  187. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/revision_pins.py +0 -0
  188. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/shared_clone_cache.py +0 -0
  189. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/tiered_ref_resolver.py +0 -0
  190. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/transport_selection.py +0 -0
  191. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/verifier.py +0 -0
  192. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/deps/why_walker.py +0 -0
  193. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/drift.py +0 -0
  194. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/export/__init__.py +0 -0
  195. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/export/authoring.py +0 -0
  196. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/export/declared_license.py +0 -0
  197. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/export/formats.py +0 -0
  198. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/export/purl.py +0 -0
  199. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/export/sbom.py +0 -0
  200. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/export/spdx.py +0 -0
  201. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/export/spdx_data.py +0 -0
  202. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/factory.py +0 -0
  203. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/__init__.py +0 -0
  204. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/artifactory_resolver.py +0 -0
  205. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/cache_pin.py +0 -0
  206. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/context.py +0 -0
  207. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/deployed_paths.py +0 -0
  208. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/drift.py +0 -0
  209. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/errors.py +0 -0
  210. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/exec_gate.py +0 -0
  211. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/gitlab_resolver.py +0 -0
  212. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/heals/__init__.py +0 -0
  213. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/heals/base.py +0 -0
  214. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
  215. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
  216. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/helpers/__init__.py +0 -0
  217. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/helpers/ref_reuse.py +0 -0
  218. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/helpers/ref_seed.py +0 -0
  219. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/helpers/security_scan.py +0 -0
  220. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/insecure_policy.py +0 -0
  221. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/integrity.py +0 -0
  222. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/local_bundle_handler.py +0 -0
  223. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/lsp/__init__.py +0 -0
  224. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/lsp/integration.py +0 -0
  225. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/manifest_reconcile.py +0 -0
  226. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/mcp/args.py +0 -0
  227. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/mcp/command.py +0 -0
  228. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/mcp/conflicts.py +0 -0
  229. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/mcp/entry.py +0 -0
  230. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/mcp/registry.py +0 -0
  231. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/mcp/warnings.py +0 -0
  232. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/mcp/writer.py +0 -0
  233. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/package_selection.py +0 -0
  234. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/__init__.py +0 -0
  235. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/_redownload.py +0 -0
  236. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/_skip_logic.py +0 -0
  237. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/audit.py +0 -0
  238. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/cleanup.py +0 -0
  239. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/download.py +0 -0
  240. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/finalize.py +0 -0
  241. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/heal.py +0 -0
  242. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/integrate.py +0 -0
  243. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/local_content.py +0 -0
  244. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/policy_gate.py +0 -0
  245. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/policy_target_check.py +0 -0
  246. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/post_deps_local.py +0 -0
  247. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/resolve.py +0 -0
  248. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/phases/targets.py +0 -0
  249. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/pipeline.py +0 -0
  250. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/plan.py +0 -0
  251. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/presentation/__init__.py +0 -0
  252. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/presentation/dry_run.py +0 -0
  253. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/registry_wiring.py +0 -0
  254. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/request.py +0 -0
  255. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/root_redirect.py +0 -0
  256. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/service.py +0 -0
  257. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/services.py +0 -0
  258. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/skill_path_migration.py +0 -0
  259. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/sources.py +0 -0
  260. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/summary.py +0 -0
  261. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/target_filter.py +0 -0
  262. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/install/template.py +0 -0
  263. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/__init__.py +0 -0
  264. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/_shared.py +0 -0
  265. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/agent_integrator.py +0 -0
  266. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/base_integrator.py +0 -0
  267. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/canvas_integrator.py +0 -0
  268. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/cleanup.py +0 -0
  269. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/command_integrator.py +0 -0
  270. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/copilot_app_db.py +0 -0
  271. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/copilot_app_project.py +0 -0
  272. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/copilot_app_workflow_integrator.py +0 -0
  273. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/copilot_app_ws.py +0 -0
  274. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
  275. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/coverage.py +0 -0
  276. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/dispatch.py +0 -0
  277. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/hook_bundle.py +0 -0
  278. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/hook_file_routing.py +0 -0
  279. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/hook_integrator.py +0 -0
  280. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/instruction_integrator.py +0 -0
  281. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/kiro_hook_integrator.py +0 -0
  282. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/lsp_integrator.py +0 -0
  283. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/mcp_integrator_install.py +0 -0
  284. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
  285. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/prompt_integrator.py +0 -0
  286. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/skill_transformer.py +0 -0
  287. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/targets.py +0 -0
  288. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/integration/utils.py +0 -0
  289. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/__init__.py +0 -0
  290. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/_git_utils.py +0 -0
  291. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/_io.py +0 -0
  292. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/_shared.py +0 -0
  293. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/audit.py +0 -0
  294. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/auth_helpers.py +0 -0
  295. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/builder.py +0 -0
  296. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/client.py +0 -0
  297. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/diagnostics.py +0 -0
  298. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/drift_check.py +0 -0
  299. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/errors.py +0 -0
  300. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/git_stderr.py +0 -0
  301. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/init_template.py +0 -0
  302. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/migration.py +0 -0
  303. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/models.py +0 -0
  304. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/output_mappers.py +0 -0
  305. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/output_profiles.py +0 -0
  306. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/ref_resolver.py +0 -0
  307. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/registry.py +0 -0
  308. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/resolver.py +0 -0
  309. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/semver.py +0 -0
  310. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/shadow_detector.py +0 -0
  311. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/tag_pattern.py +0 -0
  312. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/validator.py +0 -0
  313. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/version_check.py +0 -0
  314. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/version_pins.py +0 -0
  315. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/version_resolver.py +0 -0
  316. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/yml_editor.py +0 -0
  317. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/marketplace/yml_schema.py +0 -0
  318. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/__init__.py +0 -0
  319. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/dependency/__init__.py +0 -0
  320. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/dependency/lsp.py +0 -0
  321. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/dependency/object_fields.py +0 -0
  322. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/dependency/subsets.py +0 -0
  323. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/dependency/types.py +0 -0
  324. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/format_detection.py +0 -0
  325. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/plugin.py +0 -0
  326. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/results.py +0 -0
  327. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/models/validation.py +0 -0
  328. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/output/__init__.py +0 -0
  329. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/output/formatters.py +0 -0
  330. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/output/models.py +0 -0
  331. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/output/script_formatters.py +0 -0
  332. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/__init__.py +0 -0
  333. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/_constraint_pinning.py +0 -0
  334. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/_help_text.py +0 -0
  335. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/_shared.py +0 -0
  336. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/discovery.py +0 -0
  337. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/inheritance.py +0 -0
  338. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/install_preflight.py +0 -0
  339. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/matcher.py +0 -0
  340. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/models.py +0 -0
  341. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/outcome_routing.py +0 -0
  342. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/parser.py +0 -0
  343. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/policy_checks.py +0 -0
  344. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/project_config.py +0 -0
  345. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/policy/schema.py +0 -0
  346. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/primitives/__init__.py +0 -0
  347. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/primitives/discovery.py +0 -0
  348. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/primitives/models.py +0 -0
  349. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/primitives/parser.py +0 -0
  350. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/registry/__init__.py +0 -0
  351. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/registry/client.py +0 -0
  352. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/registry/integration.py +0 -0
  353. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/registry/operations.py +0 -0
  354. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/runtime/__init__.py +0 -0
  355. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/runtime/base.py +0 -0
  356. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/runtime/codex_runtime.py +0 -0
  357. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/runtime/copilot_runtime.py +0 -0
  358. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/runtime/factory.py +0 -0
  359. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/runtime/llm_runtime.py +0 -0
  360. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/runtime/manager.py +0 -0
  361. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/runtime/utils.py +0 -0
  362. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/__init__.py +0 -0
  363. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/audit_report.py +0 -0
  364. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/content_scanner.py +0 -0
  365. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/executables.py +0 -0
  366. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/external/__init__.py +0 -0
  367. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/external/base.py +0 -0
  368. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/external/gate.py +0 -0
  369. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/external/generic_sarif.py +0 -0
  370. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/external/options.py +0 -0
  371. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/external/registry.py +0 -0
  372. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/external/runner.py +0 -0
  373. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/external/sarif_ingest.py +0 -0
  374. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/external/skillspector.py +0 -0
  375. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/file_scanner.py +0 -0
  376. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/security/gate.py +0 -0
  377. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/update_policy.py +0 -0
  378. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/__init__.py +0 -0
  379. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/archive.py +0 -0
  380. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/atomic_io.py +0 -0
  381. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/console.py +0 -0
  382. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/content_hash.py +0 -0
  383. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/diagnostics.py +0 -0
  384. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/exclude.py +0 -0
  385. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/file_ops.py +0 -0
  386. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/git_env.py +0 -0
  387. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/git_sparse.py +0 -0
  388. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/github_host.py +0 -0
  389. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/guards.py +0 -0
  390. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/helpers.py +0 -0
  391. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/install_tui.py +0 -0
  392. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/normalization.py +0 -0
  393. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/path_security.py +0 -0
  394. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/paths.py +0 -0
  395. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/patterns.py +0 -0
  396. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/perf_stats.py +0 -0
  397. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/reflink.py +0 -0
  398. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/short_sha.py +0 -0
  399. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/subprocess_env.py +0 -0
  400. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/version_checker.py +0 -0
  401. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/utils/yaml_io.py +0 -0
  402. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/version.py +0 -0
  403. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/workflow/__init__.py +0 -0
  404. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/workflow/discovery.py +0 -0
  405. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/workflow/parser.py +0 -0
  406. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli/workflow/runner.py +0 -0
  407. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli.egg-info/dependency_links.txt +0 -0
  408. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli.egg-info/entry_points.txt +0 -0
  409. {apm_cli-0.24.0 → apm_cli-0.24.1}/src/apm_cli.egg-info/top_level.txt +0 -0
  410. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_apm_resolver.py +0 -0
  411. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_codex_docker_args_fix.py +0 -0
  412. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_codex_empty_string_and_defaults.py +0 -0
  413. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_collision_integration.py +0 -0
  414. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_console.py +0 -0
  415. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_distributed_compilation.py +0 -0
  416. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_empty_string_and_defaults.py +0 -0
  417. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_enhanced_discovery.py +0 -0
  418. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_github_downloader.py +0 -0
  419. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_github_downloader_token_precedence.py +0 -0
  420. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_gitlab_git_transport.py +0 -0
  421. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_runnable_prompts.py +0 -0
  422. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_runtime_manager_token_precedence.py +0 -0
  423. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_token_manager.py +0 -0
  424. {apm_cli-0.24.0 → apm_cli-0.24.1}/tests/test_virtual_package_multi_install.py +0 -0
@@ -703,6 +703,41 @@ THE SOFTWARE.
703
703
 
704
704
  ---
705
705
 
706
+ ## Component. tomlkit
707
+
708
+ - Version requirement: `>=0.13`
709
+ - Upstream: https://github.com/python-poetry/tomlkit
710
+ - SPDX: `MIT`
711
+
712
+ ### Open Source License/Copyright Notice.
713
+
714
+ _Copyright (c) 2018 Sébastien Eustace_
715
+
716
+ ```
717
+ Copyright (c) 2018 Sébastien Eustace
718
+
719
+ Permission is hereby granted, free of charge, to any person obtaining
720
+ a copy of this software and associated documentation files (the
721
+ "Software"), to deal in the Software without restriction, including
722
+ without limitation the rights to use, copy, modify, merge, publish,
723
+ distribute, sublicense, and/or sell copies of the Software, and to
724
+ permit persons to whom the Software is furnished to do so, subject to
725
+ the following conditions:
726
+
727
+ The above copyright notice and this permission notice shall be
728
+ included in all copies or substantial portions of the Software.
729
+
730
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
731
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
732
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
733
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
734
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
735
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
736
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
737
+ ```
738
+
739
+ ---
740
+
706
741
  ## Component. rich
707
742
 
708
743
  - Version requirement: `>=13.0.0`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apm-cli
3
- Version: 0.24.0
3
+ Version: 0.24.1
4
4
  Summary: MCP configuration tool
5
5
  Author-email: Daniel Meppiel <user@example.com>
6
6
  License: MIT License
@@ -46,6 +46,7 @@ Requires-Dist: llm>=0.28
46
46
  Requires-Dist: llm-github-models>=0.18.0
47
47
  Requires-Dist: tomli>=1.2.0; python_version < "3.11"
48
48
  Requires-Dist: toml>=0.10.2
49
+ Requires-Dist: tomlkit>=0.13
49
50
  Requires-Dist: rich>=13.0.0
50
51
  Requires-Dist: rich-click>=1.7.0
51
52
  Requires-Dist: watchdog>=3.0.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "apm-cli"
7
- version = "0.24.0"
7
+ version = "0.24.1"
8
8
  description = "MCP configuration tool"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -31,6 +31,7 @@ dependencies = [
31
31
  "llm-github-models>=0.18.0",
32
32
  "tomli>=1.2.0; python_version<'3.11'",
33
33
  "toml>=0.10.2",
34
+ "tomlkit>=0.13",
34
35
  "rich>=13.0.0",
35
36
  "rich-click>=1.7.0",
36
37
  "watchdog>=3.0.0",
@@ -170,4 +171,3 @@ markers = [
170
171
  "requires_inference: requires APM_RUN_INFERENCE_TESTS=1 + model API access",
171
172
  "req: binds a test to one or more OpenAPM req-XXX ids (spec-conformance suite)",
172
173
  ]
173
-
@@ -4,11 +4,11 @@ Project scope: ``.mcp.json`` at the project root with top-level ``mcpServers``
4
4
  (``--scope project`` in Claude Code). Writes are opt-in when ``.claude/`` exists,
5
5
  mirroring the Cursor/OpenCode directory-presence convention.
6
6
 
7
- User scope: top-level ``mcpServers`` in ``~/.claude.json`` (``--scope user``).
8
- Writes are atomic and create the file with ``0o600`` permissions on first
9
- write so the shared Claude Code config is not silently truncated by a
10
- concurrent writer and cannot leak any embedded OAuth state to other users
11
- on a multi-user host.
7
+ User scope: top-level ``mcpServers`` in ``$CLAUDE_CONFIG_DIR/.claude.json``
8
+ when configured, otherwise ``~/.claude.json`` (``--scope user``). Writes are
9
+ atomic and create the file with ``0o600`` permissions on first write so the
10
+ shared Claude Code config is not silently truncated by a concurrent writer
11
+ and cannot leak any embedded OAuth state to other users on a multi-user host.
12
12
 
13
13
  Local scope (Claude Code's third scope -- the default for ``claude mcp add``,
14
14
  storing per-project private config under ``~/.claude.json -> projects.<abs_path>
@@ -20,12 +20,17 @@ See https://code.claude.com/docs/en/mcp
20
20
  """
21
21
 
22
22
  import json
23
+ import logging
24
+ import os
23
25
  from pathlib import Path
24
26
 
25
27
  from ...utils.atomic_io import atomic_write_text
26
28
  from ...utils.console import _rich_error, _rich_success, _rich_warning
29
+ from ...utils.path_security import PathTraversalError
27
30
  from .copilot import CopilotClientAdapter
28
31
 
32
+ _log = logging.getLogger(__name__)
33
+
29
34
 
30
35
  class ClaudeClientAdapter(CopilotClientAdapter):
31
36
  """MCP configuration for Claude Code (``mcpServers`` schema).
@@ -141,6 +146,15 @@ class ClaudeClientAdapter(CopilotClientAdapter):
141
146
  return self.project_root / ".mcp.json"
142
147
 
143
148
  def _user_claude_json_path(self) -> Path:
149
+ config_dir = os.environ.get("CLAUDE_CONFIG_DIR", "").strip()
150
+ if config_dir:
151
+ config_path = Path(config_dir).expanduser()
152
+ if not config_path.is_absolute():
153
+ raise PathTraversalError(
154
+ "CLAUDE_CONFIG_DIR must be an absolute path for user-scope MCP "
155
+ "config; set an absolute path or unset it to use ~/.claude.json."
156
+ )
157
+ return config_path.resolve(strict=False) / ".claude.json"
144
158
  return Path.home() / ".claude.json"
145
159
 
146
160
  def _should_write_project(self) -> bool:
@@ -206,6 +220,7 @@ class ClaudeClientAdapter(CopilotClientAdapter):
206
220
  payload = json.dumps(data, indent=2) + "\n"
207
221
  path.parent.mkdir(parents=True, exist_ok=True)
208
222
  atomic_write_text(path, payload, new_file_mode=0o600)
223
+ _log.debug("Claude user-scope MCP config written to %s", path)
209
224
  return True
210
225
  except OSError:
211
226
  return False
@@ -5,10 +5,12 @@ import os
5
5
  from pathlib import Path
6
6
  from urllib.parse import urlparse
7
7
 
8
- import toml
8
+ import tomlkit
9
+ from tomlkit.exceptions import TOMLKitError
9
10
 
10
11
  from ...registry.client import SimpleRegistryClient
11
12
  from ...registry.integration import RegistryIntegration
13
+ from ...utils.atomic_io import atomic_write_text
12
14
  from ...utils.console import _rich_success, _rich_warning
13
15
  from ...utils.path_security import PathTraversalError
14
16
  from ._mcp_runtime_args import process_v01_value_hint_arg
@@ -94,9 +96,7 @@ class CodexClientAdapter(MCPClientAdapter):
94
96
  # Ensure directory exists
95
97
  config_path.parent.mkdir(parents=True, exist_ok=True)
96
98
 
97
- with open(config_path, "w", encoding="utf-8") as f:
98
- toml.dump(current_config, f)
99
- os.chmod(config_path, 0o600)
99
+ atomic_write_text(config_path, tomlkit.dumps(current_config), new_file_mode=0o600)
100
100
  _log.debug("Codex config written to %s", config_path)
101
101
  return True
102
102
 
@@ -104,8 +104,9 @@ class CodexClientAdapter(MCPClientAdapter):
104
104
  """Get the current Codex CLI MCP configuration.
105
105
 
106
106
  Returns:
107
- dict | None: Current configuration, empty dict if file doesn't
108
- exist, or None when an existing config cannot be parsed safely.
107
+ MutableMapping | None: Round-trip-preserving mapping when the file
108
+ exists, empty mapping if it does not exist, or None when an
109
+ existing config cannot be parsed safely.
109
110
  """
110
111
  config_path = self.get_config_path()
111
112
 
@@ -113,12 +114,14 @@ class CodexClientAdapter(MCPClientAdapter):
113
114
  return {}
114
115
 
115
116
  try:
116
- with open(config_path, encoding="utf-8") as f:
117
- return toml.load(f)
118
- except toml.TomlDecodeError as exc:
117
+ with open(config_path, encoding="utf-8") as config_file:
118
+ return tomlkit.load(config_file)
119
+ except (TOMLKitError, UnicodeDecodeError) as exc:
119
120
  _log.debug("Failed to parse Codex config at %s", config_path, exc_info=True)
120
121
  _rich_warning(
121
- f"Could not parse {config_path}: {exc} -- skipping config write to avoid data loss",
122
+ f"Could not read or parse {config_path}: {exc} "
123
+ "-- skipping config write to avoid data loss; inspect the file "
124
+ "or delete it to reset Codex configuration",
122
125
  symbol="warning",
123
126
  )
124
127
  return None
@@ -308,7 +308,7 @@ def _check_orphaned_packages():
308
308
  from ..models.apm_package import APMPackage
309
309
 
310
310
  apm_package = APMPackage.from_apm_yml(Path(APM_YML_FILENAME))
311
- declared_deps = apm_package.get_apm_dependencies()
311
+ declared_deps = apm_package.get_all_apm_dependencies()
312
312
  lockfile = LockFile.read(get_lockfile_path(Path.cwd()))
313
313
  expected = _build_expected_install_paths(declared_deps, lockfile, apm_modules_dir)
314
314
  except Exception:
@@ -70,14 +70,42 @@ def _dep_display_name(dep) -> str:
70
70
  return f"{key}@{version}"
71
71
 
72
72
 
73
- def _add_tree_children(parent_branch, parent_repo_url, children_map, has_rich, depth=0):
73
+ def _add_tree_children(parent_branch, parent_key, children_map, has_rich, depth=0):
74
74
  """Recursively add transitive deps as nested children of a tree node."""
75
- kids = children_map.get(parent_repo_url, [])
75
+ kids = children_map.get(parent_key, [])
76
76
  for child_dep in kids:
77
77
  child_name = _dep_display_name(child_dep)
78
78
  child_branch = parent_branch.add(f"[dim]{child_name}[/dim]") if has_rich else child_name
79
79
  if depth < 5: # Prevent infinite recursion
80
- _add_tree_children(child_branch, child_dep.repo_url, children_map, has_rich, depth + 1)
80
+ _add_tree_children(
81
+ child_branch,
82
+ child_dep.get_unique_key(),
83
+ children_map,
84
+ has_rich,
85
+ depth + 1,
86
+ )
87
+
88
+
89
+ def _echo_tree_children(
90
+ parent_key: str,
91
+ children_map: dict[str, list],
92
+ prefix: str = "",
93
+ depth: int = 0,
94
+ ) -> None:
95
+ """Render transitive dependencies recursively without Rich."""
96
+ kids = children_map.get(parent_key, [])
97
+ for index, child_dep in enumerate(kids):
98
+ is_last = index == len(kids) - 1
99
+ child_prefix = "+-- " if is_last else "|-- "
100
+ click.echo(f"{prefix}{child_prefix}{_dep_display_name(child_dep)}")
101
+ if depth < 5:
102
+ continuation = " " if is_last else "| "
103
+ _echo_tree_children(
104
+ child_dep.get_unique_key(),
105
+ children_map,
106
+ prefix + continuation,
107
+ depth + 1,
108
+ )
81
109
 
82
110
 
83
111
  # ---------------------------------------------------------------------------
@@ -156,13 +184,14 @@ def _resolve_scope_deps(apm_dir, logger, insecure_only=False):
156
184
  if lockfile_path.exists():
157
185
  lockfile = LockFile.read(lockfile_path)
158
186
  for dep in lockfile.dependencies.values():
159
- # Orphan / source matching is host-blind: it compares against
160
- # the apm.yml-derived keys above and the host-blind apm_modules/
161
- # filesystem layout. get_unique_key() is the host-qualified
162
- # lockfile dedup key (#773) and must NOT be used here, or a
163
- # non-default-host dep never matches its installed directory
164
- # (it would be wrongly flagged orphaned and lose its Source).
165
- dep_key = dep.get_canonical_dependency_string()
187
+ # Match the host-blind apm_modules/ layout. Local dependency
188
+ # identity retains its source-relative path, so derive its key
189
+ # from the canonical install path instead.
190
+ if dep.source == "local":
191
+ install_path = dep.to_dependency_ref().get_install_path(apm_modules_path)
192
+ dep_key = install_path.relative_to(apm_modules_path).as_posix()
193
+ else:
194
+ dep_key = dep.get_canonical_dependency_string()
166
195
  if dep_key and dep_key not in declared_sources:
167
196
  declared_sources[dep_key] = _deps_list_source_label(
168
197
  dep.host,
@@ -490,7 +519,8 @@ def _build_dep_tree(apm_dir):
490
519
  'apm_modules_path': Path,
491
520
  'source': 'lockfile' | 'directory',
492
521
  'direct': [dep, ...], # lockfile mode only
493
- 'children_map': {url: [dep]}, # lockfile mode only
522
+ 'children_map': {unique_key: [dep]}, # lockfile mode only
523
+ 'unresolved': [dep, ...], # lockfile mode only
494
524
  'scanned_packages': [{...}], # directory fallback only
495
525
  'has_modules': bool,
496
526
  }
@@ -513,6 +543,7 @@ def _build_dep_tree(apm_dir):
513
543
  "source": "directory",
514
544
  "direct": [],
515
545
  "children_map": {},
546
+ "unresolved": [],
516
547
  "scanned_packages": [],
517
548
  "has_modules": apm_modules_path.exists(),
518
549
  }
@@ -531,12 +562,36 @@ def _build_dep_tree(apm_dir):
531
562
  result["direct"] = [d for d in lockfile_deps if d.depth <= 1]
532
563
  transitive = [d for d in lockfile_deps if d.depth > 1]
533
564
  children_map: dict[str, list] = {}
565
+ unresolved = []
566
+ parents_by_unique_key: dict[tuple[int, str], list] = {}
567
+ parents_by_repo_url: dict[tuple[int, str], list] = {}
568
+ for candidate in lockfile_deps:
569
+ parents_by_unique_key.setdefault(
570
+ (candidate.depth, candidate.get_unique_key()), []
571
+ ).append(candidate)
572
+ parents_by_repo_url.setdefault(
573
+ (candidate.depth, candidate.repo_url), []
574
+ ).append(candidate)
534
575
  for dep in transitive:
535
576
  parent_key = dep.resolved_by or ""
577
+ parent_depth = dep.depth - 1
578
+ parent_candidates = parents_by_unique_key.get(
579
+ (parent_depth, parent_key), []
580
+ )
581
+ if not parent_candidates:
582
+ parent_candidates = parents_by_repo_url.get(
583
+ (parent_depth, parent_key), []
584
+ )
585
+ if len(parent_candidates) == 1:
586
+ parent_key = parent_candidates[0].get_unique_key()
587
+ else:
588
+ unresolved.append(dep)
589
+ continue
536
590
  if parent_key not in children_map:
537
591
  children_map[parent_key] = []
538
592
  children_map[parent_key].append(dep)
539
593
  result["children_map"] = children_map
594
+ result["unresolved"] = unresolved
540
595
  return result
541
596
  except Exception:
542
597
  pass
@@ -609,6 +664,7 @@ def tree(global_):
609
664
  if tree_data["source"] == "lockfile":
610
665
  direct = tree_data["direct"]
611
666
  children_map = tree_data["children_map"]
667
+ unresolved = tree_data.get("unresolved", [])
612
668
 
613
669
  if has_rich:
614
670
  root_tree = Tree(f"[bold cyan]{project_name}[/bold cyan] (local)")
@@ -624,7 +680,13 @@ def tree(global_):
624
680
  prim_summary = _format_primitive_counts(_count_primitives(install_path))
625
681
  if prim_summary:
626
682
  branch.add(f"[dim]{prim_summary}[/dim]")
627
- _add_tree_children(branch, dep.repo_url, children_map, has_rich)
683
+ _add_tree_children(branch, dep.get_unique_key(), children_map, has_rich)
684
+ for dep in unresolved:
685
+ display = _dep_display_name(dep)
686
+ branch = root_tree.add(
687
+ f"[yellow]{display} (could not determine parent)[/yellow]"
688
+ )
689
+ _add_tree_children(branch, dep.get_unique_key(), children_map, has_rich)
628
690
  console.print(root_tree)
629
691
  else:
630
692
  click.echo(f"{project_name} (local)")
@@ -632,17 +694,18 @@ def tree(global_):
632
694
  click.echo("+-- No dependencies installed")
633
695
  else:
634
696
  for i, dep in enumerate(direct):
635
- is_last = i == len(direct) - 1
697
+ is_last = i == len(direct) - 1 and not unresolved
636
698
  prefix = "+-- " if is_last else "|-- "
637
699
  display = _dep_display_name(dep)
638
700
  click.echo(f"{prefix}{display}")
639
- # Show transitive deps
640
- kids = children_map.get(dep.repo_url, [])
641
701
  sub_prefix = " " if is_last else "| "
642
- for j, child in enumerate(kids):
643
- child_is_last = j == len(kids) - 1
644
- child_prefix = "+-- " if child_is_last else "|-- "
645
- click.echo(f"{sub_prefix}{child_prefix}{_dep_display_name(child)}")
702
+ _echo_tree_children(dep.get_unique_key(), children_map, sub_prefix)
703
+ for i, dep in enumerate(unresolved):
704
+ is_last = i == len(unresolved) - 1
705
+ prefix = "+-- " if is_last else "|-- "
706
+ click.echo(f"{prefix}{_dep_display_name(dep)} (could not determine parent)")
707
+ sub_prefix = " " if is_last else "| "
708
+ _echo_tree_children(dep.get_unique_key(), children_map, sub_prefix)
646
709
  # Fallback: scan apm_modules directory (no lockfile)
647
710
  elif has_rich:
648
711
  root_tree = Tree(f"[bold cyan]{project_name}[/bold cyan] (local)")
@@ -80,10 +80,10 @@ from apm_cli.install.services import (
80
80
 
81
81
  # Re-export validation leaf helpers so that existing test patches like
82
82
  # @patch("apm_cli.commands.install._validate_package_exists") keep working.
83
- # _validate_and_add_packages_to_apm_yml stays here (not moved) because it
84
- # calls _validate_package_exists and _local_path_failure_reason via module-
85
- # level name lookup -- keeping it co-located means @patch on this module
86
- # intercepts those calls without test changes.
83
+ # _validate_and_add_packages_to_apm_yml stays co-located (module lookup keeps @patch working).
84
+ from apm_cli.install.validation import (
85
+ _generic_host_ambiguous_subpath_hint as _ambiguous_subpath_hint,
86
+ )
87
87
  from apm_cli.install.validation import (
88
88
  _local_path_failure_reason,
89
89
  _local_path_no_markers_hint, # noqa: F401 -- re-exported; test_architecture_invariants checks importability
@@ -268,7 +268,9 @@ _APM_IMPORT_ERROR = None
268
268
  try:
269
269
  from ..deps.apm_resolver import APMDependencyResolver
270
270
  from ..deps.lockfile import LockFile, get_lockfile_path, migrate_lockfile_if_needed
271
- from ..integration.mcp_integrator import MCPIntegrator
271
+ from ..integration.mcp_integrator import (
272
+ MCPIntegrator, # noqa: F401 -- re-exported; tests patch commands.install.MCPIntegrator
273
+ )
272
274
  from ..models.apm_package import APMPackage, DependencyReference
273
275
 
274
276
  class _ScopedInstallDependencyResolver(APMDependencyResolver):
@@ -543,7 +545,7 @@ def _resolve_package_references(
543
545
  if marketplace_provenance:
544
546
  _marketplace_provenance[identity] = marketplace_provenance
545
547
  else:
546
- reason = _local_path_failure_reason(dep_ref)
548
+ reason = _local_path_failure_reason(dep_ref) or _ambiguous_subpath_hint(dep_ref)
547
549
  if not reason:
548
550
  # Round-4 panel fix (devx-ux): name the four-step probe
549
551
  # chain explicitly when the validator exhausted it
@@ -1739,11 +1741,13 @@ def _install_apm_packages(ctx, outcome):
1739
1741
  # field after the lockfile is regenerated by the APM install step.
1740
1742
  old_mcp_servers: builtins.set = builtins.set()
1741
1743
  old_mcp_configs: builtins.dict = {}
1744
+ old_mcp_provenance: builtins.dict = {}
1742
1745
  _lock_path = get_lockfile_path(ctx.apm_dir)
1743
1746
  _existing_lock = LockFile.read(_lock_path)
1744
1747
  if _existing_lock:
1745
1748
  old_mcp_servers = builtins.set(_existing_lock.mcp_servers)
1746
1749
  old_mcp_configs = builtins.dict(_existing_lock.mcp_configs)
1750
+ old_mcp_provenance = builtins.dict(_existing_lock.mcp_config_provenance)
1747
1751
 
1748
1752
  # Enter the APM install path when there are deps, local .apm/ primitives
1749
1753
  # (#714), OR orphan deps in the lockfile to clean up (manifest emptied).
@@ -1845,122 +1849,45 @@ def _install_apm_packages(ctx, outcome):
1845
1849
 
1846
1850
  clear_apm_yml_cache()
1847
1851
 
1848
- # Collect transitive MCP dependencies from resolved APM packages
1849
- transitive_mcp = []
1852
+ # -------------------------------------------------------------------------
1853
+ # MCP integration (extracted to install/mcp/integration.py)
1854
+ # -------------------------------------------------------------------------
1855
+ from apm_cli.install.mcp import run_mcp_integration
1856
+ from apm_cli.policy.install_preflight import PolicyBlockError
1857
+
1850
1858
  from ..core.scope import get_modules_dir
1851
1859
 
1852
1860
  apm_modules_path = get_modules_dir(ctx.scope)
1853
- if should_install_mcp and apm_modules_path.exists():
1854
- lock_path = get_lockfile_path(ctx.apm_dir)
1855
- transitive_mcp = MCPIntegrator.collect_transitive(
1856
- apm_modules_path,
1857
- lock_path,
1858
- ctx.trust_transitive_mcp,
1859
- diagnostics=apm_diagnostics,
1860
- )
1861
- if transitive_mcp:
1862
- logger.verbose_detail(f"Collected {len(transitive_mcp)} transitive MCP dependency(ies)")
1863
- mcp_deps = MCPIntegrator.deduplicate(mcp_deps + transitive_mcp)
1864
-
1865
- # allowExecutables MCP gate.
1866
- from ..security.executables import filter_mcp_by_allow_executables as _fmcp
1867
-
1868
- mcp_deps = _fmcp(mcp_deps, getattr(apm_package, "allow_executables", None), logger)
1869
-
1870
- # The pipeline gate phase (policy_gate.py) checks direct APM deps
1871
- # and direct MCP deps from apm.yml. However, transitive MCP
1872
- # servers (discovered via collect_transitive above) are only known
1873
- # after APM packages are installed. Run a second preflight
1874
- # against the *merged* MCP set (direct + transitive) BEFORE
1875
- # MCPIntegrator writes runtime configs. On PolicyBlockError we
1876
- # abort the MCP write but leave already-installed APM packages
1877
- # in place (they were approved by the gate phase).
1878
- if should_install_mcp and mcp_deps:
1879
- from apm_cli.policy.install_preflight import (
1880
- PolicyBlockError as _TransitivePBE,
1881
- )
1882
- from apm_cli.policy.install_preflight import (
1883
- run_policy_preflight as _transitive_preflight,
1884
- )
1885
-
1886
- try:
1887
- _transitive_preflight(
1888
- project_root=ctx.project_root,
1889
- mcp_deps=mcp_deps,
1890
- no_policy=ctx.no_policy,
1891
- logger=logger,
1892
- dry_run=False,
1893
- )
1894
- except _TransitivePBE:
1895
- logger.error(
1896
- "MCP server(s) blocked by org policy. "
1897
- "APM packages remain installed; MCP configs were NOT written."
1898
- )
1899
- logger.render_summary()
1900
- sys.exit(1)
1901
1861
 
1902
- mcp_count = 0
1903
- new_mcp_servers: builtins.set = builtins.set()
1904
- # Forward only the targets-key the user actually declared so parse_targets_field
1905
- # in the gate sees the same dict shape it sees from raw apm.yml. Including a
1906
- # `targets: None` placeholder when the user wrote `target:` (singular) would
1907
- # falsely trip the conflict-mutex check (see core.apm_yml.parse_targets_field).
1908
- # This restores parity with `apm install` for users on the modern `targets:`
1909
- # plural form -- without this, `targets:` was silently dropped at the call
1910
- # site and the gate fell back to permissive directory detection (#1335).
1911
- mcp_apm_config: dict = {"scripts": apm_package.scripts or {}}
1912
- if apm_package.targets is not None:
1913
- mcp_apm_config["targets"] = apm_package.targets
1914
- elif apm_package.target is not None:
1915
- mcp_apm_config["target"] = apm_package.target
1916
- if should_install_mcp and mcp_deps:
1917
- mcp_count = MCPIntegrator.install(
1918
- mcp_deps,
1919
- ctx.runtime,
1920
- ctx.exclude,
1921
- ctx.verbose,
1922
- stored_mcp_configs=old_mcp_configs,
1923
- apm_config=mcp_apm_config,
1862
+ try:
1863
+ mcp_count, mcp_apm_config = run_mcp_integration(
1864
+ apm_package=apm_package,
1865
+ mcp_deps=mcp_deps,
1866
+ apm_modules_path=apm_modules_path,
1867
+ lock_path=_lock_path,
1868
+ old_mcp_servers=old_mcp_servers,
1869
+ old_mcp_configs=old_mcp_configs,
1870
+ old_mcp_provenance=old_mcp_provenance,
1924
1871
  project_root=ctx.project_root,
1925
1872
  user_scope=(ctx.scope is InstallScope.USER),
1926
- explicit_target=ctx.target,
1873
+ should_install=should_install_mcp,
1874
+ logger=logger,
1927
1875
  diagnostics=apm_diagnostics,
1876
+ runtime=ctx.runtime,
1877
+ exclude=ctx.exclude,
1878
+ trust_transitive_mcp=ctx.trust_transitive_mcp,
1879
+ no_policy=ctx.no_policy,
1880
+ verbose=ctx.verbose,
1881
+ explicit_target=ctx.target,
1928
1882
  scope=ctx.scope,
1929
1883
  )
1930
- new_mcp_servers = MCPIntegrator.get_server_names(mcp_deps)
1931
- new_mcp_configs = MCPIntegrator.get_server_configs(mcp_deps)
1932
-
1933
- # Remove stale MCP servers that are no longer needed
1934
- stale_servers = old_mcp_servers - new_mcp_servers
1935
- if stale_servers:
1936
- MCPIntegrator.remove_stale(
1937
- stale_servers,
1938
- ctx.runtime,
1939
- ctx.exclude,
1940
- project_root=ctx.project_root,
1941
- user_scope=(ctx.scope is InstallScope.USER),
1942
- scope=ctx.scope,
1943
- )
1944
-
1945
- # Persist the new MCP server set and configs in the lockfile
1946
- MCPIntegrator.update_lockfile(new_mcp_servers, _lock_path, mcp_configs=new_mcp_configs)
1947
- elif should_install_mcp and not mcp_deps:
1948
- # No MCP deps at all -- remove any old APM-managed servers
1949
- if old_mcp_servers:
1950
- MCPIntegrator.remove_stale(
1951
- old_mcp_servers,
1952
- ctx.runtime,
1953
- ctx.exclude,
1954
- project_root=ctx.project_root,
1955
- user_scope=(ctx.scope is InstallScope.USER),
1956
- scope=ctx.scope,
1957
- )
1958
- MCPIntegrator.update_lockfile(builtins.set(), _lock_path, mcp_configs={})
1959
- logger.verbose_detail("No MCP dependencies found in apm.yml")
1960
- elif not should_install_mcp and old_mcp_servers:
1961
- # --only=apm: APM install regenerated the lockfile and dropped
1962
- # mcp_servers. Restore the previous set so it is not lost.
1963
- MCPIntegrator.update_lockfile(old_mcp_servers, _lock_path, mcp_configs=old_mcp_configs)
1884
+ except PolicyBlockError:
1885
+ logger.error(
1886
+ "MCP server(s) blocked by org policy. "
1887
+ "APM packages remain installed; MCP configs were NOT written."
1888
+ )
1889
+ logger.render_summary()
1890
+ sys.exit(1)
1964
1891
 
1965
1892
  # -------------------------------------------------------------------------
1966
1893
  # LSP integration (extracted to install/lsp/integration.py)
@@ -52,7 +52,7 @@ def prune(ctx, dry_run):
52
52
  # Build expected vs installed using shared helpers
53
53
  try:
54
54
  apm_package = APMPackage.from_apm_yml(Path(APM_YML_FILENAME))
55
- declared_deps = apm_package.get_apm_dependencies()
55
+ declared_deps = apm_package.get_all_apm_dependencies()
56
56
  lockfile = LockFile.read(get_lockfile_path(Path.cwd()))
57
57
  expected_installed = _build_expected_install_paths(
58
58
  declared_deps, lockfile, apm_modules_dir
@@ -17,6 +17,7 @@ import click
17
17
 
18
18
  from ..core.command_logger import CommandLogger
19
19
  from ..deps.registry.feature_gate import require_package_registry_enabled
20
+ from ..models.dependency.identity import normalize_package_repo_url
20
21
  from ..utils.paths import portable_relpath
21
22
 
22
23
  _PUBLISH_HELP = """\
@@ -161,7 +162,12 @@ def _resolve_package_id(package_id: str) -> tuple[str, str]:
161
162
  raw = re.sub(r"^https?://[^/]+/", "", package_id).strip("/")
162
163
  parts = [p for p in raw.split("/") if p]
163
164
  if len(parts) >= 2:
164
- return parts[-2], parts[-1]
165
+ canonical = normalize_package_repo_url(
166
+ "/".join(parts[-2:]),
167
+ source="registry",
168
+ )
169
+ owner, repo = canonical.split("/", 1)
170
+ return owner, repo
165
171
  raise click.UsageError(
166
172
  f"--package must be in owner/repo form (got {package_id!r}).\n"
167
173
  "Example: --package acme/my-skill"