apm-cli 0.27.0__tar.gz → 0.28.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 (462) hide show
  1. {apm_cli-0.27.0/src/apm_cli.egg-info → apm_cli-0.28.0}/PKG-INFO +3 -3
  2. {apm_cli-0.27.0 → apm_cli-0.28.0}/README.md +2 -2
  3. {apm_cli-0.27.0 → apm_cli-0.28.0}/pyproject.toml +1 -1
  4. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/base.py +89 -0
  5. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/vscode.py +108 -82
  6. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/bundle/lockfile_enrichment.py +17 -13
  7. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/_helpers.py +5 -16
  8. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/deps/cli.py +2 -1
  9. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/init.py +19 -6
  10. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/install.py +35 -43
  11. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/audit.py +27 -5
  12. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/plugin/__init__.py +5 -3
  13. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/plugin/add.py +11 -3
  14. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/outdated.py +9 -2
  15. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/pack.py +38 -10
  16. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/uninstall/engine.py +25 -17
  17. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/context_optimizer.py +186 -82
  18. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/distributed_compiler.py +43 -32
  19. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/build_orchestrator.py +9 -11
  20. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/experimental.py +6 -0
  21. apm_cli-0.28.0/src/apm_cli/core/project_name.py +19 -0
  22. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/script_runner.py +2 -1
  23. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/target_catalog.py +14 -0
  24. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/target_detection.py +23 -5
  25. apm_cli-0.28.0/src/apm_cli/install/argv.py +34 -0
  26. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/local_bundle_handler.py +12 -0
  27. apm_cli-0.28.0/src/apm_cli/install/local_bundle_paths.py +89 -0
  28. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/package_resolution.py +96 -6
  29. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/_skip_logic.py +13 -2
  30. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/integrate.py +1 -0
  31. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/targets.py +23 -37
  32. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/services.py +24 -41
  33. apm_cli-0.28.0/src/apm_cli/install/target_hints.py +53 -0
  34. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/agent_integrator.py +259 -18
  35. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/hook_integrator.py +52 -39
  36. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/instruction_integrator.py +16 -16
  37. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/mcp_integrator_install.py +24 -0
  38. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/targets.py +36 -2
  39. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/audit.py +48 -3
  40. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/builder.py +18 -9
  41. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/drift_check.py +12 -18
  42. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/output_profiles.py +39 -0
  43. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/resolver.py +32 -10
  44. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/version_check.py +91 -11
  45. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/yml_schema.py +11 -10
  46. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/reference.py +21 -90
  47. apm_cli-0.28.0/src/apm_cli/models/dependency/registry_entry.py +119 -0
  48. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/discovery.py +3 -22
  49. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/primitives/parser.py +3 -29
  50. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/registry/operations.py +43 -9
  51. apm_cli-0.28.0/src/apm_cli/utils/patterns.py +185 -0
  52. {apm_cli-0.27.0 → apm_cli-0.28.0/src/apm_cli.egg-info}/PKG-INFO +3 -3
  53. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli.egg-info/SOURCES.txt +5 -0
  54. apm_cli-0.27.0/src/apm_cli/utils/patterns.py +0 -91
  55. {apm_cli-0.27.0 → apm_cli-0.28.0}/AUTHORS +0 -0
  56. {apm_cli-0.27.0 → apm_cli-0.28.0}/LICENSE +0 -0
  57. {apm_cli-0.27.0 → apm_cli-0.28.0}/NOTICE +0 -0
  58. {apm_cli-0.27.0 → apm_cli-0.28.0}/setup.cfg +0 -0
  59. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/__init__.py +0 -0
  60. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/__init__.py +0 -0
  61. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/__init__.py +0 -0
  62. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
  63. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/antigravity.py +0 -0
  64. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/claude.py +0 -0
  65. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/codex.py +0 -0
  66. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/copilot.py +0 -0
  67. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/cursor.py +0 -0
  68. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/gemini.py +0 -0
  69. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/hermes.py +0 -0
  70. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/intellij.py +0 -0
  71. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/kiro.py +0 -0
  72. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/opencode.py +0 -0
  73. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/client/windsurf.py +0 -0
  74. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
  75. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/package_manager/base.py +0 -0
  76. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
  77. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/bootstrap_mirror.py +0 -0
  78. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/bundle/__init__.py +0 -0
  79. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/bundle/attest.py +0 -0
  80. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/bundle/local_bundle.py +0 -0
  81. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/bundle/packer.py +0 -0
  82. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/bundle/plugin_exporter.py +0 -0
  83. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/bundle/plugin_layout.py +0 -0
  84. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/bundle/unpacker.py +0 -0
  85. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/cache/__init__.py +0 -0
  86. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/cache/git_cache.py +0 -0
  87. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/cache/http_cache.py +0 -0
  88. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/cache/integrity.py +0 -0
  89. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/cache/locking.py +0 -0
  90. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/cache/paths.py +0 -0
  91. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/cache/url_normalize.py +0 -0
  92. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/cli.py +0 -0
  93. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/__init__.py +0 -0
  94. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/_apm_yml_writer.py +0 -0
  95. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/approve.py +0 -0
  96. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/audit.py +0 -0
  97. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/cache.py +0 -0
  98. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/compile/__init__.py +0 -0
  99. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/compile/cli.py +0 -0
  100. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/compile/watcher.py +0 -0
  101. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/config.py +0 -0
  102. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/deps/__init__.py +0 -0
  103. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/deps/_utils.py +0 -0
  104. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/deps/why.py +0 -0
  105. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/doctor.py +0 -0
  106. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/experimental.py +0 -0
  107. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/find.py +0 -0
  108. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/lifecycle.py +0 -0
  109. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/list_cmd.py +0 -0
  110. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/lock.py +0 -0
  111. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/__init__.py +0 -0
  112. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/check.py +0 -0
  113. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/doctor.py +0 -0
  114. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/init.py +0 -0
  115. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/migrate.py +0 -0
  116. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/outdated.py +0 -0
  117. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/plugin/remove.py +0 -0
  118. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
  119. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/marketplace/validate.py +0 -0
  120. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/mcp.py +0 -0
  121. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/plugin/__init__.py +0 -0
  122. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/plugin/init.py +0 -0
  123. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/policy.py +0 -0
  124. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/prune.py +0 -0
  125. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/publish.py +0 -0
  126. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/run.py +0 -0
  127. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/runtime.py +0 -0
  128. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/self_update.py +0 -0
  129. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/targets.py +0 -0
  130. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/uninstall/__init__.py +0 -0
  131. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/uninstall/cli.py +0 -0
  132. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/uninstall/lockfile_state.py +0 -0
  133. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/update.py +0 -0
  134. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/commands/view.py +0 -0
  135. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/__init__.py +0 -0
  136. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/agents_compiler.py +0 -0
  137. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/build_id.py +0 -0
  138. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/claude_formatter.py +0 -0
  139. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/constants.py +0 -0
  140. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/constitution.py +0 -0
  141. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/constitution_block.py +0 -0
  142. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/gemini_formatter.py +0 -0
  143. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/injector.py +0 -0
  144. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/link_resolver.py +0 -0
  145. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/managed_section.py +0 -0
  146. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/output_writer.py +0 -0
  147. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/template_builder.py +0 -0
  148. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/compilation/user_root_context.py +0 -0
  149. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/config.py +0 -0
  150. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/constants.py +0 -0
  151. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/__init__.py +0 -0
  152. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/_child_tls/__init__.py +0 -0
  153. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/_child_tls/_apm_tls.pth +0 -0
  154. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/_child_tls/_apm_tls_bootstrap.py +0 -0
  155. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/apm_yml.py +0 -0
  156. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/auth.py +0 -0
  157. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/azure_cli.py +0 -0
  158. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/command_logger.py +0 -0
  159. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/conflict_detector.py +0 -0
  160. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/deployment_ledger.py +0 -0
  161. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/deployment_state.py +0 -0
  162. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/docker_args.py +0 -0
  163. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/errors.py +0 -0
  164. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/host_providers.py +0 -0
  165. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/install_audit.py +0 -0
  166. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/lifecycle_scripts.py +0 -0
  167. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/null_logger.py +0 -0
  168. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/operations.py +0 -0
  169. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/output_mode.py +0 -0
  170. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/plugin_manifest.py +0 -0
  171. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/safe_installer.py +0 -0
  172. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/scope.py +0 -0
  173. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/script_executors.py +0 -0
  174. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/script_trust.py +0 -0
  175. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/tls_trust.py +0 -0
  176. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/core/token_manager.py +0 -0
  177. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/__init__.py +0 -0
  178. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/_shared.py +0 -0
  179. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/aggregator.py +0 -0
  180. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/apm_resolver.py +0 -0
  181. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/artifactory_entry.py +0 -0
  182. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
  183. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/bare_cache.py +0 -0
  184. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/clone_engine.py +0 -0
  185. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/dependency_graph.py +0 -0
  186. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/download_strategies.py +0 -0
  187. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/git_auth_env.py +0 -0
  188. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/git_file_transport.py +0 -0
  189. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/git_reference_resolver.py +0 -0
  190. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/git_remote_ops.py +0 -0
  191. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/git_semver_resolver.py +0 -0
  192. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/github_downloader.py +0 -0
  193. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/github_downloader_validation.py +0 -0
  194. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/github_rate_limit.py +0 -0
  195. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/host_backends.py +0 -0
  196. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/installed_package.py +0 -0
  197. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/lockfile.py +0 -0
  198. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/outdated_ref_cache.py +0 -0
  199. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/outdated_row.py +0 -0
  200. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/package_validator.py +0 -0
  201. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/path_anchoring.py +0 -0
  202. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/plugin_parser.py +0 -0
  203. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/reachability.py +0 -0
  204. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/registry/__init__.py +0 -0
  205. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/registry/auth.py +0 -0
  206. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/registry/client.py +0 -0
  207. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/registry/config_loader.py +0 -0
  208. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/registry/extractor.py +0 -0
  209. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/registry/feature_gate.py +0 -0
  210. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/registry/outdated.py +0 -0
  211. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/registry/resolver.py +0 -0
  212. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/registry/semver.py +0 -0
  213. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/registry_proxy.py +0 -0
  214. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/revision_pins.py +0 -0
  215. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/shared_clone_cache.py +0 -0
  216. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/tiered_ref_resolver.py +0 -0
  217. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/transport_selection.py +0 -0
  218. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/verifier.py +0 -0
  219. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/deps/why_walker.py +0 -0
  220. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/drift.py +0 -0
  221. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/export/__init__.py +0 -0
  222. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/export/authoring.py +0 -0
  223. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/export/declared_license.py +0 -0
  224. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/export/formats.py +0 -0
  225. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/export/purl.py +0 -0
  226. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/export/sbom.py +0 -0
  227. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/export/spdx.py +0 -0
  228. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/export/spdx_data.py +0 -0
  229. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/factory.py +0 -0
  230. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/__init__.py +0 -0
  231. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/artifactory_resolver.py +0 -0
  232. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/audit_replay.py +0 -0
  233. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/cache_pin.py +0 -0
  234. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/context.py +0 -0
  235. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/deployed_paths.py +0 -0
  236. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/drift.py +0 -0
  237. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/drift_render.py +0 -0
  238. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/errors.py +0 -0
  239. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/exec_gate.py +0 -0
  240. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/gitlab_resolver.py +0 -0
  241. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/heals/__init__.py +0 -0
  242. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/heals/base.py +0 -0
  243. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
  244. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
  245. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/helpers/__init__.py +0 -0
  246. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/helpers/no_work.py +0 -0
  247. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/helpers/ref_reuse.py +0 -0
  248. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/helpers/ref_seed.py +0 -0
  249. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/helpers/security_scan.py +0 -0
  250. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/insecure_policy.py +0 -0
  251. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/integrity.py +0 -0
  252. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/lsp/__init__.py +0 -0
  253. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/lsp/integration.py +0 -0
  254. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/manifest_reconcile.py +0 -0
  255. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/mcp/__init__.py +0 -0
  256. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/mcp/args.py +0 -0
  257. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/mcp/command.py +0 -0
  258. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/mcp/conflicts.py +0 -0
  259. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/mcp/entry.py +0 -0
  260. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/mcp/integration.py +0 -0
  261. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/mcp/ownership.py +0 -0
  262. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/mcp/registry.py +0 -0
  263. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/mcp/warnings.py +0 -0
  264. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/mcp/writer.py +0 -0
  265. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/outcome.py +0 -0
  266. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/package_selection.py +0 -0
  267. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/__init__.py +0 -0
  268. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/_redownload.py +0 -0
  269. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/audit.py +0 -0
  270. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/cleanup.py +0 -0
  271. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/download.py +0 -0
  272. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/finalize.py +0 -0
  273. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/heal.py +0 -0
  274. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/local_content.py +0 -0
  275. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/lockfile.py +0 -0
  276. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/policy_gate.py +0 -0
  277. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/policy_target_check.py +0 -0
  278. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/post_deps_local.py +0 -0
  279. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/phases/resolve.py +0 -0
  280. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/pipeline.py +0 -0
  281. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/plan.py +0 -0
  282. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/presentation/__init__.py +0 -0
  283. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/presentation/dry_run.py +0 -0
  284. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/registry_wiring.py +0 -0
  285. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/request.py +0 -0
  286. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/resolution_staging.py +0 -0
  287. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/root_redirect.py +0 -0
  288. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/service.py +0 -0
  289. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/service_integration.py +0 -0
  290. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/skill_path_migration.py +0 -0
  291. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/sources.py +0 -0
  292. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/summary.py +0 -0
  293. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/target_filter.py +0 -0
  294. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/target_warnings.py +0 -0
  295. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/template.py +0 -0
  296. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/transaction.py +0 -0
  297. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/install/validation.py +0 -0
  298. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/__init__.py +0 -0
  299. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/_hook_dropped_targets.py +0 -0
  300. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/_shared.py +0 -0
  301. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/base_integrator.py +0 -0
  302. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/canvas_integrator.py +0 -0
  303. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/cleanup.py +0 -0
  304. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/command_integrator.py +0 -0
  305. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/copilot_app_db.py +0 -0
  306. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/copilot_app_project.py +0 -0
  307. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/copilot_app_workflow_integrator.py +0 -0
  308. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/copilot_app_ws.py +0 -0
  309. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
  310. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/coverage.py +0 -0
  311. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/dispatch.py +0 -0
  312. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/hook_bundle.py +0 -0
  313. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/hook_file_routing.py +0 -0
  314. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/hook_ir.py +0 -0
  315. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/hook_native_formats.py +0 -0
  316. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/hook_ownership.py +0 -0
  317. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/kiro_hook_integrator.py +0 -0
  318. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/lsp_integrator.py +0 -0
  319. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/mcp_config_view.py +0 -0
  320. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/mcp_integrator.py +0 -0
  321. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
  322. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/prompt_integrator.py +0 -0
  323. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/skill_integrator.py +0 -0
  324. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/skill_transformer.py +0 -0
  325. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/integration/utils.py +0 -0
  326. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/__init__.py +0 -0
  327. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/_git_utils.py +0 -0
  328. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/_io.py +0 -0
  329. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/_shared.py +0 -0
  330. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/auth_helpers.py +0 -0
  331. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/client.py +0 -0
  332. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/diagnostics.py +0 -0
  333. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/errors.py +0 -0
  334. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/git_stderr.py +0 -0
  335. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/init_template.py +0 -0
  336. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/migration.py +0 -0
  337. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/models.py +0 -0
  338. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/output_mappers.py +0 -0
  339. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/ref_resolver.py +0 -0
  340. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/registry.py +0 -0
  341. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/semver.py +0 -0
  342. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/shadow_detector.py +0 -0
  343. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/tag_pattern.py +0 -0
  344. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/validator.py +0 -0
  345. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/version_pins.py +0 -0
  346. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/version_resolver.py +0 -0
  347. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/marketplace/yml_editor.py +0 -0
  348. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/__init__.py +0 -0
  349. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/apm_package.py +0 -0
  350. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/__init__.py +0 -0
  351. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/identity.py +0 -0
  352. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/lsp.py +0 -0
  353. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/materialization.py +0 -0
  354. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/mcp.py +0 -0
  355. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/object_fields.py +0 -0
  356. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/provider_coordinates.py +0 -0
  357. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/selection.py +0 -0
  358. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/subsets.py +0 -0
  359. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/dependency/types.py +0 -0
  360. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/format_detection.py +0 -0
  361. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/manifest_contract.py +0 -0
  362. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/plugin.py +0 -0
  363. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/results.py +0 -0
  364. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/models/validation.py +0 -0
  365. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/output/__init__.py +0 -0
  366. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/output/formatters.py +0 -0
  367. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/output/models.py +0 -0
  368. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/output/script_formatters.py +0 -0
  369. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/__init__.py +0 -0
  370. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/_constraint_pinning.py +0 -0
  371. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/_help_text.py +0 -0
  372. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/_shared.py +0 -0
  373. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/ci_checks.py +0 -0
  374. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/inheritance.py +0 -0
  375. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/install_preflight.py +0 -0
  376. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/matcher.py +0 -0
  377. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/models.py +0 -0
  378. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/outcome_routing.py +0 -0
  379. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/parser.py +0 -0
  380. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/policy_checks.py +0 -0
  381. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/project_config.py +0 -0
  382. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/policy/schema.py +0 -0
  383. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/primitives/__init__.py +0 -0
  384. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/primitives/discovery.py +0 -0
  385. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/primitives/models.py +0 -0
  386. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/registry/__init__.py +0 -0
  387. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/registry/client.py +0 -0
  388. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/registry/integration.py +0 -0
  389. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/runtime/__init__.py +0 -0
  390. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/runtime/base.py +0 -0
  391. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/runtime/codex_runtime.py +0 -0
  392. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/runtime/copilot_runtime.py +0 -0
  393. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/runtime/factory.py +0 -0
  394. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/runtime/llm_runtime.py +0 -0
  395. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/runtime/manager.py +0 -0
  396. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/runtime/registry.py +0 -0
  397. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/runtime/utils.py +0 -0
  398. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/__init__.py +0 -0
  399. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/audit_report.py +0 -0
  400. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/content_scanner.py +0 -0
  401. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/executables.py +0 -0
  402. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/external/__init__.py +0 -0
  403. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/external/base.py +0 -0
  404. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/external/gate.py +0 -0
  405. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/external/generic_sarif.py +0 -0
  406. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/external/options.py +0 -0
  407. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/external/registry.py +0 -0
  408. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/external/runner.py +0 -0
  409. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/external/sarif_ingest.py +0 -0
  410. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/external/skillspector.py +0 -0
  411. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/file_scanner.py +0 -0
  412. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/security/gate.py +0 -0
  413. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/update_policy.py +0 -0
  414. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/__init__.py +0 -0
  415. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/archive.py +0 -0
  416. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/atomic_io.py +0 -0
  417. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/console.py +0 -0
  418. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/content_hash.py +0 -0
  419. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/diagnostics.py +0 -0
  420. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/exclude.py +0 -0
  421. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/file_ops.py +0 -0
  422. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/git_env.py +0 -0
  423. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/git_sparse.py +0 -0
  424. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/github_host.py +0 -0
  425. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/guards.py +0 -0
  426. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/helpers.py +0 -0
  427. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/install_tui.py +0 -0
  428. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/normalization.py +0 -0
  429. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/path_security.py +0 -0
  430. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/paths.py +0 -0
  431. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/perf_stats.py +0 -0
  432. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/reflink.py +0 -0
  433. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/short_sha.py +0 -0
  434. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/subprocess_env.py +0 -0
  435. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/version_checker.py +0 -0
  436. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/utils/yaml_io.py +0 -0
  437. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/version.py +0 -0
  438. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/workflow/__init__.py +0 -0
  439. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/workflow/discovery.py +0 -0
  440. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/workflow/parser.py +0 -0
  441. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli/workflow/runner.py +0 -0
  442. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli.egg-info/dependency_links.txt +0 -0
  443. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli.egg-info/entry_points.txt +0 -0
  444. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli.egg-info/requires.txt +0 -0
  445. {apm_cli-0.27.0 → apm_cli-0.28.0}/src/apm_cli.egg-info/top_level.txt +0 -0
  446. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_apm_package_models.py +0 -0
  447. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_apm_resolver.py +0 -0
  448. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_codex_docker_args_fix.py +0 -0
  449. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_codex_empty_string_and_defaults.py +0 -0
  450. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_collision_integration.py +0 -0
  451. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_console.py +0 -0
  452. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_distributed_compilation.py +0 -0
  453. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_empty_string_and_defaults.py +0 -0
  454. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_enhanced_discovery.py +0 -0
  455. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_github_downloader.py +0 -0
  456. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_github_downloader_token_precedence.py +0 -0
  457. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_gitlab_git_transport.py +0 -0
  458. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_lockfile.py +0 -0
  459. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_runnable_prompts.py +0 -0
  460. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_runtime_manager_token_precedence.py +0 -0
  461. {apm_cli-0.27.0 → apm_cli-0.28.0}/tests/test_token_manager.py +0 -0
  462. {apm_cli-0.27.0 → apm_cli-0.28.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.27.0
3
+ Version: 0.28.0
4
4
  Summary: MCP configuration tool
5
5
  Author-email: Daniel Meppiel <user@example.com>
6
6
  License: MIT License
@@ -76,7 +76,7 @@ Dynamic: license-file
76
76
 
77
77
  Think `package.json`, `requirements.txt`, or `Cargo.toml` — but for AI agent configuration.
78
78
 
79
- GitHub Copilot · Claude Code · Cursor · OpenCode · Codex · Gemini · Windsurf · Kiro
79
+ GitHub Copilot | Claude Code | Grok Build | Cursor | OpenCode | Codex | Gemini | Windsurf | Kiro
80
80
 
81
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)**
82
82
 
