apm-cli 0.21.0__tar.gz → 0.23.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 (420) hide show
  1. {apm_cli-0.21.0 → apm_cli-0.23.0}/NOTICE +2 -2
  2. {apm_cli-0.21.0/src/apm_cli.egg-info → apm_cli-0.23.0}/PKG-INFO +4 -4
  3. {apm_cli-0.21.0 → apm_cli-0.23.0}/README.md +1 -1
  4. {apm_cli-0.21.0 → apm_cli-0.23.0}/pyproject.toml +3 -3
  5. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/codex.py +13 -3
  6. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/bundle/local_bundle.py +8 -2
  7. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/bundle/lockfile_enrichment.py +7 -9
  8. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/bundle/packer.py +2 -2
  9. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/bundle/plugin_exporter.py +14 -5
  10. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/bundle/unpacker.py +12 -15
  11. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/cli.py +8 -2
  12. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/_apm_yml_writer.py +41 -10
  13. apm_cli-0.23.0/src/apm_cli/commands/approve.py +505 -0
  14. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/compile/cli.py +153 -12
  15. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/compile/watcher.py +0 -4
  16. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/config.py +139 -0
  17. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/deps/_utils.py +4 -4
  18. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/deps/cli.py +12 -4
  19. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/init.py +5 -3
  20. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/install.py +21 -20
  21. apm_cli-0.23.0/src/apm_cli/commands/lifecycle.py +591 -0
  22. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/__init__.py +1 -0
  23. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/doctor.py +80 -0
  24. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/plugin/__init__.py +5 -1
  25. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/mcp.py +3 -2
  26. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/outdated.py +14 -2
  27. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/pack.py +3 -20
  28. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/policy.py +21 -0
  29. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/run.py +4 -3
  30. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/self_update.py +65 -5
  31. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/uninstall/cli.py +64 -0
  32. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/update.py +82 -6
  33. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/view.py +272 -17
  34. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/__init__.py +4 -0
  35. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/agents_compiler.py +9 -8
  36. apm_cli-0.23.0/src/apm_cli/compilation/user_root_context.py +305 -0
  37. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/config.py +125 -1
  38. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/build_orchestrator.py +4 -4
  39. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/experimental.py +2 -2
  40. apm_cli-0.23.0/src/apm_cli/core/lifecycle_scripts.py +622 -0
  41. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/plugin_manifest.py +6 -2
  42. apm_cli-0.23.0/src/apm_cli/core/script_executors.py +1853 -0
  43. apm_cli-0.23.0/src/apm_cli/core/script_trust.py +350 -0
  44. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/target_detection.py +30 -2
  45. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/aggregator.py +2 -2
  46. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/dependency_graph.py +13 -2
  47. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/download_strategies.py +1 -1
  48. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/github_downloader.py +0 -1
  49. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/installed_package.py +4 -0
  50. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/lockfile.py +76 -14
  51. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/package_validator.py +5 -5
  52. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/plugin_parser.py +41 -12
  53. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/registry/client.py +92 -29
  54. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/registry/config_loader.py +26 -18
  55. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/registry/resolver.py +11 -2
  56. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/revision_pins.py +2 -2
  57. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/artifactory_resolver.py +7 -1
  58. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/cache_pin.py +17 -10
  59. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/context.py +15 -6
  60. apm_cli-0.23.0/src/apm_cli/install/deployed_paths.py +70 -0
  61. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/drift.py +27 -14
  62. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/exec_gate.py +36 -8
  63. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/local_bundle_handler.py +6 -3
  64. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/cleanup.py +24 -3
  65. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/finalize.py +69 -0
  66. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/integrate.py +68 -21
  67. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/lockfile.py +96 -1
  68. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/resolve.py +17 -7
  69. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/targets.py +16 -1
  70. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/pipeline.py +0 -2
  71. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/plan.py +22 -1
  72. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/request.py +0 -6
  73. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/service.py +64 -2
  74. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/services.py +122 -110
  75. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/skill_path_migration.py +6 -1
  76. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/sources.py +39 -2
  77. apm_cli-0.23.0/src/apm_cli/install/target_filter.py +33 -0
  78. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/template.py +59 -1
  79. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/agent_integrator.py +22 -22
  80. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/base_integrator.py +95 -14
  81. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/canvas_integrator.py +17 -16
  82. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/command_integrator.py +50 -13
  83. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/copilot_app_workflow_integrator.py +2 -3
  84. apm_cli-0.23.0/src/apm_cli/integration/hook_file_routing.py +120 -0
  85. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/hook_integrator.py +77 -65
  86. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/instruction_integrator.py +25 -14
  87. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/kiro_hook_integrator.py +10 -2
  88. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/lsp_integrator.py +3 -2
  89. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/mcp_integrator.py +55 -40
  90. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/prompt_integrator.py +7 -5
  91. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/skill_integrator.py +23 -19
  92. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/skill_transformer.py +2 -1
  93. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/targets.py +14 -4
  94. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/audit.py +2 -1
  95. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/builder.py +48 -15
  96. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/client.py +235 -31
  97. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/models.py +6 -2
  98. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/resolver.py +32 -3
  99. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/version_check.py +6 -1
  100. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/apm_package.py +1 -1
  101. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/dependency/reference.py +16 -25
  102. apm_cli-0.23.0/src/apm_cli/models/dependency/subsets.py +94 -0
  103. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/validation.py +7 -8
  104. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/_help_text.py +3 -1
  105. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/discovery.py +228 -12
  106. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/inheritance.py +21 -1
  107. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/models.py +1 -0
  108. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/parser.py +51 -1
  109. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/policy_checks.py +78 -10
  110. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/project_config.py +4 -2
  111. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/schema.py +38 -0
  112. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/primitives/discovery.py +3 -9
  113. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/primitives/parser.py +10 -13
  114. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/registry/client.py +74 -14
  115. apm_cli-0.23.0/src/apm_cli/security/executables.py +1157 -0
  116. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/update_policy.py +1 -1
  117. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/atomic_io.py +25 -2
  118. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/github_host.py +72 -3
  119. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/version_checker.py +42 -12
  120. apm_cli-0.23.0/src/apm_cli/utils/yaml_io.py +401 -0
  121. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/workflow/parser.py +2 -2
  122. {apm_cli-0.21.0 → apm_cli-0.23.0/src/apm_cli.egg-info}/PKG-INFO +4 -4
  123. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli.egg-info/SOURCES.txt +9 -0
  124. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli.egg-info/requires.txt +2 -2
  125. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_apm_package_models.py +3 -3
  126. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_enhanced_discovery.py +17 -17
  127. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_github_downloader.py +0 -1
  128. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_lockfile.py +242 -0
  129. apm_cli-0.21.0/src/apm_cli/commands/approve.py +0 -265
  130. apm_cli-0.21.0/src/apm_cli/security/executables.py +0 -435
  131. apm_cli-0.21.0/src/apm_cli/utils/yaml_io.py +0 -95
  132. {apm_cli-0.21.0 → apm_cli-0.23.0}/AUTHORS +0 -0
  133. {apm_cli-0.21.0 → apm_cli-0.23.0}/LICENSE +0 -0
  134. {apm_cli-0.21.0 → apm_cli-0.23.0}/setup.cfg +0 -0
  135. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/__init__.py +0 -0
  136. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/__init__.py +0 -0
  137. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/__init__.py +0 -0
  138. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
  139. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/antigravity.py +0 -0
  140. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/base.py +0 -0
  141. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/claude.py +0 -0
  142. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/copilot.py +0 -0
  143. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/cursor.py +0 -0
  144. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/gemini.py +0 -0
  145. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/hermes.py +0 -0
  146. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/intellij.py +0 -0
  147. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/kiro.py +0 -0
  148. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/opencode.py +0 -0
  149. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/vscode.py +0 -0
  150. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/client/windsurf.py +0 -0
  151. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
  152. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/package_manager/base.py +0 -0
  153. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
  154. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/bootstrap_mirror.py +0 -0
  155. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/bundle/__init__.py +0 -0
  156. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/cache/__init__.py +0 -0
  157. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/cache/git_cache.py +0 -0
  158. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/cache/http_cache.py +0 -0
  159. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/cache/integrity.py +0 -0
  160. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/cache/locking.py +0 -0
  161. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/cache/paths.py +0 -0
  162. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/cache/url_normalize.py +0 -0
  163. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/__init__.py +0 -0
  164. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/_helpers.py +0 -0
  165. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/audit.py +0 -0
  166. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/cache.py +0 -0
  167. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/compile/__init__.py +0 -0
  168. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/deps/__init__.py +0 -0
  169. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/deps/why.py +0 -0
  170. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/doctor.py +0 -0
  171. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/experimental.py +0 -0
  172. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/find.py +0 -0
  173. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/list_cmd.py +0 -0
  174. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/lock.py +0 -0
  175. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/audit.py +0 -0
  176. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/check.py +0 -0
  177. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/init.py +0 -0
  178. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/migrate.py +0 -0
  179. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/outdated.py +0 -0
  180. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/plugin/add.py +0 -0
  181. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/plugin/remove.py +0 -0
  182. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
  183. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/marketplace/validate.py +0 -0
  184. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/plugin/__init__.py +0 -0
  185. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/plugin/init.py +0 -0
  186. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/prune.py +0 -0
  187. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/publish.py +0 -0
  188. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/runtime.py +0 -0
  189. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/targets.py +0 -0
  190. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/uninstall/__init__.py +0 -0
  191. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/commands/uninstall/engine.py +0 -0
  192. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/build_id.py +0 -0
  193. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/claude_formatter.py +0 -0
  194. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/constants.py +0 -0
  195. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/constitution.py +0 -0
  196. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/constitution_block.py +0 -0
  197. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/context_optimizer.py +0 -0
  198. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/distributed_compiler.py +0 -0
  199. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/gemini_formatter.py +0 -0
  200. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/injector.py +0 -0
  201. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/link_resolver.py +0 -0
  202. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/managed_section.py +0 -0
  203. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/output_writer.py +0 -0
  204. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/compilation/template_builder.py +0 -0
  205. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/constants.py +0 -0
  206. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/__init__.py +0 -0
  207. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/apm_yml.py +0 -0
  208. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/auth.py +0 -0
  209. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/azure_cli.py +0 -0
  210. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/command_logger.py +0 -0
  211. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/conflict_detector.py +0 -0
  212. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/docker_args.py +0 -0
  213. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/errors.py +0 -0
  214. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/install_audit.py +0 -0
  215. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/null_logger.py +0 -0
  216. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/operations.py +0 -0
  217. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/safe_installer.py +0 -0
  218. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/scope.py +0 -0
  219. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/script_runner.py +0 -0
  220. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/core/token_manager.py +0 -0
  221. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/__init__.py +0 -0
  222. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/_shared.py +0 -0
  223. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/apm_resolver.py +0 -0
  224. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/artifactory_entry.py +0 -0
  225. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
  226. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/bare_cache.py +0 -0
  227. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/clone_engine.py +0 -0
  228. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/git_auth_env.py +0 -0
  229. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/git_file_transport.py +0 -0
  230. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/git_reference_resolver.py +0 -0
  231. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/git_remote_ops.py +0 -0
  232. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/git_semver_resolver.py +0 -0
  233. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/github_downloader_validation.py +0 -0
  234. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/host_backends.py +0 -0
  235. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/outdated_row.py +0 -0
  236. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/path_anchoring.py +0 -0
  237. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/registry/__init__.py +0 -0
  238. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/registry/auth.py +0 -0
  239. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/registry/extractor.py +0 -0
  240. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/registry/feature_gate.py +0 -0
  241. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/registry/outdated.py +0 -0
  242. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/registry/semver.py +0 -0
  243. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/registry_proxy.py +0 -0
  244. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/shared_clone_cache.py +0 -0
  245. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/tiered_ref_resolver.py +0 -0
  246. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/transport_selection.py +0 -0
  247. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/verifier.py +0 -0
  248. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/deps/why_walker.py +0 -0
  249. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/drift.py +0 -0
  250. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/export/__init__.py +0 -0
  251. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/export/authoring.py +0 -0
  252. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/export/declared_license.py +0 -0
  253. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/export/formats.py +0 -0
  254. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/export/purl.py +0 -0
  255. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/export/sbom.py +0 -0
  256. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/export/spdx.py +0 -0
  257. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/export/spdx_data.py +0 -0
  258. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/factory.py +0 -0
  259. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/__init__.py +0 -0
  260. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/errors.py +0 -0
  261. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/gitlab_resolver.py +0 -0
  262. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/heals/__init__.py +0 -0
  263. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/heals/base.py +0 -0
  264. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
  265. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
  266. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/helpers/__init__.py +0 -0
  267. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/helpers/security_scan.py +0 -0
  268. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/insecure_policy.py +0 -0
  269. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/integrity.py +0 -0
  270. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/lsp/__init__.py +0 -0
  271. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/lsp/integration.py +0 -0
  272. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/manifest_reconcile.py +0 -0
  273. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/mcp/__init__.py +0 -0
  274. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/mcp/args.py +0 -0
  275. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/mcp/command.py +0 -0
  276. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/mcp/conflicts.py +0 -0
  277. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/mcp/entry.py +0 -0
  278. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/mcp/registry.py +0 -0
  279. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/mcp/warnings.py +0 -0
  280. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/mcp/writer.py +0 -0
  281. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/package_resolution.py +0 -0
  282. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/package_selection.py +0 -0
  283. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/__init__.py +0 -0
  284. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/_redownload.py +0 -0
  285. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/_skip_logic.py +0 -0
  286. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/audit.py +0 -0
  287. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/download.py +0 -0
  288. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/heal.py +0 -0
  289. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/local_content.py +0 -0
  290. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/policy_gate.py +0 -0
  291. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/policy_target_check.py +0 -0
  292. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/phases/post_deps_local.py +0 -0
  293. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/presentation/__init__.py +0 -0
  294. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/presentation/dry_run.py +0 -0
  295. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/registry_wiring.py +0 -0
  296. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/root_redirect.py +0 -0
  297. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/summary.py +0 -0
  298. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/install/validation.py +0 -0
  299. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/__init__.py +0 -0
  300. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/_shared.py +0 -0
  301. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/cleanup.py +0 -0
  302. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/copilot_app_db.py +0 -0
  303. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/copilot_app_project.py +0 -0
  304. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/copilot_app_ws.py +0 -0
  305. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
  306. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/coverage.py +0 -0
  307. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/dispatch.py +0 -0
  308. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/mcp_integrator_install.py +0 -0
  309. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
  310. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/integration/utils.py +0 -0
  311. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/__init__.py +0 -0
  312. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/_git_utils.py +0 -0
  313. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/_io.py +0 -0
  314. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/_shared.py +0 -0
  315. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/auth_helpers.py +0 -0
  316. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/diagnostics.py +0 -0
  317. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/drift_check.py +0 -0
  318. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/errors.py +0 -0
  319. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/git_stderr.py +0 -0
  320. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/init_template.py +0 -0
  321. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/migration.py +0 -0
  322. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/output_mappers.py +0 -0
  323. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/output_profiles.py +0 -0
  324. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/ref_resolver.py +0 -0
  325. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/registry.py +0 -0
  326. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/semver.py +0 -0
  327. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/shadow_detector.py +0 -0
  328. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/tag_pattern.py +0 -0
  329. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/validator.py +0 -0
  330. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/version_pins.py +0 -0
  331. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/version_resolver.py +0 -0
  332. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/yml_editor.py +0 -0
  333. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/marketplace/yml_schema.py +0 -0
  334. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/__init__.py +0 -0
  335. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/dependency/__init__.py +0 -0
  336. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/dependency/identity.py +0 -0
  337. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/dependency/lsp.py +0 -0
  338. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/dependency/mcp.py +0 -0
  339. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/dependency/types.py +0 -0
  340. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/format_detection.py +0 -0
  341. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/plugin.py +0 -0
  342. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/models/results.py +0 -0
  343. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/output/__init__.py +0 -0
  344. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/output/formatters.py +0 -0
  345. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/output/models.py +0 -0
  346. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/output/script_formatters.py +0 -0
  347. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/__init__.py +0 -0
  348. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/_constraint_pinning.py +0 -0
  349. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/_shared.py +0 -0
  350. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/ci_checks.py +0 -0
  351. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/install_preflight.py +0 -0
  352. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/matcher.py +0 -0
  353. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/policy/outcome_routing.py +0 -0
  354. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/primitives/__init__.py +0 -0
  355. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/primitives/models.py +0 -0
  356. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/registry/__init__.py +0 -0
  357. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/registry/integration.py +0 -0
  358. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/registry/operations.py +0 -0
  359. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/runtime/__init__.py +0 -0
  360. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/runtime/base.py +0 -0
  361. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/runtime/codex_runtime.py +0 -0
  362. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/runtime/copilot_runtime.py +0 -0
  363. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/runtime/factory.py +0 -0
  364. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/runtime/llm_runtime.py +0 -0
  365. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/runtime/manager.py +0 -0
  366. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/runtime/utils.py +0 -0
  367. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/__init__.py +0 -0
  368. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/audit_report.py +0 -0
  369. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/content_scanner.py +0 -0
  370. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/external/__init__.py +0 -0
  371. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/external/base.py +0 -0
  372. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/external/gate.py +0 -0
  373. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/external/generic_sarif.py +0 -0
  374. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/external/options.py +0 -0
  375. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/external/registry.py +0 -0
  376. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/external/runner.py +0 -0
  377. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/external/sarif_ingest.py +0 -0
  378. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/external/skillspector.py +0 -0
  379. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/file_scanner.py +0 -0
  380. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/security/gate.py +0 -0
  381. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/__init__.py +0 -0
  382. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/archive.py +0 -0
  383. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/console.py +0 -0
  384. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/content_hash.py +0 -0
  385. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/diagnostics.py +0 -0
  386. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/exclude.py +0 -0
  387. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/file_ops.py +0 -0
  388. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/git_env.py +0 -0
  389. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/git_sparse.py +0 -0
  390. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/guards.py +0 -0
  391. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/helpers.py +0 -0
  392. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/install_tui.py +0 -0
  393. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/normalization.py +0 -0
  394. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/path_security.py +0 -0
  395. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/paths.py +0 -0
  396. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/patterns.py +0 -0
  397. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/perf_stats.py +0 -0
  398. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/reflink.py +0 -0
  399. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/short_sha.py +0 -0
  400. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/utils/subprocess_env.py +0 -0
  401. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/version.py +0 -0
  402. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/workflow/__init__.py +0 -0
  403. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/workflow/discovery.py +0 -0
  404. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli/workflow/runner.py +0 -0
  405. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli.egg-info/dependency_links.txt +0 -0
  406. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli.egg-info/entry_points.txt +0 -0
  407. {apm_cli-0.21.0 → apm_cli-0.23.0}/src/apm_cli.egg-info/top_level.txt +0 -0
  408. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_apm_resolver.py +0 -0
  409. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_codex_docker_args_fix.py +0 -0
  410. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_codex_empty_string_and_defaults.py +0 -0
  411. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_collision_integration.py +0 -0
  412. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_console.py +0 -0
  413. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_distributed_compilation.py +0 -0
  414. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_empty_string_and_defaults.py +0 -0
  415. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_github_downloader_token_precedence.py +0 -0
  416. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_gitlab_git_transport.py +0 -0
  417. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_runnable_prompts.py +0 -0
  418. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_runtime_manager_token_precedence.py +0 -0
  419. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_token_manager.py +0 -0
  420. {apm_cli-0.21.0 → apm_cli-0.23.0}/tests/test_virtual_package_multi_install.py +0 -0
