apm-cli 0.16.0__tar.gz → 0.17.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 (380) hide show
  1. {apm_cli-0.16.0/src/apm_cli.egg-info → apm_cli-0.17.0}/PKG-INFO +1 -1
  2. {apm_cli-0.16.0 → apm_cli-0.17.0}/pyproject.toml +9 -9
  3. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/copilot.py +5 -5
  4. apm_cli-0.17.0/src/apm_cli/adapters/client/intellij.py +99 -0
  5. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/vscode.py +0 -1
  6. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/bundle/lockfile_enrichment.py +0 -1
  7. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/bundle/packer.py +0 -2
  8. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/bundle/plugin_exporter.py +12 -49
  9. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/bundle/unpacker.py +0 -1
  10. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/cli.py +24 -1
  11. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/_apm_yml_writer.py +0 -1
  12. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/_helpers.py +91 -2
  13. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/audit.py +199 -24
  14. apm_cli-0.17.0/src/apm_cli/commands/compile/cli.py +1002 -0
  15. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/compile/watcher.py +44 -1
  16. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/config.py +179 -1
  17. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/deps/_utils.py +1 -1
  18. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/deps/cli.py +26 -32
  19. apm_cli-0.17.0/src/apm_cli/commands/doctor.py +32 -0
  20. apm_cli-0.17.0/src/apm_cli/commands/find.py +241 -0
  21. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/init.py +42 -1
  22. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/install.py +114 -58
  23. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/list_cmd.py +0 -1
  24. apm_cli-0.17.0/src/apm_cli/commands/lock.py +206 -0
  25. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/__init__.py +0 -2
  26. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/doctor.py +34 -7
  27. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/plugin/__init__.py +0 -2
  28. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/plugin/remove.py +1 -1
  29. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/mcp.py +17 -7
  30. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/outdated.py +0 -1
  31. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/pack.py +115 -72
  32. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/policy.py +1 -3
  33. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/prune.py +2 -2
  34. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/publish.py +36 -10
  35. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/self_update.py +37 -3
  36. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/uninstall/cli.py +30 -7
  37. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/uninstall/engine.py +14 -2
  38. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/update.py +140 -71
  39. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/view.py +1 -2
  40. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/agents_compiler.py +194 -45
  41. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/claude_formatter.py +34 -19
  42. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/constitution.py +0 -1
  43. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/constitution_block.py +0 -1
  44. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/context_optimizer.py +0 -2
  45. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/distributed_compiler.py +72 -27
  46. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/gemini_formatter.py +0 -1
  47. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/injector.py +1 -2
  48. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/link_resolver.py +0 -1
  49. apm_cli-0.17.0/src/apm_cli/compilation/managed_section.py +96 -0
  50. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/template_builder.py +17 -7
  51. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/config.py +222 -1
  52. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/constants.py +18 -0
  53. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/auth.py +10 -3
  54. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/azure_cli.py +0 -1
  55. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/build_orchestrator.py +129 -10
  56. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/command_logger.py +9 -4
  57. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/conflict_detector.py +1 -1
  58. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/docker_args.py +0 -2
  59. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/experimental.py +13 -0
  60. apm_cli-0.17.0/src/apm_cli/core/install_audit.py +176 -0
  61. apm_cli-0.17.0/src/apm_cli/core/plugin_manifest.py +467 -0
  62. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/safe_installer.py +1 -1
  63. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/scope.py +109 -9
  64. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/script_runner.py +0 -3
  65. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/target_detection.py +1 -1
  66. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/token_manager.py +1 -2
  67. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/aggregator.py +0 -3
  68. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/apm_resolver.py +1 -2
  69. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/artifactory_entry.py +1 -1
  70. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/dependency_graph.py +1 -2
  71. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/download_strategies.py +3 -2
  72. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/git_remote_ops.py +0 -1
  73. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/github_downloader.py +4 -4
  74. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/lockfile.py +12 -3
  75. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/package_validator.py +1 -2
  76. apm_cli-0.17.0/src/apm_cli/deps/path_anchoring.py +151 -0
  77. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/plugin_parser.py +25 -4
  78. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/registry_proxy.py +1 -1
  79. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/transport_selection.py +2 -2
  80. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/verifier.py +0 -3
  81. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/drift.py +5 -3
  82. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/factory.py +2 -0
  83. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/__init__.py +1 -0
  84. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/context.py +23 -4
  85. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/drift.py +29 -13
  86. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/errors.py +1 -1
  87. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/mcp/args.py +0 -1
  88. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/mcp/command.py +6 -4
  89. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/mcp/conflicts.py +7 -6
  90. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/mcp/entry.py +1 -1
  91. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/mcp/registry.py +21 -7
  92. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/mcp/warnings.py +0 -2
  93. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/mcp/writer.py +1 -1
  94. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/package_resolution.py +60 -1
  95. apm_cli-0.17.0/src/apm_cli/install/package_selection.py +26 -0
  96. apm_cli-0.17.0/src/apm_cli/install/phases/_skip_logic.py +57 -0
  97. apm_cli-0.17.0/src/apm_cli/install/phases/audit.py +135 -0
  98. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/download.py +17 -0
  99. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/integrate.py +86 -19
  100. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/lockfile.py +23 -1
  101. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/resolve.py +142 -73
  102. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/targets.py +68 -20
  103. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/pipeline.py +133 -46
  104. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/presentation/dry_run.py +1 -1
  105. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/request.py +7 -1
  106. apm_cli-0.17.0/src/apm_cli/install/root_redirect.py +102 -0
  107. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/service.py +2 -0
  108. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/services.py +69 -21
  109. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/sources.py +23 -10
  110. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/template.py +15 -12
  111. apm_cli-0.17.0/src/apm_cli/install/validation.py +785 -0
  112. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/agent_integrator.py +4 -7
  113. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/base_integrator.py +72 -15
  114. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/cleanup.py +0 -1
  115. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/command_integrator.py +1 -1
  116. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/dispatch.py +0 -1
  117. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/hook_integrator.py +80 -6
  118. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/instruction_integrator.py +158 -13
  119. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/mcp_integrator.py +232 -200
  120. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/mcp_integrator_install.py +350 -215
  121. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/prompt_integrator.py +18 -10
  122. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/skill_integrator.py +312 -36
  123. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/skill_transformer.py +0 -1
  124. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/targets.py +34 -6
  125. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/builder.py +3 -7
  126. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/migration.py +0 -1
  127. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/pr_integration.py +0 -1
  128. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/publisher.py +160 -102
  129. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/ref_resolver.py +1 -2
  130. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/registry.py +0 -1
  131. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/semver.py +17 -24
  132. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/shadow_detector.py +0 -1
  133. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/validator.py +0 -1
  134. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/version_pins.py +0 -1
  135. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/yml_editor.py +0 -2
  136. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/yml_schema.py +1 -1
  137. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/models/__init__.py +27 -0
  138. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/models/dependency/mcp.py +1 -1
  139. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/models/dependency/reference.py +5 -2
  140. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/models/dependency/types.py +0 -1
  141. apm_cli-0.17.0/src/apm_cli/models/format_detection.py +408 -0
  142. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/models/plugin.py +1 -1
  143. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/models/results.py +0 -1
  144. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/models/validation.py +47 -67
  145. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/output/formatters.py +0 -5
  146. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/output/models.py +0 -1
  147. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/output/script_formatters.py +0 -1
  148. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/ci_checks.py +14 -1
  149. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/discovery.py +0 -1
  150. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/inheritance.py +73 -2
  151. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/install_preflight.py +0 -3
  152. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/matcher.py +0 -1
  153. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/models.py +0 -1
  154. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/outcome_routing.py +1 -1
  155. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/parser.py +99 -1
  156. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/policy_checks.py +29 -41
  157. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/project_config.py +1 -1
  158. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/schema.py +72 -1
  159. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/primitives/discovery.py +153 -60
  160. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/primitives/models.py +2 -1
  161. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/primitives/parser.py +39 -4
  162. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/registry/client.py +1 -1
  163. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/registry/integration.py +1 -3
  164. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/registry/operations.py +0 -1
  165. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/runtime/base.py +1 -1
  166. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/runtime/codex_runtime.py +1 -3
  167. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/runtime/copilot_runtime.py +1 -2
  168. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/runtime/factory.py +1 -1
  169. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/runtime/llm_runtime.py +1 -3
  170. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/runtime/manager.py +0 -1
  171. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/security/audit_report.py +1 -1
  172. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/security/content_scanner.py +1 -2
  173. apm_cli-0.17.0/src/apm_cli/security/external/__init__.py +27 -0
  174. apm_cli-0.17.0/src/apm_cli/security/external/base.py +76 -0
  175. apm_cli-0.17.0/src/apm_cli/security/external/gate.py +35 -0
  176. apm_cli-0.17.0/src/apm_cli/security/external/generic_sarif.py +85 -0
  177. apm_cli-0.17.0/src/apm_cli/security/external/options.py +179 -0
  178. apm_cli-0.17.0/src/apm_cli/security/external/registry.py +41 -0
  179. apm_cli-0.17.0/src/apm_cli/security/external/runner.py +100 -0
  180. apm_cli-0.17.0/src/apm_cli/security/external/sarif_ingest.py +149 -0
  181. apm_cli-0.17.0/src/apm_cli/security/external/skillspector.py +175 -0
  182. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/security/file_scanner.py +0 -1
  183. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/security/gate.py +1 -1
  184. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/console.py +1 -2
  185. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/content_hash.py +0 -1
  186. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/diagnostics.py +2 -3
  187. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/exclude.py +0 -1
  188. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/file_ops.py +1 -0
  189. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/git_env.py +8 -4
  190. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/helpers.py +0 -2
  191. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/paths.py +23 -0
  192. apm_cli-0.17.0/src/apm_cli/utils/perf_stats.py +179 -0
  193. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/version_checker.py +83 -8
  194. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/yaml_io.py +1 -1
  195. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/workflow/runner.py +0 -2
  196. {apm_cli-0.16.0 → apm_cli-0.17.0/src/apm_cli.egg-info}/PKG-INFO +1 -1
  197. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli.egg-info/SOURCES.txt +23 -0
  198. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_distributed_compilation.py +48 -0
  199. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_lockfile.py +19 -0
  200. apm_cli-0.16.0/src/apm_cli/commands/compile/cli.py +0 -907
  201. apm_cli-0.16.0/src/apm_cli/install/validation.py +0 -701
  202. {apm_cli-0.16.0 → apm_cli-0.17.0}/AUTHORS +0 -0
  203. {apm_cli-0.16.0 → apm_cli-0.17.0}/LICENSE +0 -0
  204. {apm_cli-0.16.0 → apm_cli-0.17.0}/NOTICE +0 -0
  205. {apm_cli-0.16.0 → apm_cli-0.17.0}/README.md +0 -0
  206. {apm_cli-0.16.0 → apm_cli-0.17.0}/setup.cfg +0 -0
  207. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/__init__.py +0 -0
  208. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/__init__.py +0 -0
  209. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/__init__.py +0 -0
  210. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/_mcp_runtime_args.py +0 -0
  211. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/base.py +0 -0
  212. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/claude.py +0 -0
  213. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/codex.py +0 -0
  214. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/cursor.py +0 -0
  215. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/gemini.py +0 -0
  216. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/opencode.py +0 -0
  217. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/client/windsurf.py +0 -0
  218. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
  219. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/package_manager/base.py +0 -0
  220. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
  221. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/bundle/__init__.py +0 -0
  222. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/bundle/local_bundle.py +0 -0
  223. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/cache/__init__.py +0 -0
  224. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/cache/git_cache.py +0 -0
  225. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/cache/http_cache.py +0 -0
  226. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/cache/integrity.py +0 -0
  227. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/cache/locking.py +0 -0
  228. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/cache/paths.py +0 -0
  229. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/cache/url_normalize.py +0 -0
  230. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/__init__.py +0 -0
  231. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/cache.py +0 -0
  232. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/compile/__init__.py +0 -0
  233. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/deps/__init__.py +0 -0
  234. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/deps/why.py +0 -0
  235. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/experimental.py +0 -0
  236. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/check.py +0 -0
  237. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/init.py +0 -0
  238. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/migrate.py +0 -0
  239. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/outdated.py +0 -0
  240. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/plugin/add.py +0 -0
  241. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/plugin/set.py +0 -0
  242. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/publish.py +0 -0
  243. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/marketplace/validate.py +0 -0
  244. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/plugin/__init__.py +0 -0
  245. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/plugin/init.py +0 -0
  246. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/run.py +0 -0
  247. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/runtime.py +0 -0
  248. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/targets.py +0 -0
  249. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/commands/uninstall/__init__.py +0 -0
  250. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/__init__.py +0 -0
  251. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/build_id.py +0 -0
  252. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/constants.py +0 -0
  253. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/compilation/output_writer.py +0 -0
  254. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/__init__.py +0 -0
  255. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/apm_yml.py +0 -0
  256. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/errors.py +0 -0
  257. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/null_logger.py +0 -0
  258. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/core/operations.py +0 -0
  259. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/__init__.py +0 -0
  260. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/_shared.py +0 -0
  261. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/artifactory_orchestrator.py +0 -0
  262. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/bare_cache.py +0 -0
  263. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/clone_engine.py +0 -0
  264. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/git_auth_env.py +0 -0
  265. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/git_reference_resolver.py +0 -0
  266. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/git_semver_resolver.py +0 -0
  267. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/github_downloader_validation.py +0 -0
  268. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/host_backends.py +0 -0
  269. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/installed_package.py +0 -0
  270. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/outdated_row.py +0 -0
  271. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/registry/__init__.py +0 -0
  272. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/registry/auth.py +0 -0
  273. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/registry/client.py +0 -0
  274. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/registry/config_loader.py +0 -0
  275. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/registry/extractor.py +0 -0
  276. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/registry/feature_gate.py +0 -0
  277. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/registry/outdated.py +0 -0
  278. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/registry/resolver.py +0 -0
  279. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/registry/semver.py +0 -0
  280. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/shared_clone_cache.py +0 -0
  281. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/tiered_ref_resolver.py +0 -0
  282. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/deps/why_walker.py +0 -0
  283. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/artifactory_resolver.py +0 -0
  284. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/cache_pin.py +0 -0
  285. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/gitlab_resolver.py +0 -0
  286. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/heals/__init__.py +0 -0
  287. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/heals/base.py +0 -0
  288. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/heals/branch_ref_drift.py +0 -0
  289. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/heals/buggy_lockfile_recovery.py +0 -0
  290. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/helpers/__init__.py +0 -0
  291. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/helpers/security_scan.py +0 -0
  292. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/insecure_policy.py +0 -0
  293. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/local_bundle_handler.py +0 -0
  294. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/mcp/__init__.py +0 -0
  295. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/__init__.py +0 -0
  296. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/_redownload.py +0 -0
  297. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/cleanup.py +0 -0
  298. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/finalize.py +0 -0
  299. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/heal.py +0 -0
  300. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/local_content.py +0 -0
  301. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/policy_gate.py +0 -0
  302. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/policy_target_check.py +0 -0
  303. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/phases/post_deps_local.py +0 -0
  304. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/plan.py +0 -0
  305. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/presentation/__init__.py +0 -0
  306. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/registry_wiring.py +0 -0
  307. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/skill_path_migration.py +0 -0
  308. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/install/summary.py +0 -0
  309. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/__init__.py +0 -0
  310. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/copilot_app_db.py +0 -0
  311. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/copilot_app_project.py +0 -0
  312. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/copilot_app_workflow_integrator.py +0 -0
  313. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/copilot_app_ws.py +0 -0
  314. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/copilot_cowork_paths.py +0 -0
  315. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/coverage.py +0 -0
  316. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/opencode_frontmatter.py +0 -0
  317. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/integration/utils.py +0 -0
  318. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/__init__.py +0 -0
  319. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/_git_utils.py +0 -0
  320. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/_io.py +0 -0
  321. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/_shared.py +0 -0
  322. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/client.py +0 -0
  323. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/diagnostics.py +0 -0
  324. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/drift_check.py +0 -0
  325. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/errors.py +0 -0
  326. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/git_stderr.py +0 -0
  327. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/init_template.py +0 -0
  328. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/models.py +0 -0
  329. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/output_mappers.py +0 -0
  330. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/output_profiles.py +0 -0
  331. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/resolver.py +0 -0
  332. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/tag_pattern.py +0 -0
  333. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/marketplace/version_check.py +0 -0
  334. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/models/apm_package.py +0 -0
  335. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/models/dependency/__init__.py +0 -0
  336. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/output/__init__.py +0 -0
  337. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/__init__.py +0 -0
  338. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/_constraint_pinning.py +0 -0
  339. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/_help_text.py +0 -0
  340. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/policy/_shared.py +0 -0
  341. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/primitives/__init__.py +0 -0
  342. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/registry/__init__.py +0 -0
  343. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/runtime/__init__.py +0 -0
  344. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/runtime/utils.py +0 -0
  345. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/security/__init__.py +0 -0
  346. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/update_policy.py +0 -0
  347. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/__init__.py +0 -0
  348. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/atomic_io.py +0 -0
  349. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/git_sparse.py +0 -0
  350. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/github_host.py +0 -0
  351. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/guards.py +0 -0
  352. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/install_tui.py +0 -0
  353. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/normalization.py +0 -0
  354. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/path_security.py +0 -0
  355. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/patterns.py +0 -0
  356. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/reflink.py +0 -0
  357. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/short_sha.py +0 -0
  358. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/utils/subprocess_env.py +0 -0
  359. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/version.py +0 -0
  360. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/workflow/__init__.py +0 -0
  361. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/workflow/discovery.py +0 -0
  362. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli/workflow/parser.py +0 -0
  363. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli.egg-info/dependency_links.txt +0 -0
  364. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli.egg-info/entry_points.txt +0 -0
  365. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli.egg-info/requires.txt +0 -0
  366. {apm_cli-0.16.0 → apm_cli-0.17.0}/src/apm_cli.egg-info/top_level.txt +0 -0
  367. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_apm_package_models.py +0 -0
  368. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_apm_resolver.py +0 -0
  369. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_codex_docker_args_fix.py +0 -0
  370. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_codex_empty_string_and_defaults.py +0 -0
  371. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_collision_integration.py +0 -0
  372. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_console.py +0 -0
  373. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_empty_string_and_defaults.py +0 -0
  374. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_enhanced_discovery.py +0 -0
  375. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_github_downloader.py +0 -0
  376. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_github_downloader_token_precedence.py +0 -0
  377. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_runnable_prompts.py +0 -0
  378. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_runtime_manager_token_precedence.py +0 -0
  379. {apm_cli-0.16.0 → apm_cli-0.17.0}/tests/test_token_manager.py +0 -0
  380. {apm_cli-0.16.0 → apm_cli-0.17.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.16.0
3
+ Version: 0.17.0
4
4
  Summary: MCP configuration tool
5
5
  Author-email: Daniel Meppiel <user@example.com>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "apm-cli"
7
- version = "0.16.0"
7
+ version = "0.17.0"
8
8
  description = "MCP configuration tool"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -88,21 +88,22 @@ ignore = [
88
88
  "S602", # subprocess-popen-with-shell -- intentional in CLI wrapping git/pip
89
89
  # --- Deferred rules: enable in dedicated future PRs ---
90
90
  "SIM102", # collapsible-if -- 28 violations, auto-fixable style improvement
91
- "RUF003", # ambiguous-unicode-character-comment -- 14 violations, review against ASCII convention
92
- "RUF002", # ambiguous-unicode-character-docstring -- 8 violations, same as above
93
91
  ]
94
92
 
95
93
  [tool.ruff.lint.pylint]
96
94
  # High initial thresholds set just above current codebase maximums.
97
95
  # Prevents new code from exceeding the worst existing violations.
98
96
  # Tighten these over time via dedicated refactoring PRs.
99
- max-statements = 275 # current max: 269 (mcp_integrator.py::install)
100
- max-args = 18 # current max: 16 (commands/install.py)
101
- max-branches = 115 # current max: 108 (mcp_integrator.py::install)
102
- max-returns = 18 # current max: 16 (marketplace/publisher.py)
97
+ # Stage 1 thresholds (PR #1464, issue #1077).
98
+ # Roadmap: Stage 2 targets max-complexity<=20, max-branches<=25 (McCabe standard).
99
+ max-statements = 200 # Stage 1 (was 275)
100
+ max-args = 15 # Stage 1 (was 18)
101
+ max-branches = 60 # Stage 1 (was 115)
102
+ max-returns = 12 # Stage 1 (was 18)
103
103
 
104
104
  [tool.ruff.lint.mccabe]
105
- max-complexity = 100 # current max: 97 (mcp_integrator.py::install)
105
+ # Stage 1 (was 100). Stage 2 target: <=20 (McCabe industry standard).
106
+ max-complexity = 50
106
107
 
107
108
  [tool.ruff.lint.per-file-ignores]
108
109
  # Subprocess calls are intentional in a CLI tool
@@ -120,7 +121,6 @@ max-complexity = 100 # current max: 97 (mcp_integrator.py::install)
120
121
  "src/apm_cli/commands/init.py" = ["F821", "S603", "S607"]
121
122
  "src/apm_cli/install/pipeline.py" = ["F821", "S603", "S607"]
122
123
  "src/apm_cli/integration/skill_integrator.py" = ["F821", "S603", "S607"]
123
-
124
124
  [tool.ruff.format]
125
125
  quote-style = "double"
126
126
  indent-style = "space"
@@ -117,12 +117,12 @@ class CopilotClientAdapter(MCPClientAdapter):
117
117
  """
118
118
  current_config = self.get_current_config()
119
119
 
120
- # Ensure mcpServers section exists
121
- if "mcpServers" not in current_config:
122
- current_config["mcpServers"] = {}
120
+ # Ensure servers section exists and is a dict (guard against malformed config).
121
+ if not isinstance(current_config.get(self.mcp_servers_key), dict):
122
+ current_config[self.mcp_servers_key] = {}
123
123
 
124
124
  # Apply updates
125
- current_config["mcpServers"].update(config_updates)
125
+ current_config[self.mcp_servers_key].update(config_updates)
126
126
 
127
127
  # Write back to file
128
128
  config_path = Path(self.get_config_path())
@@ -259,7 +259,7 @@ class CopilotClientAdapter(MCPClientAdapter):
259
259
  current = self.get_current_config()
260
260
  except Exception:
261
261
  return set(), False
262
- servers = current.get("mcpServers") or {}
262
+ servers = current.get(self.mcp_servers_key) or {}
263
263
  # Match the same key resolution rule used below.
264
264
  if server_name:
265
265
  key = server_name
@@ -0,0 +1,99 @@
1
+ """JetBrains Copilot implementation of the MCP client adapter.
2
+
3
+ GitHub Copilot for JetBrains IDEs stores MCP server configuration under
4
+ a user-scope directory whose location is OS-dependent:
5
+
6
+ Windows : %LOCALAPPDATA%\\github-copilot\\intellij\\mcp.json
7
+ macOS : ~/Library/Application Support/github-copilot/intellij/mcp.json
8
+ Linux : $XDG_DATA_HOME/github-copilot/intellij/mcp.json
9
+ (defaults to ~/.local/share/github-copilot/intellij/mcp.json)
10
+
11
+ The configuration file uses a top-level ``"servers"`` key (unlike most
12
+ other Copilot-family adapters which use ``"mcpServers"``).
13
+
14
+ Ref: https://github.com/orgs/community/discussions/139762
15
+ """
16
+
17
+ import os
18
+ import sys
19
+ from pathlib import Path
20
+
21
+ from ...utils.path_security import PathTraversalError, ensure_path_within
22
+ from .copilot import CopilotClientAdapter
23
+
24
+
25
+ def _intellij_config_dir() -> Path:
26
+ """Return the OS-specific JetBrains Copilot config directory.
27
+
28
+ Does not guarantee the directory exists; callers that need to write
29
+ to it should call ``mkdir(parents=True, exist_ok=True)`` first.
30
+
31
+ Raises
32
+ ------
33
+ PathTraversalError
34
+ If the environment variable the location is derived from
35
+ (``LOCALAPPDATA`` on Windows, ``XDG_DATA_HOME`` on Linux) is unset
36
+ or not absolute. Without this guard an empty ``LOCALAPPDATA``
37
+ would yield ``Path("")`` -- a *relative* path -- causing APM to
38
+ silently read/write ``./github-copilot/intellij/mcp.json`` in the
39
+ current working directory and to falsely auto-detect the runtime.
40
+ """
41
+ if sys.platform == "win32":
42
+ local_app_data = os.environ.get("LOCALAPPDATA", "")
43
+ if not local_app_data or not os.path.isabs(local_app_data):
44
+ raise PathTraversalError(
45
+ "LOCALAPPDATA is unset or not an absolute path; cannot locate the "
46
+ "JetBrains Copilot configuration directory."
47
+ )
48
+ return Path(local_app_data) / "github-copilot" / "intellij"
49
+
50
+ if sys.platform == "darwin":
51
+ return Path.home() / "Library" / "Application Support" / "github-copilot" / "intellij"
52
+
53
+ # Linux: honour $XDG_DATA_HOME, fall back to ~/.local/share
54
+ xdg_data = os.environ.get("XDG_DATA_HOME", "")
55
+ if xdg_data:
56
+ if not os.path.isabs(xdg_data):
57
+ raise PathTraversalError(
58
+ "XDG_DATA_HOME is set to a non-absolute path; cannot locate the "
59
+ "JetBrains Copilot configuration directory."
60
+ )
61
+ return Path(xdg_data) / "github-copilot" / "intellij"
62
+ return Path.home() / ".local" / "share" / "github-copilot" / "intellij"
63
+
64
+
65
+ class IntelliJClientAdapter(CopilotClientAdapter):
66
+ """MCP client adapter for GitHub Copilot inside JetBrains IDEs.
67
+
68
+ JetBrains Copilot stores server definitions in a user-scope JSON file
69
+ with a ``"servers"`` top-level key (not ``"mcpServers"``). This adapter
70
+ inherits all registry-resolution, env-var handling, and config read/write
71
+ from :class:`CopilotClientAdapter` and overrides only the config path and
72
+ ``mcp_servers_key`` so the parent methods operate on the correct key.
73
+ """
74
+
75
+ supports_user_scope: bool = True
76
+ _client_label: str = "JetBrains Copilot"
77
+ target_name: str = "intellij"
78
+ mcp_servers_key: str = "servers"
79
+
80
+ # JetBrains runtime-substitution support has not yet been audited.
81
+ # Pin to install-time resolution for safety; revisit in a follow-up.
82
+ _supports_runtime_env_substitution: bool = False
83
+
84
+ # ------------------------------------------------------------------ #
85
+ # Config path
86
+ # ------------------------------------------------------------------ #
87
+
88
+ def get_config_path(self) -> str:
89
+ """Return the OS-specific path to ``mcp.json`` for JetBrains Copilot.
90
+
91
+ The config directory is derived from an environment variable
92
+ (``LOCALAPPDATA`` / ``XDG_DATA_HOME``). Validate it resolves
93
+ inside the user's home directory before any read/write so a
94
+ tampered or unexpected environment cannot redirect APM's writes
95
+ outside the user-scope tree (supply-chain hardening).
96
+ """
97
+ config_dir = _intellij_config_dir()
98
+ ensure_path_within(config_dir, Path.home())
99
+ return str(config_dir / "mcp.json")
@@ -6,7 +6,6 @@ https://code.visualstudio.com/docs/copilot/chat/mcp-servers
6
6
  """
7
7
 
8
8
  import json
9
- import os # noqa: F401
10
9
  import re
11
10
  from pathlib import Path
12
11
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  import posixpath
4
4
  from datetime import datetime, timezone
5
- from typing import Dict, List, Tuple, Union # noqa: F401, UP035
6
5
 
7
6
  from ..deps.lockfile import LockFile
8
7
  from ..integration.targets import KNOWN_TARGETS
@@ -1,11 +1,9 @@
1
1
  """Bundle packer -- creates self-contained APM bundles from the resolved dependency tree."""
2
2
 
3
- import os # noqa: F401
4
3
  import shutil
5
4
  import tarfile
6
5
  from dataclasses import dataclass, field
7
6
  from pathlib import Path
8
- from typing import Dict, List, Optional, Union # noqa: F401, UP035
9
7
 
10
8
  from ..core.target_detection import detect_target
11
9
  from ..deps.lockfile import LockFile, get_lockfile_path, migrate_lockfile_if_needed
@@ -9,12 +9,10 @@ under ``pack.bundle_files`` (issue #1098).
9
9
 
10
10
  import hashlib
11
11
  import json
12
- import os # noqa: F401
13
12
  import re
14
13
  import shutil
15
14
  import tarfile
16
15
  from pathlib import Path, PurePosixPath
17
- from typing import Dict, List, Optional, Set, Tuple # noqa: F401, UP035
18
16
 
19
17
  import yaml
20
18
 
@@ -25,7 +23,7 @@ from ..deps.lockfile import (
25
23
  migrate_lockfile_if_needed,
26
24
  )
27
25
  from ..models.apm_package import APMPackage, DependencyReference
28
- from ..utils.console import _rich_info, _rich_warning
26
+ from ..utils.console import _rich_warning
29
27
  from ..utils.path_security import PathTraversalError, ensure_path_within, safe_rmtree
30
28
  from .packer import PackResult
31
29
 
@@ -270,17 +268,9 @@ def _collect_hooks_from_root(package_root: Path) -> dict:
270
268
 
271
269
  def _collect_mcp(package_root: Path) -> dict:
272
270
  """Return ``mcpServers`` dict from ``.mcp.json``."""
273
- mcp_file = package_root / ".mcp.json"
274
- if not mcp_file.is_file() or mcp_file.is_symlink():
275
- return {}
276
- try:
277
- data = json.loads(mcp_file.read_text(encoding="utf-8"))
278
- if isinstance(data, dict):
279
- servers = data.get("mcpServers", {})
280
- return dict(servers) if isinstance(servers, dict) else {}
281
- except (json.JSONDecodeError, OSError):
282
- pass
283
- return {}
271
+ from ..core.plugin_manifest import collect_mcp_servers
272
+
273
+ return collect_mcp_servers(package_root)
284
274
 
285
275
 
286
276
  # ---------------------------------------------------------------------------
@@ -339,42 +329,15 @@ def _find_or_synthesize_plugin_json(
339
329
  suppress_missing_warning: bool = False,
340
330
  logger=None,
341
331
  ) -> dict:
342
- """Locate an existing ``plugin.json`` or synthesise one from ``apm.yml``.
343
-
344
- ``suppress_missing_warning`` silences the "no plugin.json on disk"
345
- message when the caller knows synthesis is the expected path -- for
346
- example a marketplace-publishing run that happens to have
347
- ``dependencies:`` for local dev. Genuine parse errors on an existing
348
- file are always surfaced.
349
- """
350
- from ..deps.plugin_parser import synthesize_plugin_json_from_apm_yml
351
- from ..utils.helpers import find_plugin_json
352
-
353
- plugin_json_path = find_plugin_json(project_root)
354
- if plugin_json_path is not None:
355
- try:
356
- return json.loads(plugin_json_path.read_text(encoding="utf-8"))
357
- except (json.JSONDecodeError, OSError) as exc:
358
- _warn_msg = (
359
- f"Found plugin.json at {plugin_json_path} but could not parse it: {exc}. "
360
- "Falling back to synthesis from apm.yml."
361
- )
362
- if logger:
363
- logger.warning(_warn_msg)
364
- else:
365
- _rich_warning(_warn_msg)
332
+ """Locate an existing ``plugin.json`` or synthesise one from ``apm.yml``."""
333
+ from ..core.plugin_manifest import find_or_synthesize_plugin_json
366
334
 
367
- elif not suppress_missing_warning:
368
- # Demoted from warning to info: synthesis from apm.yml is the
369
- # APM-native happy path for plugin authoring, not a defect.
370
- _info_msg = (
371
- "No plugin.json on disk; deriving it from apm.yml (the APM-native source of truth)."
372
- )
373
- if logger:
374
- logger.info(_info_msg)
375
- else:
376
- _rich_info(_info_msg)
377
- return synthesize_plugin_json_from_apm_yml(apm_yml_path)
335
+ return find_or_synthesize_plugin_json(
336
+ project_root,
337
+ apm_yml_path,
338
+ suppress_missing_warning=suppress_missing_warning,
339
+ logger=logger,
340
+ )
378
341
 
379
342
 
380
343
  def _has_marketplace_block(apm_yml_path: Path) -> bool:
@@ -6,7 +6,6 @@ import tarfile
6
6
  import tempfile
7
7
  from dataclasses import dataclass, field
8
8
  from pathlib import Path, PureWindowsPath
9
- from typing import Dict, List # noqa: F401, UP035
10
9
 
11
10
  from ..deps.lockfile import LEGACY_LOCKFILE_NAME, LOCKFILE_NAME, LockFile
12
11
  from ..utils.path_security import PathTraversalError, validate_path_segments
@@ -22,10 +22,13 @@ from apm_cli.commands.cache import cache
22
22
  from apm_cli.commands.compile import compile as compile_cmd
23
23
  from apm_cli.commands.config import config
24
24
  from apm_cli.commands.deps import deps
25
+ from apm_cli.commands.doctor import doctor
25
26
  from apm_cli.commands.experimental import experimental
27
+ from apm_cli.commands.find import find as find_cmd
26
28
  from apm_cli.commands.init import init
27
29
  from apm_cli.commands.install import install
28
30
  from apm_cli.commands.list_cmd import list as list_cmd
31
+ from apm_cli.commands.lock import lock
29
32
  from apm_cli.commands.marketplace import marketplace
30
33
  from apm_cli.commands.marketplace import search as marketplace_search
31
34
  from apm_cli.commands.mcp import mcp
@@ -43,8 +46,25 @@ from apm_cli.commands.uninstall import uninstall
43
46
  from apm_cli.commands.update import update
44
47
  from apm_cli.commands.view import view as view_cmd
45
48
 
49
+ _CLI_EPILOG = (
50
+ "\b\n"
51
+ "Common workflows:\n"
52
+ " apm init Scaffold a new project\n"
53
+ " apm install Install dependencies from apm.yml\n"
54
+ " apm install --frozen Reproduce lockfile exactly (CI-safe)\n"
55
+ " apm lock Resolve deps and write lockfile only\n"
56
+ " apm outdated See what's drifted from upstream\n"
57
+ " apm update Refresh refs and rewrite the lockfile\n"
58
+ " apm audit --ci Validate lockfile integrity for CI gates\n"
59
+ " apm doctor Diagnose environment problems\n"
60
+ " apm run <script> Execute a script from apm.yml"
61
+ )
62
+
46
63
 
47
- @click.group(help="Agent Package Manager (APM): The package manager for AI-Native Development")
64
+ @click.group(
65
+ help="Agent Package Manager (APM): The package manager for AI-Native Development",
66
+ epilog=_CLI_EPILOG,
67
+ )
48
68
  @click.option(
49
69
  "--version",
50
70
  is_flag=True,
@@ -91,6 +111,7 @@ cli.add_command(unpack_cmd, name="unpack")
91
111
  cli.add_command(publish_cmd, name="publish")
92
112
  cli.add_command(init)
93
113
  cli.add_command(install)
114
+ cli.add_command(lock)
94
115
  cli.add_command(uninstall)
95
116
  cli.add_command(prune)
96
117
  cli.add_command(update)
@@ -107,7 +128,9 @@ cli.add_command(targets)
107
128
  cli.add_command(mcp)
108
129
  cli.add_command(policy)
109
130
  cli.add_command(outdated_cmd, name="outdated")
131
+ cli.add_command(doctor)
110
132
  cli.add_command(marketplace)
133
+ cli.add_command(find_cmd)
111
134
  cli.add_command(marketplace_search, name="search")
112
135
 
113
136
 
@@ -6,7 +6,6 @@ field. Keeps write-back logic isolated and unit-testable.
6
6
  """
7
7
 
8
8
  from pathlib import Path
9
- from typing import List, Optional # noqa: F401, UP035
10
9
 
11
10
  from ..models.dependency.reference import DependencyReference
12
11
  from ..utils.yaml_io import dump_yaml, load_yaml
@@ -14,14 +14,15 @@ from colorama import Fore, Style
14
14
  from colorama import init as colorama_init
15
15
 
16
16
  from ..constants import (
17
- APM_LOCK_FILENAME, # noqa: F401
18
17
  APM_MODULES_DIR,
19
18
  APM_MODULES_GITIGNORE_PATTERN,
20
19
  APM_YML_FILENAME,
21
20
  GITIGNORE_FILENAME,
22
21
  )
23
22
  from ..update_policy import get_update_hint_message, is_self_update_enabled
24
- from ..utils.atomic_io import atomic_write_text as _atomic_write # noqa: F401
23
+ from ..utils.atomic_io import (
24
+ atomic_write_text as _atomic_write, # noqa: F401 -- re-exported; tests import from apm_cli.commands._helpers
25
+ )
25
26
  from ..utils.console import _rich_echo, _rich_info, _rich_warning
26
27
  from ..utils.path_security import PathTraversalError, validate_path_segments
27
28
  from ..utils.version_checker import check_for_updates
@@ -331,6 +332,74 @@ def _check_orphaned_packages():
331
332
  return []
332
333
 
333
334
 
335
+ # ------------------------------------------------------------------
336
+ # Dependency-update helpers (shared by `apm update` and `apm deps update`)
337
+ # ------------------------------------------------------------------
338
+
339
+
340
+ class UnknownPackageError(Exception):
341
+ """A requested package token matched no declared dependency.
342
+
343
+ Carries the offending *token* and the list of *available* display
344
+ names so the CLI caller can render a consistent error message.
345
+ """
346
+
347
+ def __init__(self, token: str, available: list[str]):
348
+ self.token = token
349
+ self.available = available
350
+ super().__init__(f"Package '{token}' not found")
351
+
352
+
353
+ def resolve_requested_packages(
354
+ packages: tuple[str, ...] | list[str],
355
+ all_deps: list,
356
+ ) -> list[str] | None:
357
+ """Map requested package tokens to canonical dependency keys.
358
+
359
+ The install engine matches ``only_packages`` by ``DependencyReference``
360
+ identity (e.g. ``owner/repo``), so short names like ``compliance-rules``
361
+ must be normalised to their canonical key before the engine is called.
362
+
363
+ Args:
364
+ packages: Raw tokens from the CLI ``[PACKAGES]...`` argument.
365
+ all_deps: Declared dependencies (direct + dev) to match against.
366
+
367
+ Returns:
368
+ An order-preserving, de-duplicated list of canonical keys, or
369
+ ``None`` when *packages* is empty (meaning "refresh everything").
370
+
371
+ Raises:
372
+ UnknownPackageError: when a token matches no declared dependency.
373
+ """
374
+ if not packages:
375
+ return None
376
+
377
+ token_to_canonical: dict[str, str] = {}
378
+ for dep in all_deps:
379
+ canonical_key = dep.get_unique_key() or dep.repo_url or dep.get_display_name()
380
+ tokens = {canonical_key, dep.get_display_name(), dep.repo_url}
381
+ if getattr(dep, "alias", None):
382
+ tokens.add(dep.alias)
383
+ parts = dep.repo_url.split("/")
384
+ if len(parts) >= 2:
385
+ tokens.add(parts[-1])
386
+ for token in tokens:
387
+ if token and token not in token_to_canonical:
388
+ token_to_canonical[token] = canonical_key
389
+
390
+ resolved: list[str] = []
391
+ seen: set[str] = set()
392
+ for pkg in packages:
393
+ canonical = token_to_canonical.get(pkg)
394
+ if not canonical:
395
+ available = [dep.get_display_name() for dep in all_deps]
396
+ raise UnknownPackageError(pkg, available)
397
+ if canonical not in seen:
398
+ seen.add(canonical)
399
+ resolved.append(canonical)
400
+ return resolved
401
+
402
+
334
403
  def print_version(ctx, param, value):
335
404
  """Print version and exit."""
336
405
  if not value or ctx.resilient_parsing:
@@ -656,3 +725,23 @@ def _create_minimal_apm_yml(config, plugin=False, target_path=None):
656
725
  content = content.replace("dependencies:", skeleton + "\ndependencies:", 1)
657
726
 
658
727
  out_file.write_text(content, encoding="utf-8")
728
+
729
+
730
+ def _find_apm_yml(start: Path | None = None) -> Path | None:
731
+ """Walk parent directories from ``start`` (or cwd) to find ``apm.yml``.
732
+
733
+ Matches the npm / cargo / poetry ergonomic: a developer running
734
+ an ``apm`` command from a subdirectory of their project (``src/``,
735
+ ``docs/``, ``scripts/``) finds the manifest and operates on it.
736
+
737
+ The walk stops at the filesystem root or when an ``apm.yml`` is
738
+ found, whichever comes first. Returns the absolute path to the
739
+ ``apm.yml`` file when found; ``None`` when no project root is
740
+ discoverable from ``start`` upward.
741
+ """
742
+ cwd = (start or Path.cwd()).resolve()
743
+ for candidate in (cwd, *cwd.parents):
744
+ manifest = candidate / "apm.yml"
745
+ if manifest.is_file():
746
+ return manifest
747
+ return None