@@ -139,7 +139,7 @@ One command, no configuration -- VS Code and GitHub Copilot read the file automa
139
139
 
140
140
  One `apm.yml` describes every primitive your agents need — instructions, skills, prompts, agents, hooks, plugins, MCP servers — and `apm install` reproduces the exact same setup across every client on every machine. `apm.lock.yaml` pins the resolved tree the way `package-lock.json` does for npm.
141
141
 
142
- - **[One manifest for everything](https://microsoft.github.io/apm/reference/primitive-types/)** — declared once, deployed across Copilot, Claude, Cursor, OpenCode, Codex, Gemini, Windsurf, Kiro
142
+ - **[One manifest for everything](https://microsoft.github.io/apm/reference/primitive-types/)** -- declared once, deployed across Copilot, Claude, Grok Build, Cursor, OpenCode, Codex, Gemini, Windsurf, Kiro
143
143
  - **[Install from anywhere](https://microsoft.github.io/apm/guides/dependencies/)** — GitHub, GitLab, Bitbucket, Azure DevOps, GitHub Enterprise, Gitea, Gogs, any git host
144
144
  - **[Transitive dependencies](https://microsoft.github.io/apm/guides/dependencies/)** — packages can depend on packages; APM resolves the full tree
145
145
  - **[Author plugins](https://microsoft.github.io/apm/guides/plugins/)** — build Copilot, Claude, and Cursor plugins with dependency management, then export standard `plugin.json`
@@ -4,7 +4,7 @@
4
4
 
5
5
  Think `package.json`, `requirements.txt`, or `Cargo.toml` — but for AI agent configuration.
6
6
 
7
- GitHub Copilot · Claude Code · Cursor · OpenCode · Codex · Gemini · Windsurf · Kiro
7
+ GitHub Copilot | Claude Code | Grok Build | Cursor | OpenCode | Codex | Gemini | Windsurf | Kiro
8
8
 
9
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)**
10
10
 
@@ -67,7 +67,7 @@ One command, no configuration -- VS Code and GitHub Copilot read the file automa
67
67
 
68
68
  One `apm.yml` describes every primitive your agents need — instructions, skills, prompts, agents, hooks, plugins, MCP servers — and `apm install` reproduces the exact same setup across every client on every machine. `apm.lock.yaml` pins the resolved tree the way `package-lock.json` does for npm.
69
69
 
70
- - **[One manifest for everything](https://microsoft.github.io/apm/reference/primitive-types/)** — declared once, deployed across Copilot, Claude, Cursor, OpenCode, Codex, Gemini, Windsurf, Kiro
70
+ - **[One manifest for everything](https://microsoft.github.io/apm/reference/primitive-types/)** -- declared once, deployed across Copilot, Claude, Grok Build, Cursor, OpenCode, Codex, Gemini, Windsurf, Kiro
71
71
  - **[Install from anywhere](https://microsoft.github.io/apm/guides/dependencies/)** — GitHub, GitLab, Bitbucket, Azure DevOps, GitHub Enterprise, Gitea, Gogs, any git host
72
72
  - **[Transitive dependencies](https://microsoft.github.io/apm/guides/dependencies/)** — packages can depend on packages; APM resolves the full tree
73
73
  - **[Author plugins](https://microsoft.github.io/apm/guides/plugins/)** — build Copilot, Claude, and Cursor plugins with dependency management, then export standard `plugin.json`
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "apm-cli"
7
- version = "0.27.0"
7
+ version = "0.28.0"
8
8
  description = "MCP configuration tool"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -29,6 +29,7 @@ _ENV_PLACEHOLDER_RE = re.compile(r"<([A-Z_][A-Z0-9_]*)>|" + _ENV_VAR_RE.pattern)
29
29
  # Detects the legacy ``<VAR>`` placeholder syntax only. Used to aggregate
30
30
  # deprecation warnings across all servers in a single install run.
31
31
  _LEGACY_ANGLE_VAR_RE = re.compile(r"<([A-Z_][A-Z0-9_]*)>")
32
+ _RUNTIME_TEMPLATE_VARIABLE_RE = re.compile(r"(?<!\$)\{([a-zA-Z_][a-zA-Z0-9_]*)\}")
32
33
 
33
34
  # MCP Registry v0.1 names the container registry type ``oci``; the adapters
34
35
  # below key their launcher dispatch on ``docker`` (the vocabulary the legacy
@@ -656,6 +657,94 @@ class MCPClientAdapter(ABC):
656
657
  None,
657
658
  )
658
659
 
660
+ @staticmethod
661
+ def _package_runtime_variable_metadata(
662
+ package: dict[str, Any] | None,
663
+ ) -> dict[str, dict] | None:
664
+ """Return one validated runtime-variable declaration map for a package.
665
+
666
+ Registry metadata may declare a variable on one argument and reference it
667
+ later without repeating the declaration. Keeping this map package-scoped
668
+ makes those references resolve consistently while rejecting malformed
669
+ secret metadata before an adapter can render a collected value.
670
+ """
671
+ metadata_by_name: dict[str, dict] = {}
672
+ for field_name in ("runtime_arguments", "package_arguments"):
673
+ for argument in (package or {}).get(field_name) or []:
674
+ if not isinstance(argument, dict):
675
+ continue
676
+ variables = argument.get("variables")
677
+ if variables is None:
678
+ continue
679
+ if not isinstance(variables, dict):
680
+ return None
681
+ for name, metadata in variables.items():
682
+ if not isinstance(name, str) or not isinstance(metadata, dict):
683
+ return None
684
+ secret_marker = metadata.get("isSecret", metadata.get("is_secret", False))
685
+ if not isinstance(secret_marker, bool):
686
+ return None
687
+ existing = metadata_by_name.get(name)
688
+ if existing is not None and existing != metadata:
689
+ return None
690
+ metadata_by_name[name] = metadata
691
+ return metadata_by_name
692
+
693
+ @staticmethod
694
+ def _substitute_runtime_variables(
695
+ template: str,
696
+ variables: dict[object, object] | None,
697
+ runtime_vars: dict[str, object] | None,
698
+ runtime_variable_fallbacks: dict[str, str] | None = None,
699
+ secret_variable_fallbacks: dict[str, str] | None = None,
700
+ ) -> str | None:
701
+ """Resolve every APM runtime variable in one registry argument template.
702
+
703
+ Variable metadata may appear on an earlier argument while later
704
+ arguments reference the same value. Collected values therefore apply to
705
+ every template, not only the metadata-bearing entry. Target-specific
706
+ fallbacks are used only for declared variables with no collected value.
707
+ """
708
+ secret_fallbacks = secret_variable_fallbacks or {}
709
+ values: dict[str, str] = dict(secret_fallbacks)
710
+ for name, value in (runtime_vars or {}).items():
711
+ if (
712
+ isinstance(name, str)
713
+ and name not in secret_fallbacks
714
+ and value is not None
715
+ and str(value) != ""
716
+ ):
717
+ values[name] = str(value)
718
+
719
+ fallbacks = runtime_variable_fallbacks or {}
720
+ for name, metadata in (variables or {}).items():
721
+ if not isinstance(name, str) or not isinstance(metadata, dict):
722
+ return None
723
+ placeholder = f"{{{name}}}"
724
+ if placeholder not in template or name in values:
725
+ continue
726
+ secret_marker = metadata.get("isSecret", metadata.get("is_secret", False))
727
+ if not isinstance(secret_marker, bool):
728
+ return None
729
+ if secret_marker is True:
730
+ return None
731
+ fallback = fallbacks.get(name)
732
+ if fallback is not None:
733
+ values[name] = fallback
734
+ continue
735
+ configured = metadata.get("value", metadata.get("default"))
736
+ if isinstance(configured, str) and configured:
737
+ values[name] = configured
738
+ elif configured is not None:
739
+ return None
740
+
741
+ for name, value in values.items():
742
+ template = template.replace(f"{{{name}}}", value)
743
+
744
+ if _RUNTIME_TEMPLATE_VARIABLE_RE.search(template):
745
+ return None
746
+ return template
747
+
659
748
  @staticmethod
660
749
  def _processed_non_container_argument_groups(
661
750
  arguments: list[object],
@@ -5,6 +5,7 @@ following the official documentation at:
5
5
  https://code.visualstudio.com/docs/copilot/chat/mcp-servers
6
6
  """
7
7
 
8
+ import hashlib
8
9
  import json
9
10
  import re
10
11
  from pathlib import Path
@@ -13,7 +14,13 @@ from ...core.docker_args import DockerArgsProcessor
13
14
  from ...registry.client import SimpleRegistryClient
14
15
  from ...registry.integration import RegistryIntegration
15
16
  from ...utils.console import _rich_warning
16
- from .base import _ENV_VAR_RE, _INPUT_VAR_RE, MCPClientAdapter, registry_field_is_required
17
+ from .base import (
18
+ _ENV_VAR_RE,
19
+ _INPUT_VAR_RE,
20
+ _RUNTIME_TEMPLATE_VARIABLE_RE,
21
+ MCPClientAdapter,
22
+ registry_field_is_required,
23
+ )
17
24
 
18
25
  # Legacy ``<VAR>`` placeholder (Copilot CLI / Codex only). VS Code does not
19
26
  # resolve angle-bracket placeholders, so emitting them produces literal
@@ -298,7 +305,8 @@ class VSCodeClientAdapter(MCPClientAdapter):
298
305
  existing_server_config=existing_server_config,
299
306
  )
300
307
  secret_fallbacks, argument_inputs = self._declared_vscode_argument_secret_inputs(
301
- package
308
+ package,
309
+ server_name=server_info.get("name", ""),
302
310
  )
303
311
  seen_input_ids = {item.get("id") for item in input_vars}
304
312
  for input_definition in (*declared_inputs, *argument_inputs):
@@ -342,19 +350,29 @@ class VSCodeClientAdapter(MCPClientAdapter):
342
350
 
343
351
  # Handle docker packages
344
352
  elif is_docker:
345
- args = self._docker_run_args(package, runtime_vars)
353
+ docker_kwargs = (
354
+ {"secret_variable_fallbacks": secret_fallbacks} if secret_fallbacks else {}
355
+ )
356
+ unresolved_variables: list[str] = []
357
+ args = self._docker_run_args(
358
+ package,
359
+ runtime_vars,
360
+ unresolved_variables=unresolved_variables,
361
+ **docker_kwargs,
362
+ )
346
363
  if args is None:
347
364
  if package.get("runtime_arguments") or package.get("package_arguments"):
365
+ variable_name = (
366
+ unresolved_variables[0] if unresolved_variables else "unknown"
367
+ )
348
368
  _rich_warning(
349
- "Could not resolve container run options for "
350
- f"'{package.get('name', '')}'; using the default launcher. "
351
- "Set the required registry runtime variables and rerun "
352
- "'apm install'."
369
+ "Could not resolve required container run option "
370
+ f"'{variable_name}' for '{package.get('name', '')}'; "
371
+ "target configuration was not changed. Set the required "
372
+ "registry runtime variables and rerun 'apm install'."
353
373
  )
354
- args = self._ensure_docker_image_arg(
355
- ["run", "-i", "--rm"],
356
- package.get("name"),
357
- )
374
+ return {}, []
375
+ args = self._ensure_docker_image_arg(["run", "-i", "--rm"], package.get("name"))
358
376
 
359
377
  server_config = {"type": "stdio", "command": "docker", "args": args}
360
378
 
@@ -547,50 +565,50 @@ class VSCodeClientAdapter(MCPClientAdapter):
547
565
  return env_config, input_vars
548
566
 
549
567
  @staticmethod
550
- def _declared_vscode_argument_secret_inputs(package):
568
+ def _vscode_argument_secret_input_id(server_name: str, variable_name: str) -> str:
569
+ """Return a collision-safe VS Code input ID for one server variable."""
570
+ server_digest = hashlib.sha256(server_name.encode("utf-8")).hexdigest()[:12]
571
+ return f"mcp-{server_digest}-{variable_name.encode('utf-8').hex()}"
572
+
573
+ @classmethod
574
+ def _declared_vscode_argument_secret_inputs(cls, package, *, server_name: str):
551
575
  """Return VS Code input indirections for secret argument variables."""
552
576
  if not package:
553
577
  return {}, []
578
+ package_variables = cls._package_runtime_variable_metadata(package)
579
+ if package_variables is None:
580
+ raise ValueError("MCP package argument variable metadata must be valid")
554
581
  fallbacks = {}
555
582
  input_vars = []
583
+ templates = []
556
584
  for field_name in ("runtime_arguments", "package_arguments"):
557
585
  for argument in package.get(field_name) or []:
558
586
  if not isinstance(argument, dict):
559
587
  continue
560
- variables = argument.get("variables")
561
- if not isinstance(variables, dict):
562
- continue
563
588
  template = argument.get(
564
589
  "value",
565
590
  argument.get("default", argument.get("value_hint", "")),
566
591
  )
567
- for variable_name, variable_info in variables.items():
568
- if not isinstance(variable_name, str) or not isinstance(
569
- variable_info,
570
- dict,
571
- ):
572
- continue
573
- if not isinstance(template, str) or f"{{{variable_name}}}" not in template:
574
- continue
575
- is_secret = variable_info.get(
576
- "isSecret",
577
- variable_info.get("is_secret", False),
578
- )
579
- if is_secret is not True or variable_name in fallbacks:
580
- continue
581
- input_id = variable_name.lower().replace("_", "-")
582
- fallbacks[variable_name] = f"${{input:{input_id}}}"
583
- input_vars.append(
584
- {
585
- "type": "promptString",
586
- "id": input_id,
587
- "description": variable_info.get(
588
- "description",
589
- f"{variable_name} for MCP server",
590
- ),
591
- "password": True,
592
- }
593
- )
592
+ if isinstance(template, str):
593
+ templates.append(template)
594
+ for variable_name, variable_info in package_variables.items():
595
+ if not any(f"{{{variable_name}}}" in template for template in templates):
596
+ continue
597
+ if not variable_info.get("isSecret", variable_info.get("is_secret", False)):
598
+ continue
599
+ input_id = cls._vscode_argument_secret_input_id(server_name, variable_name)
600
+ fallbacks[variable_name] = f"${{input:{input_id}}}"
601
+ input_vars.append(
602
+ {
603
+ "type": "promptString",
604
+ "id": input_id,
605
+ "description": variable_info.get(
606
+ "description",
607
+ f"{variable_name} for MCP server",
608
+ ),
609
+ "password": True,
610
+ }
611
+ )
594
612
  return fallbacks, input_vars
595
613
 
596
614
  @staticmethod
@@ -776,7 +794,14 @@ class VSCodeClientAdapter(MCPClientAdapter):
776
794
  return extracted
777
795
 
778
796
  @classmethod
779
- def _docker_run_args(cls, package: dict, runtime_vars: dict | None = None) -> list[str] | None:
797
+ def _docker_run_args(
798
+ cls,
799
+ package: dict,
800
+ runtime_vars: dict | None = None,
801
+ *,
802
+ secret_variable_fallbacks: dict[str, str] | None = None,
803
+ unresolved_variables: list[str] | None = None,
804
+ ) -> list[str] | None:
780
805
  """Build ``docker run`` arguments from a container package's metadata.
781
806
 
782
807
  Container packages retain a dedicated assembler because Docker requires
@@ -813,10 +838,27 @@ class VSCodeClientAdapter(MCPClientAdapter):
813
838
  """
814
839
  if not package:
815
840
  return None
816
- run_options = cls._docker_arg_values(package.get("runtime_arguments"), runtime_vars)
841
+ package_variables = cls._package_runtime_variable_metadata(package)
842
+ if package_variables is None:
843
+ if unresolved_variables is not None:
844
+ unresolved_variables.append("invalid metadata")
845
+ return None
846
+ run_options = cls._docker_arg_values(
847
+ package.get("runtime_arguments"),
848
+ runtime_vars,
849
+ secret_variable_fallbacks,
850
+ package_variables,
851
+ unresolved_variables,
852
+ )
817
853
  if run_options is None:
818
854
  return None
819
- package_args = cls._docker_arg_values(package.get("package_arguments"), runtime_vars)
855
+ package_args = cls._docker_arg_values(
856
+ package.get("package_arguments"),
857
+ runtime_vars,
858
+ secret_variable_fallbacks,
859
+ package_variables,
860
+ unresolved_variables,
861
+ )
820
862
  if package_args is None:
821
863
  return None
822
864
  if not run_options and package_args and package_args[0] == "run":
@@ -855,7 +897,12 @@ class VSCodeClientAdapter(MCPClientAdapter):
855
897
 
856
898
  @classmethod
857
899
  def _docker_arg_values(
858
- cls, entries: list | None, runtime_vars: dict | None
900
+ cls,
901
+ entries: list | None,
902
+ runtime_vars: dict | None,
903
+ secret_variable_fallbacks: dict[str, str] | None,
904
+ package_variables: dict[str, dict],
905
+ unresolved_variables: list[str] | None,
859
906
  ) -> list[str] | None:
860
907
  """Resolve one registry argument list into CLI argument strings.
861
908
 
@@ -903,47 +950,26 @@ class VSCodeClientAdapter(MCPClientAdapter):
903
950
  continue
904
951
 
905
952
  template = str(raw)
906
- variables = arg.get("variables")
907
- if isinstance(variables, dict) and variables:
908
- substituted = cls._substitute_runtime_variables(template, variables, runtime_vars)
909
- if substituted is None:
910
- if required:
911
- return None
912
- continue
913
- template = substituted
953
+ substituted = cls._substitute_runtime_variables(
954
+ template,
955
+ package_variables,
956
+ runtime_vars,
957
+ {"workspaceFolder": "${workspaceFolder}"},
958
+ secret_variable_fallbacks,
959
+ )
960
+ if substituted is None:
961
+ if required:
962
+ if unresolved_variables is not None:
963
+ match = _RUNTIME_TEMPLATE_VARIABLE_RE.search(template)
964
+ unresolved_variables.append(match.group(1) if match else "unknown")
965
+ return None
966
+ continue
967
+ template = substituted
914
968
  if arg_type == "named" and arg.get("name"):
915
969
  args.append(str(arg["name"]))
916
970
  args.append(template)
917
971
  return args
918
972
 
919
- @staticmethod
920
- def _substitute_runtime_variables(
921
- template: str, variables: dict, runtime_vars: dict | None
922
- ) -> str | None:
923
- """Substitute ``{var}`` placeholders, or return None if unresolvable.
924
-
925
- ``workspaceFolder`` resolves to VS Code's own ``${workspaceFolder}``
926
- token, which the editor expands at server start. Any other name that
927
- this install did not collect a value for has no such fallback, so the
928
- caller is told to decline rather than write a literal ``${name}`` into
929
- a mount path.
930
- """
931
- for var_name in variables:
932
- placeholder = f"{{{var_name}}}"
933
- # A descriptor the template never references cannot make it
934
- # unresolvable; declining on one would drop a usable argument.
935
- if placeholder not in template:
936
- continue
937
- supplied = (runtime_vars or {}).get(var_name)
938
- if supplied is not None and str(supplied) != "":
939
- replacement = str(supplied)
940
- elif var_name == "workspaceFolder":
941
- replacement = "${workspaceFolder}"
942
- else:
943
- return None
944
- template = template.replace(placeholder, replacement)
945
- return template
946
-
947
973
  @staticmethod
948
974
  def _select_remote_with_url(remotes):
949
975
  """Return the first remote entry that has a non-empty URL.
@@ -46,6 +46,13 @@ _CROSS_TARGET_MAPS: dict[str, dict[str, str]] = {
46
46
  ".github/skills/": ".agents/skills/",
47
47
  ".github/agents/": ".windsurf/skills/",
48
48
  },
49
+ "grok-cloud": {
50
+ ".github/skills/": ".grok/skills/",
51
+ },
52
+ "grok-build": {
53
+ ".github/skills/": ".grok/skills/",
54
+ ".github/agents/": ".grok/agents/",
55
+ },
49
56
  "agent-skills": {
50
57
  ".github/skills/": ".agents/skills/",
51
58
  },
@@ -131,32 +138,30 @@ def _filter_files_by_target(
131
138
  if p not in seen_prefixes:
132
139
  seen_prefixes.add(p)
133
140
  prefixes.append(p)
134
- # Union all cross-target maps
135
- # NOTE: dict.update() means the last target's mapping wins when
136
- # multiple targets map the same source prefix. In practice this
137
- # is benign -- common multi-target combos (e.g. claude+copilot)
138
- # match prefixes directly without needing cross-maps.
139
- cross_map: dict[str, str] = {}
141
+ # Preserve every selected target's cross-map so one source path can
142
+ # intentionally fan out to multiple target-specific destinations.
143
+ cross_maps: list[tuple[str, str]] = []
140
144
  for t in target:
141
- cross_map.update(_CROSS_TARGET_MAPS.get(t, {}))
145
+ cross_maps.extend(_CROSS_TARGET_MAPS.get(t, {}).items())
142
146
  else:
143
147
  prefixes = _get_target_prefixes(target)
144
- cross_map = _CROSS_TARGET_MAPS.get(target, {})
148
+ cross_maps = list(_CROSS_TARGET_MAPS.get(target, {}).items())
145
149
 
146
150
  direct = [f for f in deployed_files if any(f.startswith(p) for p in prefixes)]
147
151
 
148
152
  path_mappings: dict[str, str] = {}
149
- if cross_map:
153
+ if cross_maps:
150
154
  direct_set = set(direct)
151
155
  for f in deployed_files:
152
156
  if f in direct_set:
153
157
  continue
154
- for src_prefix, dst_prefix in cross_map.items():
158
+ for src_prefix, dst_prefix in cross_maps:
155
159
  if f.startswith(src_prefix):
156
160
  mapped = dst_prefix + f[len(src_prefix) :]
157
161
  # Containment guard: normalise the remapped path and
158
- # reject any result that escapes the destination prefix
159
- # via traversal segments (e.g. "../../etc/passwd").
162
+ # reject any result that escapes the destination prefix.
163
+ # The ".." check catches root-level escapes; the prefix
164
+ # check below is the authoritative containment barrier.
160
165
  normalised = posixpath.normpath(mapped)
161
166
  if ".." in normalised.split("/"):
162
167
  continue
@@ -170,7 +175,6 @@ def _filter_files_by_target(
170
175
  direct.append(mapped)
171
176
  direct_set.add(mapped)
172
177
  path_mappings[mapped] = f
173
- break
174
178
 
175
179
  return direct, path_mappings
176
180
 
@@ -19,6 +19,7 @@ from ..constants import (
19
19
  APM_YML_FILENAME,
20
20
  GITIGNORE_FILENAME,
21
21
  )
22
+ from ..core import project_name as _project_name
22
23
  from ..update_policy import get_update_hint_message, is_self_update_enabled
23
24
  from ..utils.atomic_io import (
24
25
  atomic_write_text as _atomic_write, # noqa: F401 -- re-exported; tests import from apm_cli.commands._helpers
@@ -29,6 +30,10 @@ from ..utils.version_checker import check_for_updates
29
30
  from ..version import get_build_sha, get_version
30
31
  from .deps._utils import _scan_installed_packages
31
32
 
33
+ # Thin compatibility aliases only; core/project_name.py remains the AC18 owner.
34
+ _resolve_bootstrap_project_name = _project_name.resolve_bootstrap_project_name
35
+ _validate_project_name = _project_name.validate_project_name
36
+
32
37
  # CRITICAL: Shadow Click commands at module level to prevent namespace collision
33
38
  # When Click commands like 'config set' are defined, calling set() can invoke the command
34
39
  # instead of the Python built-in. This affects ALL functions in this module.
@@ -617,22 +622,6 @@ def _validate_plugin_name(name):
617
622
  return bool(re.match(r"^[a-z][a-z0-9-]{0,63}$", name))
618
623
 
619
624
 
620
- def _validate_project_name(name):
621
- """Validate that a project name is safe to use as a directory name.
622
-
623
- Project names are used directly as directory names and must not contain
624
- '/' or '\' so the name is not interpreted as a filesystem path,
625
- and must not be '..' to prevent directory traversal.
626
-
627
- Returns True if valid, False otherwise.
628
- """
629
- if "/" in name or "\\" in name:
630
- return False
631
- if name == "..": # noqa: SIM103
632
- return False
633
- return True
634
-
635
-
636
625
  def _create_plugin_json(config):
637
626
  """Create plugin.json file with package metadata.
638
627
 
@@ -11,6 +11,7 @@ import click
11
11
  # Import existing APM components
12
12
  from ...constants import APM_MODULES_DIR, APM_YML_FILENAME, SKILL_MD_FILENAME
13
13
  from ...core.command_logger import CommandLogger
14
+ from ...core.project_name import DEFAULT_BOOTSTRAP_PROJECT_NAME
14
15
  from ...core.target_detection import TargetParamType
15
16
  from ...deps.lockfile import LockedDependency
16
17
  from ...models.apm_package import APMPackage
@@ -644,7 +645,7 @@ def _build_dep_tree(apm_dir):
644
645
  apm_modules_path = apm_dir / APM_MODULES_DIR
645
646
 
646
647
  # Load project info
647
- project_name = "my-project"
648
+ project_name = DEFAULT_BOOTSTRAP_PROJECT_NAME
648
649
  try:
649
650
  apm_yml_path = apm_dir / APM_YML_FILENAME
650
651
  if apm_yml_path.exists():
@@ -10,6 +10,10 @@ import click
10
10
  from ..bundle.plugin_layout import find_plugin_root_sources
11
11
  from ..constants import APM_YML_FILENAME
12
12
  from ..core.command_logger import CommandLogger
13
+ from ..core.project_name import (
14
+ resolve_bootstrap_project_name as _resolve_bootstrap_project_name,
15
+ )
16
+ from ..core.project_name import validate_project_name as _validate_project_name
13
17
  from ..core.target_detection import (
14
18
  EXPLICIT_ONLY_TARGETS,
15
19
  TargetParamType,
@@ -29,7 +33,6 @@ from ._helpers import (
29
33
  _get_default_config,
30
34
  _rich_blank_line,
31
35
  _validate_plugin_name,
32
- _validate_project_name,
33
36
  )
34
37
 
35
38
 
@@ -146,10 +149,11 @@ def _perform_init(
146
149
  project_name = None
147
150
 
148
151
  # Reject names containing path separators before any filesystem use
149
- if project_name and not _validate_project_name(project_name):
152
+ if project_name is not None and not _validate_project_name(project_name):
150
153
  logger.error(
151
154
  f"Invalid project name '{project_name}': "
152
- "project names must not contain path separators ('/' or '\\\\') or be '..'."
155
+ "project names must not be empty or whitespace-only and must not contain "
156
+ "path separators ('/' or '\\\\') or be '..'."
153
157
  )
154
158
  sys.exit(1)
155
159
 
@@ -162,7 +166,14 @@ def _perform_init(
162
166
  final_project_name = project_name
163
167
  else:
164
168
  project_dir = Path.cwd()
165
- final_project_name = project_dir.name
169
+ # A filesystem root has no directory name, so resolve a valid fallback.
170
+ derived_project_name = project_dir.name
171
+ final_project_name = _resolve_bootstrap_project_name(derived_project_name)
172
+ if final_project_name != derived_project_name:
173
+ logger.verbose_detail(
174
+ f'Using default project name "{final_project_name}" because '
175
+ f"derived name {derived_project_name!a} is invalid"
176
+ )
166
177
  project_root = Path.cwd()
167
178
 
168
179
  # Validate plugin name early
@@ -395,7 +406,8 @@ def _interactive_project_setup(default_name, logger):
395
406
  break
396
407
  console.print(
397
408
  f"[error]Invalid project name '{name}': "
398
- "project names must not contain path separators ('/' or '\\\\') or be '..'.[/error]"
409
+ "project names must not be empty or whitespace-only and must not contain "
410
+ "path separators ('/' or '\\\\') or be '..'.[/error]"
399
411
  )
400
412
 
401
413
  version = Prompt.ask("Version", default="1.0.0").strip()
@@ -412,7 +424,8 @@ def _interactive_project_setup(default_name, logger):
412
424
  break
413
425
  click.echo(
414
426
  f"{ERROR}Invalid project name '{name}': "
415
- f"project names must not contain path separators ('/' or '\\\\') or be '..'.{RESET}"
427
+ f"project names must not be empty or whitespace-only and must not contain "
428
+ f"path separators ('/' or '\\\\') or be '..'.{RESET}"
416
429
  )
417
430
 
418
431
  version = click.prompt("Version", default="1.0.0").strip()