apm-cli 0.19.0__tar.gz → 0.21.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 (412) hide show
  1. {apm_cli-0.19.0/src/apm_cli.egg-info → apm_cli-0.21.0}/PKG-INFO +7 -4
  2. {apm_cli-0.19.0 → apm_cli-0.21.0}/README.md +6 -3
  3. {apm_cli-0.19.0 → apm_cli-0.21.0}/pyproject.toml +4 -1
  4. apm_cli-0.21.0/src/apm_cli/adapters/client/antigravity.py +54 -0
  5. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/base.py +51 -11
  6. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/codex.py +3 -0
  7. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/copilot.py +13 -2
  8. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/cursor.py +3 -0
  9. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/gemini.py +36 -19
  10. apm_cli-0.21.0/src/apm_cli/adapters/client/hermes.py +210 -0
  11. apm_cli-0.21.0/src/apm_cli/adapters/client/kiro.py +229 -0
  12. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/vscode.py +117 -30
  13. apm_cli-0.21.0/src/apm_cli/bootstrap_mirror.py +101 -0
  14. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/bundle/local_bundle.py +57 -62
  15. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/bundle/lockfile_enrichment.py +3 -0
  16. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/bundle/packer.py +25 -7
  17. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/bundle/plugin_exporter.py +28 -14
  18. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/bundle/unpacker.py +76 -29
  19. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/cli.py +3 -0
  20. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/_helpers.py +2 -2
  21. apm_cli-0.21.0/src/apm_cli/commands/approve.py +265 -0
  22. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/audit.py +79 -4
  23. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/compile/cli.py +22 -6
  24. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/deps/cli.py +8 -3
  25. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/doctor.py +3 -5
  26. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/install.py +78 -65
  27. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/lock.py +140 -2
  28. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/__init__.py +151 -262
  29. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/check.py +83 -4
  30. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/doctor.py +7 -66
  31. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/outdated.py +76 -12
  32. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/pack.py +113 -6
  33. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/publish.py +15 -9
  34. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/self_update.py +87 -26
  35. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/update.py +206 -31
  36. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/agents_compiler.py +199 -6
  37. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/claude_formatter.py +14 -7
  38. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/distributed_compiler.py +241 -26
  39. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/apm_yml.py +1 -0
  40. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/auth.py +66 -11
  41. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/build_orchestrator.py +2 -0
  42. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/errors.py +1 -1
  43. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/experimental.py +22 -0
  44. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/target_detection.py +47 -7
  45. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/apm_resolver.py +155 -43
  46. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/download_strategies.py +215 -54
  47. apm_cli-0.21.0/src/apm_cli/deps/git_file_transport.py +246 -0
  48. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/git_reference_resolver.py +18 -3
  49. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/git_remote_ops.py +24 -3
  50. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/github_downloader.py +22 -4
  51. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/github_downloader_validation.py +5 -1
  52. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/host_backends.py +18 -6
  53. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/lockfile.py +77 -5
  54. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/path_anchoring.py +4 -4
  55. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/registry/client.py +9 -9
  56. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/registry/extractor.py +8 -34
  57. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/registry/outdated.py +22 -2
  58. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/registry/resolver.py +27 -13
  59. apm_cli-0.21.0/src/apm_cli/deps/revision_pins.py +262 -0
  60. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/drift.py +9 -4
  61. apm_cli-0.21.0/src/apm_cli/export/__init__.py +13 -0
  62. apm_cli-0.21.0/src/apm_cli/export/authoring.py +55 -0
  63. apm_cli-0.21.0/src/apm_cli/export/declared_license.py +79 -0
  64. apm_cli-0.21.0/src/apm_cli/export/formats.py +15 -0
  65. apm_cli-0.21.0/src/apm_cli/export/purl.py +153 -0
  66. apm_cli-0.21.0/src/apm_cli/export/sbom.py +178 -0
  67. apm_cli-0.21.0/src/apm_cli/export/spdx.py +168 -0
  68. apm_cli-0.21.0/src/apm_cli/export/spdx_data.py +841 -0
  69. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/factory.py +6 -0
  70. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/cache_pin.py +2 -2
  71. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/context.py +13 -0
  72. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/drift.py +34 -0
  73. apm_cli-0.21.0/src/apm_cli/install/exec_gate.py +139 -0
  74. apm_cli-0.21.0/src/apm_cli/install/integrity.py +59 -0
  75. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/local_bundle_handler.py +2 -0
  76. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/package_resolution.py +51 -0
  77. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/integrate.py +53 -0
  78. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/local_content.py +8 -7
  79. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/lockfile.py +34 -0
  80. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/targets.py +61 -8
  81. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/pipeline.py +49 -1
  82. apm_cli-0.21.0/src/apm_cli/install/registry_wiring.py +145 -0
  83. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/request.py +6 -0
  84. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/service.py +1 -0
  85. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/services.py +204 -91
  86. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/sources.py +22 -0
  87. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/template.py +3 -0
  88. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/validation.py +8 -1
  89. apm_cli-0.21.0/src/apm_cli/integration/canvas_integrator.py +508 -0
  90. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/cleanup.py +236 -23
  91. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/dispatch.py +7 -0
  92. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/hook_integrator.py +193 -36
  93. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/instruction_integrator.py +65 -0
  94. apm_cli-0.21.0/src/apm_cli/integration/kiro_hook_integrator.py +322 -0
  95. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/mcp_integrator.py +44 -3
  96. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/mcp_integrator_install.py +142 -111
  97. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/skill_integrator.py +61 -14
  98. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/targets.py +139 -12
  99. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/__init__.py +0 -16
  100. apm_cli-0.21.0/src/apm_cli/marketplace/auth_helpers.py +53 -0
  101. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/builder.py +238 -65
  102. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/client.py +250 -15
  103. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/git_stderr.py +1 -3
  104. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/models.py +48 -4
  105. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/output_mappers.py +118 -55
  106. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/resolver.py +48 -1
  107. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/validator.py +1 -1
  108. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/version_check.py +1 -1
  109. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/yml_editor.py +19 -22
  110. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/yml_schema.py +123 -18
  111. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/apm_package.py +40 -6
  112. apm_cli-0.21.0/src/apm_cli/models/dependency/identity.py +112 -0
  113. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/dependency/mcp.py +46 -2
  114. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/dependency/reference.py +151 -43
  115. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/dependency/types.py +2 -1
  116. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/validation.py +31 -0
  117. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/discovery.py +1 -0
  118. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/inheritance.py +54 -2
  119. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/matcher.py +19 -6
  120. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/parser.py +35 -1
  121. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/policy_checks.py +156 -17
  122. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/schema.py +25 -0
  123. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/registry/operations.py +47 -18
  124. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/__init__.py +8 -0
  125. apm_cli-0.21.0/src/apm_cli/security/executables.py +435 -0
  126. apm_cli-0.21.0/src/apm_cli/utils/archive.py +380 -0
  127. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/version_checker.py +66 -21
  128. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/yaml_io.py +40 -0
  129. {apm_cli-0.19.0 → apm_cli-0.21.0/src/apm_cli.egg-info}/PKG-INFO +7 -4
  130. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli.egg-info/SOURCES.txt +24 -3
  131. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_apm_resolver.py +141 -1
  132. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_github_downloader.py +123 -41
  133. apm_cli-0.21.0/tests/test_gitlab_git_transport.py +663 -0
  134. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_lockfile.py +71 -1
  135. apm_cli-0.19.0/src/apm_cli/commands/marketplace/publish.py +0 -239
  136. apm_cli-0.19.0/src/apm_cli/install/registry_wiring.py +0 -63
  137. apm_cli-0.19.0/src/apm_cli/marketplace/pr_integration.py +0 -498
  138. apm_cli-0.19.0/src/apm_cli/marketplace/publisher.py +0 -922
  139. {apm_cli-0.19.0 → apm_cli-0.21.0}/AUTHORS +0 -0
  140. {apm_cli-0.19.0 → apm_cli-0.21.0}/LICENSE +0 -0
  141. {apm_cli-0.19.0 → apm_cli-0.21.0}/NOTICE +0 -0
  142. {apm_cli-0.19.0 → apm_cli-0.21.0}/setup.cfg +0 -0
  143. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/__init__.py +0 -0
  144. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/__init__.py +0 -0
  145. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/__init__.py +0 -0
  146. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
  147. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/claude.py +0 -0
  148. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/intellij.py +0 -0
  149. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/opencode.py +0 -0
  150. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/client/windsurf.py +0 -0
  151. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
  152. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/package_manager/base.py +0 -0
  153. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
  154. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/bundle/__init__.py +0 -0
  155. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/cache/__init__.py +0 -0
  156. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/cache/git_cache.py +0 -0
  157. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/cache/http_cache.py +0 -0
  158. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/cache/integrity.py +0 -0
  159. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/cache/locking.py +0 -0
  160. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/cache/paths.py +0 -0
  161. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/cache/url_normalize.py +0 -0
  162. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/__init__.py +0 -0
  163. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/_apm_yml_writer.py +0 -0
  164. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/cache.py +0 -0
  165. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/compile/__init__.py +0 -0
  166. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/compile/watcher.py +0 -0
  167. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/config.py +0 -0
  168. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/deps/__init__.py +0 -0
  169. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/deps/_utils.py +0 -0
  170. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/deps/why.py +0 -0
  171. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/experimental.py +0 -0
  172. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/find.py +0 -0
  173. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/init.py +0 -0
  174. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/list_cmd.py +0 -0
  175. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/audit.py +0 -0
  176. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/init.py +0 -0
  177. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/migrate.py +0 -0
  178. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/outdated.py +0 -0
  179. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/plugin/__init__.py +0 -0
  180. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/plugin/add.py +0 -0
  181. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/plugin/remove.py +0 -0
  182. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
  183. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/marketplace/validate.py +0 -0
  184. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/mcp.py +0 -0
  185. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/plugin/__init__.py +0 -0
  186. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/plugin/init.py +0 -0
  187. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/policy.py +0 -0
  188. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/prune.py +0 -0
  189. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/run.py +0 -0
  190. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/runtime.py +0 -0
  191. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/targets.py +0 -0
  192. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/uninstall/__init__.py +0 -0
  193. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/uninstall/cli.py +0 -0
  194. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/uninstall/engine.py +0 -0
  195. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/commands/view.py +0 -0
  196. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/__init__.py +0 -0
  197. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/build_id.py +0 -0
  198. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/constants.py +0 -0
  199. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/constitution.py +0 -0
  200. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/constitution_block.py +0 -0
  201. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/context_optimizer.py +0 -0
  202. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/gemini_formatter.py +0 -0
  203. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/injector.py +0 -0
  204. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/link_resolver.py +0 -0
  205. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/managed_section.py +0 -0
  206. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/output_writer.py +0 -0
  207. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/compilation/template_builder.py +0 -0
  208. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/config.py +0 -0
  209. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/constants.py +0 -0
  210. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/__init__.py +0 -0
  211. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/azure_cli.py +0 -0
  212. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/command_logger.py +0 -0
  213. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/conflict_detector.py +0 -0
  214. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/docker_args.py +0 -0
  215. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/install_audit.py +0 -0
  216. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/null_logger.py +0 -0
  217. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/operations.py +0 -0
  218. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/plugin_manifest.py +0 -0
  219. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/safe_installer.py +0 -0
  220. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/scope.py +0 -0
  221. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/script_runner.py +0 -0
  222. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/core/token_manager.py +0 -0
  223. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/__init__.py +0 -0
  224. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/_shared.py +0 -0
  225. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/aggregator.py +0 -0
  226. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/artifactory_entry.py +0 -0
  227. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
  228. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/bare_cache.py +0 -0
  229. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/clone_engine.py +0 -0
  230. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/dependency_graph.py +0 -0
  231. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/git_auth_env.py +0 -0
  232. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/git_semver_resolver.py +0 -0
  233. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/installed_package.py +0 -0
  234. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/outdated_row.py +0 -0
  235. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/package_validator.py +0 -0
  236. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/plugin_parser.py +0 -0
  237. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/registry/__init__.py +0 -0
  238. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/registry/auth.py +0 -0
  239. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/registry/config_loader.py +0 -0
  240. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/registry/feature_gate.py +0 -0
  241. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/registry/semver.py +0 -0
  242. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/registry_proxy.py +0 -0
  243. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/shared_clone_cache.py +0 -0
  244. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/tiered_ref_resolver.py +0 -0
  245. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/transport_selection.py +0 -0
  246. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/verifier.py +0 -0
  247. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/deps/why_walker.py +0 -0
  248. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/__init__.py +0 -0
  249. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/artifactory_resolver.py +0 -0
  250. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/errors.py +0 -0
  251. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/gitlab_resolver.py +0 -0
  252. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/heals/__init__.py +0 -0
  253. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/heals/base.py +0 -0
  254. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
  255. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
  256. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/helpers/__init__.py +0 -0
  257. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/helpers/security_scan.py +0 -0
  258. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/insecure_policy.py +0 -0
  259. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/lsp/__init__.py +0 -0
  260. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/lsp/integration.py +0 -0
  261. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/manifest_reconcile.py +0 -0
  262. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/mcp/__init__.py +0 -0
  263. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/mcp/args.py +0 -0
  264. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/mcp/command.py +0 -0
  265. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/mcp/conflicts.py +0 -0
  266. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/mcp/entry.py +0 -0
  267. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/mcp/registry.py +0 -0
  268. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/mcp/warnings.py +0 -0
  269. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/mcp/writer.py +0 -0
  270. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/package_selection.py +0 -0
  271. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/__init__.py +0 -0
  272. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/_redownload.py +0 -0
  273. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/_skip_logic.py +0 -0
  274. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/audit.py +0 -0
  275. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/cleanup.py +0 -0
  276. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/download.py +0 -0
  277. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/finalize.py +0 -0
  278. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/heal.py +0 -0
  279. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/policy_gate.py +0 -0
  280. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/policy_target_check.py +0 -0
  281. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/post_deps_local.py +0 -0
  282. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/phases/resolve.py +0 -0
  283. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/plan.py +0 -0
  284. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/presentation/__init__.py +0 -0
  285. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/presentation/dry_run.py +0 -0
  286. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/root_redirect.py +0 -0
  287. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/skill_path_migration.py +0 -0
  288. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/install/summary.py +0 -0
  289. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/__init__.py +0 -0
  290. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/_shared.py +0 -0
  291. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/agent_integrator.py +0 -0
  292. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/base_integrator.py +0 -0
  293. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/command_integrator.py +0 -0
  294. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/copilot_app_db.py +0 -0
  295. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/copilot_app_project.py +0 -0
  296. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/copilot_app_workflow_integrator.py +0 -0
  297. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/copilot_app_ws.py +0 -0
  298. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
  299. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/coverage.py +0 -0
  300. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/lsp_integrator.py +0 -0
  301. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
  302. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/prompt_integrator.py +0 -0
  303. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/skill_transformer.py +0 -0
  304. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/integration/utils.py +0 -0
  305. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/_git_utils.py +0 -0
  306. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/_io.py +0 -0
  307. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/_shared.py +0 -0
  308. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/audit.py +0 -0
  309. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/diagnostics.py +0 -0
  310. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/drift_check.py +0 -0
  311. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/errors.py +0 -0
  312. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/init_template.py +0 -0
  313. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/migration.py +0 -0
  314. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/output_profiles.py +0 -0
  315. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/ref_resolver.py +0 -0
  316. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/registry.py +0 -0
  317. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/semver.py +0 -0
  318. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/shadow_detector.py +0 -0
  319. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/tag_pattern.py +0 -0
  320. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/version_pins.py +0 -0
  321. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/marketplace/version_resolver.py +0 -0
  322. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/__init__.py +0 -0
  323. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/dependency/__init__.py +0 -0
  324. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/dependency/lsp.py +0 -0
  325. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/format_detection.py +0 -0
  326. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/plugin.py +0 -0
  327. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/models/results.py +0 -0
  328. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/output/__init__.py +0 -0
  329. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/output/formatters.py +0 -0
  330. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/output/models.py +0 -0
  331. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/output/script_formatters.py +0 -0
  332. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/__init__.py +0 -0
  333. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/_constraint_pinning.py +0 -0
  334. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/_help_text.py +0 -0
  335. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/_shared.py +0 -0
  336. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/ci_checks.py +0 -0
  337. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/install_preflight.py +0 -0
  338. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/models.py +0 -0
  339. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/outcome_routing.py +0 -0
  340. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/policy/project_config.py +0 -0
  341. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/primitives/__init__.py +0 -0
  342. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/primitives/discovery.py +0 -0
  343. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/primitives/models.py +0 -0
  344. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/primitives/parser.py +0 -0
  345. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/registry/__init__.py +0 -0
  346. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/registry/client.py +0 -0
  347. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/registry/integration.py +0 -0
  348. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/runtime/__init__.py +0 -0
  349. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/runtime/base.py +0 -0
  350. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/runtime/codex_runtime.py +0 -0
  351. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/runtime/copilot_runtime.py +0 -0
  352. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/runtime/factory.py +0 -0
  353. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/runtime/llm_runtime.py +0 -0
  354. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/runtime/manager.py +0 -0
  355. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/runtime/utils.py +0 -0
  356. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/audit_report.py +0 -0
  357. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/content_scanner.py +0 -0
  358. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/external/__init__.py +0 -0
  359. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/external/base.py +0 -0
  360. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/external/gate.py +0 -0
  361. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/external/generic_sarif.py +0 -0
  362. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/external/options.py +0 -0
  363. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/external/registry.py +0 -0
  364. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/external/runner.py +0 -0
  365. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/external/sarif_ingest.py +0 -0
  366. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/external/skillspector.py +0 -0
  367. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/file_scanner.py +0 -0
  368. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/security/gate.py +0 -0
  369. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/update_policy.py +0 -0
  370. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/__init__.py +0 -0
  371. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/atomic_io.py +0 -0
  372. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/console.py +0 -0
  373. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/content_hash.py +0 -0
  374. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/diagnostics.py +0 -0
  375. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/exclude.py +0 -0
  376. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/file_ops.py +0 -0
  377. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/git_env.py +0 -0
  378. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/git_sparse.py +0 -0
  379. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/github_host.py +0 -0
  380. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/guards.py +0 -0
  381. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/helpers.py +0 -0
  382. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/install_tui.py +0 -0
  383. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/normalization.py +0 -0
  384. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/path_security.py +0 -0
  385. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/paths.py +0 -0
  386. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/patterns.py +0 -0
  387. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/perf_stats.py +0 -0
  388. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/reflink.py +0 -0
  389. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/short_sha.py +0 -0
  390. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/utils/subprocess_env.py +0 -0
  391. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/version.py +0 -0
  392. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/workflow/__init__.py +0 -0
  393. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/workflow/discovery.py +0 -0
  394. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/workflow/parser.py +0 -0
  395. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli/workflow/runner.py +0 -0
  396. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli.egg-info/dependency_links.txt +0 -0
  397. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli.egg-info/entry_points.txt +0 -0
  398. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli.egg-info/requires.txt +0 -0
  399. {apm_cli-0.19.0 → apm_cli-0.21.0}/src/apm_cli.egg-info/top_level.txt +0 -0
  400. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_apm_package_models.py +0 -0
  401. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_codex_docker_args_fix.py +0 -0
  402. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_codex_empty_string_and_defaults.py +0 -0
  403. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_collision_integration.py +0 -0
  404. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_console.py +0 -0
  405. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_distributed_compilation.py +0 -0
  406. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_empty_string_and_defaults.py +0 -0
  407. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_enhanced_discovery.py +0 -0
  408. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_github_downloader_token_precedence.py +0 -0
  409. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_runnable_prompts.py +0 -0
  410. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_runtime_manager_token_precedence.py +0 -0
  411. {apm_cli-0.19.0 → apm_cli-0.21.0}/tests/test_token_manager.py +0 -0
  412. {apm_cli-0.19.0 → apm_cli-0.21.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.19.0
3
+ Version: 0.21.0
4
4
  Summary: MCP configuration tool
5
5
  Author-email: Daniel Meppiel <user@example.com>
6
6
  License: MIT License
@@ -72,7 +72,7 @@ Dynamic: license-file
72
72
 
73
73
  Think `package.json`, `requirements.txt`, or `Cargo.toml` — but for AI agent configuration.
74
74
 
75
- GitHub Copilot · Claude Code · Cursor · OpenCode · Codex · Gemini · Windsurf
75
+ GitHub Copilot · Claude Code · Cursor · OpenCode · Codex · Gemini · Windsurf · Kiro
76
76
 
77
77
  **[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)**
78
78
 
@@ -135,7 +135,7 @@ One command, no configuration -- VS Code and GitHub Copilot read the file automa
135
135
 
136
136
  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.
137
137
 
138
- - **[One manifest for everything](https://microsoft.github.io/apm/reference/primitive-types/)** — declared once, deployed across Copilot, Claude, Cursor, OpenCode, Codex, Gemini, Windsurf
138
+ - **[One manifest for everything](https://microsoft.github.io/apm/reference/primitive-types/)** — declared once, deployed across Copilot, Claude, Cursor, OpenCode, Codex, Gemini, Windsurf, Kiro
139
139
  - **[Install from anywhere](https://microsoft.github.io/apm/guides/dependencies/)** — GitHub, GitLab, Bitbucket, Azure DevOps, GitHub Enterprise, Gitea, Gogs, any git host
140
140
  - **[Transitive dependencies](https://microsoft.github.io/apm/guides/dependencies/)** — packages can depend on packages; APM resolves the full tree
141
141
  - **[Author plugins](https://microsoft.github.io/apm/guides/plugins/)** — build Copilot, Claude, and Cursor plugins with dependency management, then export standard `plugin.json`
@@ -149,6 +149,7 @@ Agent context is executable in effect — a prompt is a program for an LLM. APM
149
149
 
150
150
  - **[Content security](https://microsoft.github.io/apm/enterprise/security/)** — `apm install` blocks compromised packages before agents read them; `apm audit` runs the same checks on demand
151
151
  - **[Lockfile integrity](https://microsoft.github.io/apm/enterprise/governance/)** — `apm.lock` records resolved sources and content hashes for full provenance
152
+ - **[SBOM export](https://microsoft.github.io/apm/reference/cli/lock/)** — `apm lock export --format cyclonedx|spdx` emits a standard inventory of what reached disk, straight from the lockfile — provenance for procurement, not a compliance attestation
152
153
  - **[Drift detection](https://microsoft.github.io/apm/guides/drift-detection/)** — `apm audit` rebuilds your agent context in scratch and diffs it against your working tree to catch hand-edits before they ship
153
154
  - **[MCP trust boundaries](https://microsoft.github.io/apm/guides/mcp-servers/)** — transitive MCP servers require explicit consent
154
155
 
@@ -156,6 +157,8 @@ Agent context is executable in effect — a prompt is a program for an LLM. APM
156
157
 
157
158
  `apm-policy.yml` lets a security team say *"these are the only sources, scopes, and primitives this org will allow"* and have every `apm install` enforce it — with tighten-only inheritance from enterprise to org to repo, a published bypass contract, and audit-mode CI gates.
158
159
 
160
+ apm-policy.yml governs what gets installed; your agent harness governs what runs. The two planes do not overlap.
161
+
159
162
  - **[Governance Guide](https://microsoft.github.io/apm/enterprise/governance-guide/)** — the canonical enterprise reference: enforcement points, bypass contract, air-gapped story, failure semantics, rollout playbook
160
163
  - **[Policy reference](https://microsoft.github.io/apm/enterprise/policy-reference/)** — every check, every field, every default
161
164
  - **[Adoption playbook](https://microsoft.github.io/apm/enterprise/adoption-playbook/)** — staged rollout from warn to block across hundreds of repos
@@ -214,7 +217,7 @@ apm marketplace add github/awesome-copilot
214
217
  apm install azure-cloud-development@awesome-copilot
215
218
  ```
216
219
 
217
- Or add an MCP server (wired into Copilot, Claude, Cursor, Codex, OpenCode, Gemini, and Windsurf):
220
+ Or add an MCP server (wired into Copilot, Claude, Cursor, Codex, OpenCode, Gemini, Windsurf, and Kiro):
218
221
 
219
222
  ```bash
220
223
  apm install --mcp io.github.github/github-mcp-server --transport http # connects over HTTPS
@@ -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
7
+ GitHub Copilot · Claude Code · 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
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
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`
@@ -81,6 +81,7 @@ Agent context is executable in effect — a prompt is a program for an LLM. APM
81
81
 
82
82
  - **[Content security](https://microsoft.github.io/apm/enterprise/security/)** — `apm install` blocks compromised packages before agents read them; `apm audit` runs the same checks on demand
83
83
  - **[Lockfile integrity](https://microsoft.github.io/apm/enterprise/governance/)** — `apm.lock` records resolved sources and content hashes for full provenance
84
+ - **[SBOM export](https://microsoft.github.io/apm/reference/cli/lock/)** — `apm lock export --format cyclonedx|spdx` emits a standard inventory of what reached disk, straight from the lockfile — provenance for procurement, not a compliance attestation
84
85
  - **[Drift detection](https://microsoft.github.io/apm/guides/drift-detection/)** — `apm audit` rebuilds your agent context in scratch and diffs it against your working tree to catch hand-edits before they ship
85
86
  - **[MCP trust boundaries](https://microsoft.github.io/apm/guides/mcp-servers/)** — transitive MCP servers require explicit consent
86
87
 
@@ -88,6 +89,8 @@ Agent context is executable in effect — a prompt is a program for an LLM. APM
88
89
 
89
90
  `apm-policy.yml` lets a security team say *"these are the only sources, scopes, and primitives this org will allow"* and have every `apm install` enforce it — with tighten-only inheritance from enterprise to org to repo, a published bypass contract, and audit-mode CI gates.
90
91
 
92
+ apm-policy.yml governs what gets installed; your agent harness governs what runs. The two planes do not overlap.
93
+
91
94
  - **[Governance Guide](https://microsoft.github.io/apm/enterprise/governance-guide/)** — the canonical enterprise reference: enforcement points, bypass contract, air-gapped story, failure semantics, rollout playbook
92
95
  - **[Policy reference](https://microsoft.github.io/apm/enterprise/policy-reference/)** — every check, every field, every default
93
96
  - **[Adoption playbook](https://microsoft.github.io/apm/enterprise/adoption-playbook/)** — staged rollout from warn to block across hundreds of repos
@@ -146,7 +149,7 @@ apm marketplace add github/awesome-copilot
146
149
  apm install azure-cloud-development@awesome-copilot
147
150
  ```
148
151
 
149
- Or add an MCP server (wired into Copilot, Claude, Cursor, Codex, OpenCode, Gemini, and Windsurf):
152
+ Or add an MCP server (wired into Copilot, Claude, Cursor, Codex, OpenCode, Gemini, Windsurf, and Kiro):
150
153
 
151
154
  ```bash
152
155
  apm install --mcp io.github.github/github-mcp-server --transport http # connects over HTTPS
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "apm-cli"
7
- version = "0.19.0"
7
+ version = "0.21.0"
8
8
  description = "MCP configuration tool"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -105,6 +105,9 @@ max-returns = 12 # Stage 1 (was 18)
105
105
  # Stage 1 (was 100). Stage 2 target: <=20 (McCabe industry standard).
106
106
  max-complexity = 50
107
107
 
108
+ [tool.ruff.lint.isort]
109
+ known-first-party = ["apm_cli"]
110
+
108
111
  [tool.ruff.lint.per-file-ignores]
109
112
  # Subprocess calls are intentional in a CLI tool
110
113
  "src/apm_cli/**" = ["S603", "S607"]
@@ -0,0 +1,54 @@
1
+ """Antigravity CLI (agy) implementation of MCP client adapter.
2
+
3
+ Antigravity CLI is Google's Gemini-derived agentic CLI. Unlike Gemini
4
+ CLI (which stores MCP servers in ``settings.json``), Antigravity reads a
5
+ dedicated ``mcp_config.json`` with an ``mcpServers`` key -- the same JSON
6
+ schema, a different file:
7
+
8
+ .. code-block:: json
9
+
10
+ {
11
+ "mcpServers": {
12
+ "server-name": {
13
+ "command": "npx",
14
+ "args": ["-y", "@modelcontextprotocol/server-foo"],
15
+ "env": { "KEY": "value" }
16
+ }
17
+ }
18
+ }
19
+
20
+ Scope resolution: project scope writes to
21
+ ``<project_root>/.agents/mcp_config.json`` (opt-in -- the directory must
22
+ already exist). User scope writes to ``~/.gemini/config/mcp_config.json``
23
+ unconditionally, creating the directory if needed.
24
+
25
+ Ref: https://antigravity.google/docs/mcp
26
+ """
27
+
28
+ from pathlib import Path
29
+
30
+ from .gemini import GeminiClientAdapter
31
+
32
+
33
+ class AntigravityClientAdapter(GeminiClientAdapter):
34
+ """Antigravity CLI MCP client adapter.
35
+
36
+ Reuses GeminiClientAdapter's ``_format_server_config`` and
37
+ ``configure_mcp_server`` (identical ``mcpServers`` JSON schema) and
38
+ overrides only the config directory, the config filename, and the
39
+ display name. Antigravity writes MCP servers to a dedicated
40
+ ``mcp_config.json`` rather than ``settings.json``.
41
+ """
42
+
43
+ supports_user_scope: bool = True
44
+ target_name: str = "antigravity"
45
+
46
+ def _get_config_dir(self) -> Path:
47
+ """Return the ``.agents`` or ``~/.gemini/config`` directory."""
48
+ if self.user_scope:
49
+ return Path.home() / ".gemini" / "config"
50
+ return self.project_root / ".agents"
51
+
52
+ def get_config_path(self):
53
+ """Return the path to ``mcp_config.json`` for the active scope."""
54
+ return str(self._get_config_dir() / "mcp_config.json")
@@ -4,8 +4,9 @@ import os
4
4
  import re
5
5
  from abc import ABC, abstractmethod
6
6
  from pathlib import Path
7
- from typing import ClassVar
7
+ from typing import Any, ClassVar
8
8
 
9
+ from ...models.dependency.mcp import _RESERVED_EXTRA_KEYS
9
10
  from ...utils.console import _rich_error, _rich_warning
10
11
 
11
12
  _INPUT_VAR_RE = re.compile(r"\$\{input:([^}]+)\}")
@@ -28,6 +29,20 @@ _ENV_PLACEHOLDER_RE = re.compile(r"<([A-Z_][A-Z0-9_]*)>|" + _ENV_VAR_RE.pattern)
28
29
  # deprecation warnings across all servers in a single install run.
29
30
  _LEGACY_ANGLE_VAR_RE = re.compile(r"<([A-Z_][A-Z0-9_]*)>")
30
31
 
32
+ # Config keys that ``_extra`` passthrough must NEVER set on a rendered harness
33
+ # config. Covers the modeled MCP fields (imported single-source from the model)
34
+ # plus harness-specific aliases that mirror a modeled field under a different
35
+ # name -- e.g. Codex emits ``http_headers`` for remote auth headers, which must
36
+ # not be injectable via passthrough. Enforced unconditionally per adapter path
37
+ # (NOT guarded by "key absent from config"), so it also closes paths that do not
38
+ # pre-set the key. Security boundary for PR #1765 / issue #1670.
39
+ _EXTRA_DENYLIST = _RESERVED_EXTRA_KEYS | frozenset({"http_headers"})
40
+
41
+
42
+ def registry_field_is_required(field: dict[str, Any]) -> bool:
43
+ """Return True unless registry metadata explicitly marks a field optional."""
44
+ return field.get("required", field.get("is_required", True)) is not False
45
+
31
46
 
32
47
  def _translate_env_placeholder(value):
33
48
  """Pure-textual translation of env-var placeholders to the canonical
@@ -113,6 +128,29 @@ class MCPClientAdapter(ABC):
113
128
  # (e.g. ``VSCodeClientAdapter``) that have no ``KNOWN_TARGETS`` entry.
114
129
  mcp_servers_key: str = ""
115
130
 
131
+ @staticmethod
132
+ def _merge_extra(config: dict, server_info: dict) -> dict:
133
+ """Merge harness-specific ``_extra`` keys from server_info into config.
134
+
135
+ Two guards apply:
136
+
137
+ * Denylist (unconditional): a key naming a modeled MCP field -- or a
138
+ harness alias of one (see ``_EXTRA_DENYLIST``) -- is dropped on EVERY
139
+ path, even when the config does not already carry it. This stops a
140
+ passthrough value from shadowing/redirecting a modeled field on
141
+ adapter paths that start empty or set only a subset of keys.
142
+ * Shadow guard: a non-reserved key is appended only when absent, so it
143
+ never overwrites a value the adapter set itself.
144
+ """
145
+ extra = server_info.get("_extra")
146
+ if extra and isinstance(extra, dict):
147
+ for k, v in extra.items():
148
+ if k in _EXTRA_DENYLIST:
149
+ continue
150
+ if k not in config:
151
+ config[k] = v
152
+ return config
153
+
116
154
  # Whether this adapter's config path is user/global-scoped (e.g.
117
155
  # ``~/.copilot/``) rather than workspace-scoped (e.g. ``.vscode/``).
118
156
  # Adapters that target a global path should override this to ``True``
@@ -481,7 +519,7 @@ class MCPClientAdapter(ABC):
481
519
  name = env_var.get("name", "")
482
520
  if not name:
483
521
  continue
484
- required = env_var.get("required", True)
522
+ required = registry_field_is_required(env_var)
485
523
 
486
524
  value = env_overrides.get(name) or os.getenv(name)
487
525
  if not value and required and not skip_prompting:
@@ -797,12 +835,15 @@ class MCPClientAdapter(ABC):
797
835
  )
798
836
 
799
837
  # First pass: identify variables with empty values to warn the user.
800
- empty_value_vars = [ev for ev in env_vars if ev.get("required") and not ev.get("value")]
838
+ empty_value_vars = [
839
+ ev for ev in env_vars if registry_field_is_required(ev) and not ev.get("value")
840
+ ]
801
841
  if empty_value_vars and skip_prompting:
802
842
  var_names = [ev.get("name") for ev in empty_value_vars]
803
843
  _rich_warning(
804
- f"Warning: The following required environment variables have no default "
805
- f"value and cannot be prompted in non-interactive mode: {var_names}"
844
+ f"Required environment variables have no default value and cannot be "
845
+ f"prompted in non-interactive mode: {var_names}. Set them in your "
846
+ "environment and rerun `apm install`."
806
847
  )
807
848
 
808
849
  for env_var in env_vars:
@@ -837,9 +878,9 @@ class MCPClientAdapter(ABC):
837
878
 
838
879
  # Priority 4: interactive prompt
839
880
  default_value = env_var.get("value", "")
840
- required = env_var.get("required", False)
881
+ required = registry_field_is_required(env_var)
841
882
 
842
- if not skip_prompting:
883
+ if not skip_prompting and required:
843
884
  from rich.prompt import Prompt
844
885
 
845
886
  description = env_var.get("description", "")
@@ -859,11 +900,10 @@ class MCPClientAdapter(ABC):
859
900
  resolved[name] = default_value
860
901
  elif required:
861
902
  _rich_warning(
862
- f"Warning: Required environment variable '{name}' could not be resolved. "
863
- f"The MCP server may not function correctly."
903
+ f"Required environment variable '{name}' could not be resolved. "
904
+ f"The MCP server may not function correctly. Set {name} in your "
905
+ "environment and rerun `apm install`."
864
906
  )
865
907
  resolved[name] = ""
866
- else:
867
- resolved[name] = default_value
868
908
 
869
909
  return resolved
@@ -219,6 +219,7 @@ class CodexClientAdapter(MCPClientAdapter):
219
219
  return self.normalize_project_arg(arg)
220
220
 
221
221
  config["args"] = [_process_stdio_arg(arg) for arg in raw.get("args") or []]
222
+ self._merge_extra(config, server_info)
222
223
  return config
223
224
 
224
225
  # Remote MCP handling.
@@ -273,6 +274,7 @@ class CodexClientAdapter(MCPClientAdapter):
273
274
  if http_headers:
274
275
  remote_config["http_headers"] = http_headers
275
276
  self._warn_input_variables(http_headers, server_name, "Codex CLI")
277
+ self._merge_extra(remote_config, server_info)
276
278
  return remote_config
277
279
 
278
280
  if not packages:
@@ -361,6 +363,7 @@ class CodexClientAdapter(MCPClientAdapter):
361
363
  resolved_env,
362
364
  )
363
365
 
366
+ self._merge_extra(config, server_info)
364
367
  return config
365
368
 
366
369
  def _process_arguments( # pylint: disable=duplicate-code # structural similarity with copilot adapter is intentional
@@ -26,6 +26,7 @@ from .base import (
26
26
  _extract_legacy_angle_vars,
27
27
  _has_env_placeholder,
28
28
  _stringify_env_literal,
29
+ registry_field_is_required,
29
30
  )
30
31
  from .base import (
31
32
  _translate_env_placeholder as _translate_env_placeholder,
@@ -441,6 +442,7 @@ class CopilotClientAdapter(MCPClientAdapter):
441
442
  tools_override = server_info.get("_apm_tools_override")
442
443
  if tools_override:
443
444
  config["tools"] = tools_override
445
+ self._merge_extra(config, server_info)
444
446
  return config
445
447
 
446
448
  # Check for remote endpoints first (registry-defined priority)
@@ -483,6 +485,7 @@ class CopilotClientAdapter(MCPClientAdapter):
483
485
  if tools_override:
484
486
  config["tools"] = tools_override
485
487
 
488
+ self._merge_extra(config, server_info)
486
489
  return config
487
490
 
488
491
  # Get packages from server info
@@ -506,6 +509,7 @@ class CopilotClientAdapter(MCPClientAdapter):
506
509
  if tools_override:
507
510
  config["tools"] = tools_override
508
511
 
512
+ self._merge_extra(config, server_info)
509
513
  return config
510
514
 
511
515
  def _apply_auth_and_headers(
@@ -698,6 +702,7 @@ class CopilotClientAdapter(MCPClientAdapter):
698
702
  return translated
699
703
 
700
704
  if self._supports_runtime_env_substitution:
705
+ env_overrides = env_overrides or {}
701
706
  resolved = {}
702
707
  placeholder_keys = []
703
708
  for env_var in env_vars:
@@ -706,12 +711,18 @@ class CopilotClientAdapter(MCPClientAdapter):
706
711
  name = env_var.get("name", "")
707
712
  if not name:
708
713
  continue
714
+ required = registry_field_is_required(env_var)
715
+ override_value = env_overrides.get(name)
716
+ has_override = bool(
717
+ override_value.strip() if isinstance(override_value, str) else override_value
718
+ )
709
719
  if name in default_github_env:
710
720
  # Non-secret literal default -- preserve as-is.
711
721
  resolved[name] = default_github_env[name]
712
- else:
722
+ elif required or has_override:
713
723
  # Emit a runtime-substitution placeholder; APM never reads
714
- # or stores the value.
724
+ # or stores the value. Optional variables are included only
725
+ # when install-time collection observed a value.
715
726
  resolved[name] = self._format_runtime_env_placeholder(name)
716
727
  placeholder_keys.append(name)
717
728
  # Record for the post-install summary line and the
@@ -148,6 +148,7 @@ class CursorClientAdapter(CopilotClientAdapter):
148
148
  else arg
149
149
  for arg in args
150
150
  ]
151
+ self._merge_extra(config, server_info)
151
152
  return config
152
153
 
153
154
  # --- remote endpoints ---
@@ -169,6 +170,7 @@ class CursorClientAdapter(CopilotClientAdapter):
169
170
  config["url"] = (remote.get("url") or "").strip()
170
171
 
171
172
  self._apply_auth_and_headers(config, remote, server_info, env_overrides, "Cursor")
173
+ self._merge_extra(config, server_info)
172
174
  return config
173
175
 
174
176
  # --- local packages ---
@@ -194,6 +196,7 @@ class CursorClientAdapter(CopilotClientAdapter):
194
196
  f"{[p.get('registry_name', 'unknown') for p in packages]}."
195
197
  )
196
198
 
199
+ self._merge_extra(config, server_info)
197
200
  return config
198
201
 
199
202
  # ------------------------------------------------------------------ #
@@ -61,7 +61,7 @@ class GeminiClientAdapter(CopilotClientAdapter):
61
61
  # revisit in a follow-up.
62
62
  _supports_runtime_env_substitution: bool = False
63
63
 
64
- def _get_gemini_dir(self) -> Path:
64
+ def _get_config_dir(self) -> Path:
65
65
  """Return the ``.gemini`` directory for the active scope."""
66
66
  if self.user_scope:
67
67
  return Path.home() / ".gemini"
@@ -69,22 +69,24 @@ class GeminiClientAdapter(CopilotClientAdapter):
69
69
 
70
70
  def get_config_path(self):
71
71
  """Return the path to ``settings.json`` for the active scope."""
72
- return str(self._get_gemini_dir() / "settings.json")
72
+ return str(self._get_config_dir() / "settings.json")
73
73
 
74
74
  def update_config(self, config_updates):
75
75
  """Merge *config_updates* into the ``mcpServers`` section of settings.json.
76
76
 
77
- Project scope is opt-in: if ``<project_root>/.gemini/`` does not
77
+ Project scope is opt-in: if the target config directory does not
78
78
  exist, this method returns silently. User scope always writes,
79
- creating ``~/.gemini/`` if needed.
79
+ creating the directory if needed.
80
80
 
81
81
  Preserves all other top-level keys in settings.json (theme, tools,
82
82
  hooks, etc.).
83
83
  """
84
- gemini_dir = self._get_gemini_dir()
85
- if not self.user_scope and not gemini_dir.is_dir():
84
+ config_dir = self._get_config_dir()
85
+ if not self.user_scope and not config_dir.is_dir():
86
86
  logger.debug(
87
- "Skipping Gemini project-scope write -- %s does not exist (opt-in)", gemini_dir
87
+ "Skipping %s project-scope write -- %s does not exist (opt-in)",
88
+ self.target_name,
89
+ config_dir,
88
90
  )
89
91
  return
90
92
 
@@ -97,7 +99,9 @@ class GeminiClientAdapter(CopilotClientAdapter):
97
99
  current_config["mcpServers"][name] = entry
98
100
 
99
101
  if not config_path.parent.is_dir():
100
- logger.debug("Creating %s for Gemini CLI user configuration", config_path.parent)
102
+ logger.debug(
103
+ "Creating %s for %s user configuration", config_path.parent, self.target_name
104
+ )
101
105
  config_path.parent.mkdir(parents=True, exist_ok=True)
102
106
  with open(config_path, "w", encoding="utf-8") as f:
103
107
  json.dump(current_config, f, indent=2)
@@ -151,13 +155,16 @@ class GeminiClientAdapter(CopilotClientAdapter):
151
155
  raw["env"], env_overrides=env_overrides
152
156
  )
153
157
  config["env"] = resolved_env_for_args
154
- self._warn_input_variables(raw["env"], server_info.get("name", ""), "Gemini CLI")
158
+ self._warn_input_variables(
159
+ raw["env"], server_info.get("name", ""), self.target_name
160
+ )
155
161
  config["args"] = [
156
162
  self._resolve_variable_placeholders(arg, resolved_env_for_args, runtime_vars)
157
163
  if isinstance(arg, str)
158
164
  else arg
159
165
  for arg in raw.get("args") or []
160
166
  ]
167
+ self._merge_extra(config, server_info)
161
168
  return config
162
169
 
163
170
  # --- remote endpoints ---
@@ -170,7 +177,7 @@ class GeminiClientAdapter(CopilotClientAdapter):
170
177
  transport = "http"
171
178
  elif transport not in ("sse", "http", "streamable-http"):
172
179
  raise ValueError(
173
- f"Unsupported remote transport '{transport}' for Gemini. "
180
+ f"Unsupported remote transport '{transport}' for {self.target_name}. "
174
181
  f"Server: {server_info.get('name', 'unknown')}. "
175
182
  f"Supported transports: http, sse, streamable-http."
176
183
  )
@@ -192,9 +199,10 @@ class GeminiClientAdapter(CopilotClientAdapter):
192
199
 
193
200
  if config.get("headers"):
194
201
  self._warn_input_variables(
195
- config["headers"], server_info.get("name", ""), "Gemini CLI"
202
+ config["headers"], server_info.get("name", ""), self.target_name
196
203
  )
197
204
 
205
+ self._merge_extra(config, server_info)
198
206
  return config
199
207
 
200
208
  # --- local packages ---
@@ -208,6 +216,7 @@ class GeminiClientAdapter(CopilotClientAdapter):
208
216
 
209
217
  package = self._select_best_package(packages)
210
218
  if not package:
219
+ self._merge_extra(config, server_info)
211
220
  return config
212
221
 
213
222
  registry_name = self._infer_registry_name(package)
@@ -245,6 +254,7 @@ class GeminiClientAdapter(CopilotClientAdapter):
245
254
  if resolved_env:
246
255
  config["env"] = resolved_env
247
256
 
257
+ self._merge_extra(config, server_info)
248
258
  return config
249
259
 
250
260
  def configure_mcp_server(
@@ -256,19 +266,20 @@ class GeminiClientAdapter(CopilotClientAdapter):
256
266
  server_info_cache=None,
257
267
  runtime_vars=None,
258
268
  ):
259
- """Configure an MCP server in ``.gemini/settings.json``.
269
+ """Configure an MCP server in the target's ``settings.json``.
260
270
 
261
271
  Delegates to the parent for config formatting, then writes to
262
- the Gemini CLI settings file.
272
+ the target CLI settings file.
263
273
  """
264
274
  if not server_url:
265
275
  _rich_error("server_url cannot be empty", symbol="error")
266
276
  return False
267
277
 
268
- if not self.user_scope and not self._get_gemini_dir().is_dir():
278
+ if not self.user_scope and not self._get_config_dir().is_dir():
269
279
  logger.debug(
270
- "Gemini opt-in gate: %s absent, skipping configure_mcp_server",
271
- self._get_gemini_dir(),
280
+ "%s opt-in gate: %s absent, skipping configure_mcp_server",
281
+ self.target_name,
282
+ self._get_config_dir(),
272
283
  )
273
284
  return True
274
285
 
@@ -292,10 +303,16 @@ class GeminiClientAdapter(CopilotClientAdapter):
292
303
  server_config = self._format_server_config(server_info, env_overrides, runtime_vars)
293
304
  self.update_config({config_key: server_config})
294
305
 
295
- _rich_success(f"Configured MCP server '{config_key}' for Gemini CLI", symbol="success")
306
+ _rich_success(
307
+ f"Configured MCP server '{config_key}' for {self.target_name}",
308
+ symbol="success",
309
+ )
296
310
  return True
297
311
 
298
312
  except Exception as e:
299
- logger.debug("Gemini MCP configuration failed: %s", e)
300
- _rich_error("Failed to configure MCP server for Gemini CLI", symbol="error")
313
+ logger.debug("%s MCP configuration failed: %s", self.target_name, e)
314
+ _rich_error(
315
+ f"Failed to configure MCP server for {self.target_name}",
316
+ symbol="error",
317
+ )
301
318
  return False