@@ -372,7 +372,7 @@ THE SOFTWARE.
372
372
 
373
373
  ## Component. llm
374
374
 
375
- - Version requirement: `>=0.17.0`
375
+ - Version requirement: `>=0.28`
376
376
  - Upstream: https://github.com/simonw/llm
377
377
  - SPDX: `Apache-2.0`
378
378
  - Notes: No NOTICE or AUTHORS file present upstream; nothing additional to forward.
@@ -589,7 +589,7 @@ _Copyright Simon Willison (per PyPI author metadata; LICENSE file is the unmodif
589
589
 
590
590
  ## Component. llm-github-models
591
591
 
592
- - Version requirement: `>=0.1.0`
592
+ - Version requirement: `>=0.18.0`
593
593
  - Upstream: https://github.com/tonybaloney/llm-github-models
594
594
  - SPDX: `Apache-2.0`
595
595
  - Notes: Upstream LICENSE file declares MIT license text but PyPI metadata + classifiers say Apache-2.0. See Open Issues.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apm-cli
3
- Version: 0.21.0
3
+ Version: 0.23.0
4
4
  Summary: MCP configuration tool
5
5
  Author-email: Daniel Meppiel <user@example.com>
6
6
  License: MIT License
@@ -42,8 +42,8 @@ Requires-Dist: colorama>=0.4.6
42
42
  Requires-Dist: pyyaml>=6.0.0
43
43
  Requires-Dist: requests>=2.31.0
44
44
  Requires-Dist: python-frontmatter>=1.0.0
45
- Requires-Dist: llm>=0.17.0
46
- Requires-Dist: llm-github-models>=0.1.0
45
+ Requires-Dist: llm>=0.28
46
+ Requires-Dist: llm-github-models>=0.18.0
47
47
  Requires-Dist: tomli>=1.2.0; python_version < "3.11"
48
48
  Requires-Dist: toml>=0.10.2
49
49
  Requires-Dist: rich>=13.0.0
@@ -178,7 +178,7 @@ curl -sSL https://aka.ms/apm-unix | sh
178
178
  irm https://aka.ms/apm-windows | iex
179
179
  ```
180
180
 
181
- Native release binaries are published for macOS, Linux, and Windows x86_64. `apm update` reuses the matching platform installer.
181
+ Native release binaries are published for macOS, Linux, and Windows x86_64. `apm self-update` reuses the matching platform installer.
182
182
 
183
183
  <details>
184
184
  <summary>Other install methods</summary>
@@ -110,7 +110,7 @@ curl -sSL https://aka.ms/apm-unix | sh
110
110
  irm https://aka.ms/apm-windows | iex
111
111
  ```
112
112
 
113
- Native release binaries are published for macOS, Linux, and Windows x86_64. `apm update` reuses the matching platform installer.
113
+ Native release binaries are published for macOS, Linux, and Windows x86_64. `apm self-update` reuses the matching platform installer.
114
114
 
115
115
  <details>
116
116
  <summary>Other install methods</summary>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "apm-cli"
7
- version = "0.21.0"
7
+ version = "0.23.0"
8
8
  description = "MCP configuration tool"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -27,8 +27,8 @@ dependencies = [
27
27
  "pyyaml>=6.0.0",
28
28
  "requests>=2.31.0",
29
29
  "python-frontmatter>=1.0.0",
30
- "llm>=0.17.0",
31
- "llm-github-models>=0.1.0",
30
+ "llm>=0.28",
31
+ "llm-github-models>=0.18.0",
32
32
  "tomli>=1.2.0; python_version<'3.11'",
33
33
  "toml>=0.10.2",
34
34
  "rich>=13.0.0",
@@ -10,6 +10,7 @@ import toml
10
10
  from ...registry.client import SimpleRegistryClient
11
11
  from ...registry.integration import RegistryIntegration
12
12
  from ...utils.console import _rich_success, _rich_warning
13
+ from ...utils.path_security import PathTraversalError
13
14
  from ._mcp_runtime_args import process_v01_value_hint_arg
14
15
  from .base import MCPClientAdapter
15
16
 
@@ -49,13 +50,22 @@ class CodexClientAdapter(MCPClientAdapter):
49
50
  self.registry_client = SimpleRegistryClient(registry_url)
50
51
  self.registry_integration = RegistryIntegration(registry_url)
51
52
 
52
- def _get_codex_dir(self):
53
+ def _get_codex_dir(self) -> Path:
53
54
  """Return the root directory used for Codex config in the current scope."""
54
55
  if self.user_scope:
56
+ codex_home = os.environ.get("CODEX_HOME", "")
57
+ if codex_home.strip():
58
+ codex_home_path = Path(codex_home).expanduser()
59
+ if not codex_home_path.is_absolute():
60
+ raise PathTraversalError(
61
+ "CODEX_HOME is set to a non-absolute path; cannot locate the "
62
+ "Codex CLI configuration directory."
63
+ )
64
+ return codex_home_path
55
65
  return Path.home() / ".codex"
56
66
  return self.project_root / ".codex"
57
67
 
58
- def get_config_path(self):
68
+ def get_config_path(self) -> str:
59
69
  """Get the path to the Codex CLI MCP configuration file.
60
70
 
61
71
  Returns:
@@ -322,7 +332,7 @@ class CodexClientAdapter(MCPClientAdapter):
322
332
  all_args = processed_runtime_args + processed_package_args
323
333
  if all_args:
324
334
  # If runtime_arguments already include the package (bare or
325
- # versioned), use them as-is they are authoritative from
335
+ # versioned), use them as-is -- they are authoritative from
326
336
  # the registry and may carry a version pin.
327
337
  has_pkg = any(
328
338
  a == package_name or a.startswith(f"{package_name}@") for a in all_args
@@ -47,6 +47,7 @@ from ..utils.path_security import (
47
47
  ensure_path_within,
48
48
  validate_path_segments,
49
49
  )
50
+ from ..utils.yaml_io import load_yaml_str
50
51
 
51
52
  _MAX_ZIP_ENTRIES = MAX_ZIP_ENTRIES
52
53
  _MAX_ZIP_UNCOMPRESSED = MAX_ZIP_UNCOMPRESSED
@@ -93,7 +94,12 @@ def read_bundle_plugin_json(bundle_dir: Path) -> dict[str, Any]:
93
94
  return {}
94
95
  try:
95
96
  data = json.loads(pj_path.read_text(encoding="utf-8"))
96
- except (json.JSONDecodeError, OSError):
97
+ except (OSError, ValueError, RecursionError):
98
+ # json.JSONDecodeError is a ValueError subclass; the wider set also
99
+ # fails closed on a deeply-nested JSON (RecursionError) or an
100
+ # oversized-integer literal (bare ValueError from int_max_str_digits)
101
+ # in an untrusted bundle's plugin.json -- the same fail-closed posture
102
+ # parse_script_file / _load_trust_store take.
97
103
  return {}
98
104
  return data if isinstance(data, dict) else {}
99
105
 
@@ -104,7 +110,7 @@ def _read_bundle_lockfile(bundle_dir: Path) -> dict[str, Any] | None:
104
110
  if not lf_path.is_file():
105
111
  return None
106
112
  try:
107
- data = yaml.safe_load(lf_path.read_text(encoding="utf-8"))
113
+ data = load_yaml_str(lf_path.read_text(encoding="utf-8"))
108
114
  except (yaml.YAMLError, OSError):
109
115
  return None
110
116
  return data if isinstance(data, dict) else None
@@ -13,12 +13,10 @@ from ..integration.targets import KNOWN_TARGETS
13
13
  # .github/ is the canonical interop prefix -- install always creates it, so
14
14
  # all non-github targets map FROM .github/. The copilot target additionally
15
15
  # maps FROM .claude/ for the common case of Claude-first projects packing
16
- # for Copilot. Cursor/opencode sources are niche; if someone publishes
17
- # skills exclusively under .cursor/, they must pack with --target cursor.
18
- #
19
- # Windsurf converts agents -> skills (lossy: AGENTS.md format is collapsed
20
- # into the windsurf skill envelope), so .github/agents/ maps to
21
- # .windsurf/skills/.
16
+ # for Copilot. Cursor, opencode, and windsurf skills converge on the
17
+ # shared .agents/skills/ convention rather than bespoke per-target paths.
18
+ # Windsurf agents still collapse into .windsurf/skills/ because the target
19
+ # has no distinct agent envelope.
22
20
  _CROSS_TARGET_MAPS: dict[str, dict[str, str]] = {
23
21
  "claude": {
24
22
  ".github/skills/": ".claude/skills/",
@@ -33,11 +31,11 @@ _CROSS_TARGET_MAPS: dict[str, dict[str, str]] = {
33
31
  ".claude/agents/": ".github/agents/",
34
32
  },
35
33
  "cursor": {
36
- ".github/skills/": ".cursor/skills/",
34
+ ".github/skills/": ".agents/skills/",
37
35
  ".github/agents/": ".cursor/agents/",
38
36
  },
39
37
  "opencode": {
40
- ".github/skills/": ".opencode/skills/",
38
+ ".github/skills/": ".agents/skills/",
41
39
  ".github/agents/": ".opencode/agents/",
42
40
  },
43
41
  "codex": {
@@ -45,7 +43,7 @@ _CROSS_TARGET_MAPS: dict[str, dict[str, str]] = {
45
43
  ".github/agents/": ".codex/agents/",
46
44
  },
47
45
  "windsurf": {
48
- ".github/skills/": ".windsurf/skills/",
46
+ ".github/skills/": ".agents/skills/",
49
47
  ".github/agents/": ".windsurf/skills/",
50
48
  },
51
49
  "agent-skills": {
@@ -104,10 +104,10 @@ def pack_bundle(
104
104
  # at pack time -- this is the publish gate for the AUTHOR.
105
105
  if is_hybrid_root and not package.description and logger:
106
106
  try:
107
- import frontmatter as _frontmatter
107
+ from apm_cli.utils.yaml_io import load_frontmatter
108
108
 
109
109
  with open(skill_md_path, encoding="utf-8") as _f:
110
- _skill_post = _frontmatter.load(_f)
110
+ _skill_post = load_frontmatter(_f)
111
111
  _skill_desc = _skill_post.metadata.get("description")
112
112
  except Exception:
113
113
  _skill_desc = None
@@ -111,7 +111,7 @@ def _collect_apm_components(apm_dir: Path) -> list[tuple[Path, str]]:
111
111
  # extensions/ -> extensions/ (canvas extensions, experimental Copilot-only).
112
112
  # Preserved verbatim so an offline bundle can carry a canvas; the files are
113
113
  # inert until the consumer enables the ``canvas`` experimental flag AND
114
- # passes ``--trust-canvas-extensions`` at install time.
114
+ # approves the package via allowExecutables / ``apm approve`` at install time.
115
115
  _collect_recursive(apm_dir / "extensions", "extensions", components)
116
116
 
117
117
  return components
@@ -246,7 +246,9 @@ def _collect_hooks_from_apm(apm_dir: Path) -> dict:
246
246
  data = json.loads(f.read_text(encoding="utf-8"))
247
247
  if isinstance(data, dict):
248
248
  _deep_merge(hooks, data, overwrite=False)
249
- except (json.JSONDecodeError, OSError):
249
+ except (OSError, ValueError, RecursionError):
250
+ # Untrusted .apm/hooks/*.json: oversized-int -> bare ValueError,
251
+ # deep nest -> RecursionError. Fail closed (skip this file).
250
252
  pass
251
253
  return hooks
252
254
 
@@ -261,7 +263,9 @@ def _collect_hooks_from_root(package_root: Path) -> dict:
261
263
  data = json.loads(hooks_file.read_text(encoding="utf-8"))
262
264
  if isinstance(data, dict):
263
265
  _deep_merge(hooks, data, overwrite=False)
264
- except (json.JSONDecodeError, OSError):
266
+ except (OSError, ValueError, RecursionError):
267
+ # Untrusted root hooks.json: fail closed (oversized-int ValueError /
268
+ # deep-nest RecursionError are not JSONDecodeError).
265
269
  pass
266
270
  # Directory
267
271
  hooks_dir = package_root / "hooks"
@@ -272,7 +276,8 @@ def _collect_hooks_from_root(package_root: Path) -> dict:
272
276
  data = json.loads(f.read_text(encoding="utf-8"))
273
277
  if isinstance(data, dict):
274
278
  _deep_merge(hooks, data, overwrite=False)
275
- except (json.JSONDecodeError, OSError):
279
+ except (OSError, ValueError, RecursionError):
280
+ # Untrusted .../hooks/*.json: fail closed (skip this file).
276
281
  pass
277
282
  return hooks
278
283
 
@@ -356,7 +361,11 @@ def _has_marketplace_block(apm_yml_path: Path) -> bool:
356
361
  try:
357
362
  import yaml
358
363
 
359
- data = yaml.safe_load(apm_yml_path.read_text(encoding="utf-8")) or {}
364
+ # Bounded loader so a hostile apm.yml cannot wedge the export with a
365
+ # merge/alias expansion bomb (fails closed as yaml.YAMLError).
366
+ from apm_cli.utils.yaml_io import load_yaml
367
+
368
+ data = load_yaml(apm_yml_path) or {}
360
369
  except (OSError, yaml.YAMLError):
361
370
  return False
362
371
  return bool(data.get("marketplace"))
@@ -40,7 +40,6 @@ def unpack_bundle(
40
40
  skip_verify: bool = False,
41
41
  dry_run: bool = False,
42
42
  force: bool = False,
43
- trust_canvas: bool = False,
44
43
  ) -> UnpackResult:
45
44
  """Extract and apply an APM bundle to a project directory.
46
45
 
@@ -54,10 +53,6 @@ def unpack_bundle(
54
53
  skip_verify: If *True*, skip completeness verification against the lockfile.
55
54
  dry_run: If *True*, resolve the file list but write nothing to disk.
56
55
  force: If *True*, deploy even when critical hidden characters are found.
57
- trust_canvas: If *True*, allow executable canvas extension files
58
- (``.github/extensions/<name>/extension.mjs``) to be unpacked.
59
- Defaults to *False* (fail closed) so a vendored bundle cannot
60
- smuggle executable canvas code past the trust gate.
61
56
 
62
57
  Returns:
63
58
  :class:`UnpackResult` describing what was (or would be) extracted.
@@ -135,9 +130,12 @@ def unpack_bundle(
135
130
  # Extract pack: metadata (written by apm pack) before structured parse
136
131
  pack_meta: dict = {}
137
132
  try:
138
- import yaml
133
+ from ..utils.yaml_io import load_yaml
139
134
 
140
- raw = yaml.safe_load(lockfile_path.read_text(encoding="utf-8"))
135
+ # Bounded loader: an untrusted bundle lockfile cannot hang the
136
+ # unpacker with a merge-key bomb (the except below cannot catch a
137
+ # non-terminating safe_load loop).
138
+ raw = load_yaml(lockfile_path)
141
139
  if isinstance(raw, dict):
142
140
  val = raw.get("pack", {})
143
141
  pack_meta = val if isinstance(val, dict) else {}
@@ -170,18 +168,17 @@ def unpack_bundle(
170
168
  dep_file_map[dep_key] = dep_files
171
169
 
172
170
  # Security + feature gate: canvas extensions are executable Node
173
- # bundles (``extension.mjs``). ``apm unpack`` copies deployed files
174
- # verbatim WITHOUT routing through ``CanvasIntegrator``, so neither
175
- # the experimental feature flag nor its trust gate would otherwise
176
- # apply. Require BOTH gates -- the ``canvas`` experimental flag ON
177
- # (feature availability) AND ``trust_canvas`` (executable-code trust)
178
- # -- before unpacking canvas paths. Fail closed: drop them when
179
- # either gate is missing.
171
+ # bundles (``extension.mjs``). ``apm unpack`` (deprecated) copies
172
+ # deployed files verbatim WITHOUT routing through ``CanvasIntegrator``.
173
+ # When the canvas feature flag is OFF, drop paths silently.
174
+ # When ON, canvas files are allowed (apm unpack has no project context
175
+ # so no allowExecutables enforcement is available; the user is assumed
176
+ # to understand what they are unpacking for this deprecated command).
180
177
  canvas_blocked = 0
181
178
  from ..core.experimental import is_enabled
182
179
  from ..integration.canvas_integrator import is_canvas_bundle_path
183
180
 
184
- if not (is_enabled("canvas") and trust_canvas):
181
+ if not is_enabled("canvas"):
185
182
  _blocked = {f for f in unique_files if is_canvas_bundle_path(f)}
186
183
  if _blocked:
187
184
  canvas_blocked = len(_blocked)
@@ -29,6 +29,7 @@ from apm_cli.commands.experimental import experimental
29
29
  from apm_cli.commands.find import find as find_cmd
30
30
  from apm_cli.commands.init import init
31
31
  from apm_cli.commands.install import install
32
+ from apm_cli.commands.lifecycle import lifecycle
32
33
  from apm_cli.commands.list_cmd import list as list_cmd
33
34
  from apm_cli.commands.lock import lock
34
35
  from apm_cli.commands.marketplace import marketplace
@@ -142,8 +143,12 @@ def cli(ctx, verbose: bool) -> None:
142
143
 
143
144
  warnings.filterwarnings("ignore", category=AgentsTargetDeprecationWarning)
144
145
 
145
- # Check for updates non-blockingly (only if not already showing version)
146
- if not ctx.resilient_parsing:
146
+ # Check for updates only for known commands; skip on invalid input to fail fast.
147
+ if (
148
+ not ctx.resilient_parsing
149
+ and ctx.invoked_subcommand is not None
150
+ and ctx.command.get_command(ctx, ctx.invoked_subcommand) is not None
151
+ ):
147
152
  _check_and_notify_updates()
148
153
 
149
154
 
@@ -187,6 +192,7 @@ cli.add_command(mcp)
187
192
  cli.add_command(policy)
188
193
  cli.add_command(outdated_cmd, name="outdated")
189
194
  cli.add_command(doctor)
195
+ cli.add_command(lifecycle)
190
196
  cli.add_command(marketplace)
191
197
  cli.add_command(find_cmd)
192
198
  cli.add_command(marketplace_search, name="search")
@@ -1,8 +1,7 @@
1
- """Write-back helper for persisting skill subset selection in apm.yml.
1
+ """Write-back helpers for persisting dependency subset selection in apm.yml.
2
2
 
3
- Single helper ``set_skill_subset_for_entry`` is the one source of truth
4
- for promoting entries to dict form and setting/clearing the ``skills:``
5
- field. Keeps write-back logic isolated and unit-testable.
3
+ The helpers promote entries to dict form and set/clear the ``skills:`` or
4
+ ``targets:`` fields. Keeping write-back logic isolated makes it unit-testable.
6
5
  """
7
6
 
8
7
  from pathlib import Path
@@ -23,6 +22,31 @@ def set_skill_subset_for_entry(
23
22
 
24
23
  Returns True if file was modified.
25
24
  """
25
+ return _set_subset_for_entry(manifest_path, repo_url, "skills", subset)
26
+
27
+
28
+ def set_target_subset_for_entry(
29
+ manifest_path: Path,
30
+ repo_url: str,
31
+ subset: list[str] | None,
32
+ ) -> bool:
33
+ """Promote entry to dict form and set/clear targets: field.
34
+
35
+ subset=None or empty list -> remove targets: from entry (reset to all).
36
+ subset=[...] -> set targets: to sorted+deduped lowercase list.
37
+
38
+ Returns True if file was modified.
39
+ """
40
+ return _set_subset_for_entry(manifest_path, repo_url, "targets", subset)
41
+
42
+
43
+ def _set_subset_for_entry(
44
+ manifest_path: Path,
45
+ repo_url: str,
46
+ field: str,
47
+ subset: list[str] | None,
48
+ ) -> bool:
49
+ """Promote a matching entry to dict form and set/clear one subset field."""
26
50
  data = load_yaml(manifest_path) or {}
27
51
  deps_section = data.get("dependencies")
28
52
  if deps_section is None:
@@ -45,7 +69,7 @@ def set_skill_subset_for_entry(
45
69
 
46
70
  for entry in apm_deps:
47
71
  if _entry_matches(entry, repo_url):
48
- entry = _apply_subset(entry, subset)
72
+ entry = _apply_subset(entry, field, subset)
49
73
  modified = True
50
74
  new_deps.append(entry)
51
75
 
@@ -72,8 +96,13 @@ def _entry_matches(entry, repo_url: str) -> bool:
72
96
  return False
73
97
 
74
98
 
75
- def _apply_subset(entry, subset: list[str] | None):
76
- """Apply skill subset to an entry, promoting to dict form if needed."""
99
+ def _apply_subset(entry, field: str | list[str] | None, subset: list[str] | None = None):
100
+ """Apply a dependency subset field, promoting to dict form if needed."""
101
+ # Compatibility for older direct tests that called _apply_subset(entry, subset).
102
+ if not isinstance(field, str):
103
+ subset = field
104
+ field = "skills"
105
+
77
106
  # Parse current entry to get canonical info
78
107
  if isinstance(entry, str):
79
108
  ref = DependencyReference.parse(entry)
@@ -83,9 +112,11 @@ def _apply_subset(entry, subset: list[str] | None):
83
112
  return entry
84
113
 
85
114
  # Determine if we should set or clear
86
- if subset:
87
- ref.skill_subset = sorted(set(subset))
115
+ if field == "skills":
116
+ ref.skill_subset = sorted(set(subset)) if subset else None
117
+ elif field == "targets":
118
+ ref.target_subset = sorted({name.strip().lower() for name in subset}) if subset else None
88
119
  else:
89
- ref.skill_subset = None
120
+ raise ValueError(f"Unsupported dependency subset field: {field}")
90
121
 
91
122
  return ref.to_apm_yml_entry()