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