-
-
Notifications
You must be signed in to change notification settings - Fork 1
CLI wrapper mode: proxy <pkg-manager> <args> #52
Description
The proxy binary could double as a transparent wrapper around package manager commands. Instead of starting the proxy server separately and configuring each package manager's registry URL, you'd run:
proxy npm install express
proxy pip install requests
proxy go get github.com/foo/bar
The proxy would handle registry injection automatically, so the package manager fetches through the caching proxy without any manual config.
How it would work
- Detect the ecosystem from the command name (npm, pip, cargo, gem, go, composer, etc.)
- Find or start a proxy server (see discovery below)
- Inject the appropriate registry override for that ecosystem
- Exec the package manager command
- If an ephemeral server was started, shut it down when the command exits
Proxy discovery order
Before spinning up a new server, check for an existing one:
- Config file - walk up the directory tree looking for
.proxyrc, then fall back to~/.proxyrc. Could be as simple asurl=https://proxy.internal.company.com. This covers corporate setups where a shared proxy already exists. - Default port - probe localhost on the default port and confirm it's a git-pkgs proxy (hit the health/API endpoint, not just check if the port is open).
- Ephemeral server - bind to
:0, let the OS pick a port, start the server, run the command, tear down after.
Background daemon mode
Rather than starting and stopping the server on every command, the first invocation could start a background daemon that stays running with an idle timeout. Write the port to a pidfile, and subsequent invocations find it and connect immediately. Similar to how gpg-agent and ssh-agent work. This makes startup cost zero for the common case.
Registry override mechanisms
Each supported ecosystem already has documented configuration for pointing at the proxy. The wrapper would inject these automatically via env vars or flags, for example NPM_CONFIG_REGISTRY for npm, GOPROXY for Go, PIP_INDEX_URL for pip, etc.
Env vars are generally cleaner than injecting flags since they don't interfere with the user's arguments.
Shell aliases
Power users could alias the wrapper to replace their package manager entirely:
alias npm="proxy npm"
alias pip="proxy pip"
alias cargo="proxy cargo"At that point every install goes through the proxy with zero friction.
Startup performance
Benchmarked on Apple Silicon (arm64). The proxy starts and accepts connections in ~48ms, which is negligible compared to any package install operation.
| Metric | Time |
|---|---|
| Server startup (avg of 10 runs) | ~48ms |
| Cold npm metadata (express) | 112ms (vs 133ms direct) |
| Second npm metadata request | 61ms |
| Cold tarball fetch (is-odd) | 66ms (vs 74ms direct) |
| Cached tarball fetch | <1ms |
| Cold PyPI metadata (requests) | 90ms (vs 124ms direct) |
Even on cold requests the proxy adds no measurable overhead since it streams from upstream. Cached artifacts are served in under 1ms. The ephemeral startup mode would add ~48ms total to the install command, which is well within noise for any real package install.
Prior art
- Socket Firewall (sfw-free) / sfw-installer -
sfw npm install- spins up an ephemeral HTTP proxy that intercepts and scans packages. Security-focused, not caching. - Aikido Safe Chain - sets up shell aliases so package manager commands transparently route through a local scanning proxy. Security-focused.
- Phylum CLI -
phylum npm install- wraps package managers with policy enforcement. Security-focused. - JFrog CLI -
jf npm install,jf pip install,jf go build- injects Artifactory registry URLs for caching. Requires a commercial Artifactory backend.