fix: respect user's npm registry configuration in update check (#2038)

## Problem

The startup update check in `src/bin/check-latest-version.ts` hardcodes
`https://registry.npmjs.org/chrome-devtools-mcp/latest`. Users behind
corporate proxies or on a private registry (e.g. JFrog Artifactory)
cannot reach that URL — the request silently fails on every startup, and
they lose update notifications unless they set
`CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS=1`.

Fixes #1943.

The earlier discussion on that issue surfaced two competing approaches:

- Reading only `npm_config_registry`. The maintainer pointed out this
only covers `npx` / `npm run` invocations, not direct CLI use.
- Pulling in `@npmcli/config`. Solves all cases but adds a runtime
dependency.

This PR uses a third approach suggested in the issue: shell out to `npm
config get registry`. That command:

- Honors `.npmrc` files at every scope (global, user, project) and
respects `npm_config_registry`.
- Works the same regardless of how the CLI is invoked (direct, `npx`,
`npm run`).
- Adds no new dependency.
- Runs at most once per 24 hours from a detached process, so the
shell-out cost is negligible.

## Solution

Add a small `getRegistry()` helper that runs `npm config get registry`
with a 5 s timeout and validates the result before using it. Fall back
to the hardcoded public registry when:

- `npm` is not on `PATH`,
- the command times out or errors,
- the value is empty, `"undefined"`, or not an http(s) URL.

The fetch URL is then composed from that resolved registry.

## Testing

- `npm run typecheck` — passes
- `npm run check-format` — passes
- `npm run build` — passes
- `node --test build/tests/check-for-updates.test.js` — 6/6 pass (no
regressions in the existing test suite for this area)
- Manual: ran `node build/src/bin/check-latest-version.js /tmp/out.json`
against the public registry → wrote `{"version":"0.25.0"}`. Re-ran with
`npm_config_registry=https://example.com` → fetch fails silently as
expected, no cache written.

(Unrelated E2E browser tests in
`tests/e2e/chrome-devtools-commands.test.js` fail in my local
environment; they appear environment-dependent and are not touched by
this change.)
This commit is contained in:
Serhii Zghama
2026-05-12 22:15:02 +07:00
committed by GitHub
parent b5948582a0
commit 83a299fc95
+26 -3
View File
@@ -4,17 +4,40 @@
* SPDX-License-Identifier: Apache-2.0
*/
import {execSync} from 'node:child_process';
import fs from 'node:fs/promises';
import path from 'node:path';
import process from 'node:process';
const DEFAULT_REGISTRY = 'https://registry.npmjs.org';
function getRegistry(): string {
// Use the user's configured npm registry so update checks work behind
// corporate proxies and private registries. `npm config get registry`
// honors .npmrc files at every scope and respects npm_config_registry,
// so it covers direct CLI invocations as well as `npx` / `npm run`.
try {
const registry = execSync('npm config get registry', {
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'ignore'],
timeout: 5000,
})
.trim()
.replace(/\/$/, '');
if (registry && registry !== 'undefined' && /^https?:\/\//.test(registry)) {
return registry;
}
} catch {
// npm not on PATH or other errors, fall back to default.
}
return DEFAULT_REGISTRY;
}
const cachePath = process.argv[2];
if (cachePath) {
try {
const response = await fetch(
'https://registry.npmjs.org/chrome-devtools-mcp/latest',
);
const response = await fetch(`${getRegistry()}/chrome-devtools-mcp/latest`);
const data = response.ok ? await response.json() : null;
if (