Problem
Marketplace indexes (marketplace.json) are currently fetched exclusively via GitHub API (MarketplaceSource.host is hardcoded to "github.com"). In air-gapped or Artifactory-proxied environments, apm marketplace browse/search commands fail because they cannot reach GitHub directly.
What works today: Plugins resolved from marketplaces flow through the standard download pipeline, so PROXY_REGISTRY_URL and PROXY_REGISTRY_ONLY are respected for the actual package download. The gap is only in fetching the marketplace index itself.
Proposed Solution
Allow MarketplaceSource to use the configured registry proxy when fetching marketplace.json:
-
Proxy-aware fetch -- When PROXY_REGISTRY_URL is set, fetch_marketplace() in client.py should construct the raw file URL through the proxy (e.g., {PROXY_REGISTRY_URL}/{owner}/{repo}/raw/{path}) instead of hitting raw.githubusercontent.com directly.
-
Explicit Artifactory marketplace registration -- Allow apm marketplace add to accept an FQDN-prefixed repo:
apm marketplace add skills art.example.com/artifactory/github/anthropics/skills
-
Air-gapped enforcement -- When PROXY_REGISTRY_ONLY=1, reject marketplace fetches that would bypass the proxy.
Architecture Notes
MarketplaceSource in models.py needs optional host and registry_prefix fields (same pattern as DependencyReference)
_fetch_file() in client.py needs a proxy-aware code path using RegistryConfig.get_headers() for auth
- Cache key should include the host to avoid collisions between GitHub and proxied versions
- Lockfile provenance fields (
discovered_via, marketplace_plugin_name) are orthogonal and need no changes
Current Behavior
| Operation |
Direct GitHub |
Via Proxy |
Air-Gapped |
marketplace browse/search |
Works |
Fails |
Fails |
install NAME@MARKETPLACE (after resolution) |
Works |
Works |
Works |
install from lockfile |
Works |
Works |
Works |
Desired Behavior
| Operation |
Direct GitHub |
Via Proxy |
Air-Gapped |
marketplace browse/search |
Works |
Works |
Works |
install NAME@MARKETPLACE |
Works |
Works |
Works |
install from lockfile |
Works |
Works |
Works |
References
- Registry proxy implementation:
src/apm_cli/deps/registry_proxy.py
- Marketplace client:
src/apm_cli/marketplace/client.py
- Marketplace models:
src/apm_cli/marketplace/models.py
- Artifactory docs:
docs/src/content/docs/guides/artifactory.md
Problem
Marketplace indexes (
marketplace.json) are currently fetched exclusively via GitHub API (MarketplaceSource.hostis hardcoded to"github.com"). In air-gapped or Artifactory-proxied environments,apm marketplace browse/searchcommands fail because they cannot reach GitHub directly.What works today: Plugins resolved from marketplaces flow through the standard download pipeline, so
PROXY_REGISTRY_URLandPROXY_REGISTRY_ONLYare respected for the actual package download. The gap is only in fetching the marketplace index itself.Proposed Solution
Allow
MarketplaceSourceto use the configured registry proxy when fetchingmarketplace.json:Proxy-aware fetch -- When
PROXY_REGISTRY_URLis set,fetch_marketplace()inclient.pyshould construct the raw file URL through the proxy (e.g.,{PROXY_REGISTRY_URL}/{owner}/{repo}/raw/{path}) instead of hittingraw.githubusercontent.comdirectly.Explicit Artifactory marketplace registration -- Allow
apm marketplace addto accept an FQDN-prefixed repo:Air-gapped enforcement -- When
PROXY_REGISTRY_ONLY=1, reject marketplace fetches that would bypass the proxy.Architecture Notes
MarketplaceSourceinmodels.pyneeds optionalhostandregistry_prefixfields (same pattern asDependencyReference)_fetch_file()inclient.pyneeds a proxy-aware code path usingRegistryConfig.get_headers()for authdiscovered_via,marketplace_plugin_name) are orthogonal and need no changesCurrent Behavior
marketplace browse/searchinstall NAME@MARKETPLACE(after resolution)installfrom lockfileDesired Behavior
marketplace browse/searchinstall NAME@MARKETPLACEinstallfrom lockfileReferences
src/apm_cli/deps/registry_proxy.pysrc/apm_cli/marketplace/client.pysrc/apm_cli/marketplace/models.pydocs/src/content/docs/guides/artifactory.md