Lines 1-37javascript
2 * Async update notifier (the Vercel/update-notifier pattern, zero-dep).
4 * The CLI never blocks on the network: each run reads a tiny local state file
5 * and prints a one-line stderr nag if a newer version was seen on a PREVIOUS
6 * run; when the state is older than 24h it spawns a detached, unref'd child
7 * (this module with --refresh) that fetches the registry and rewrites the
10 * Suppressed when: AGENT_RELAY_NO_UPDATE_CHECK / NO_UPDATE_NOTIFIER / CI env
11 * vars are set, stderr isn't a TTY (don't pollute piped/scripted runs), or the
12 * CLI is running out of an ephemeral npx cache (npx users get @latest anyway).
15import { readFileSync, writeFileSync, mkdirSync, realpathSync } from "fs";
16import { homedir } from "os";
17import { join, dirname, sep } from "path";
18import { spawn } from "child_process";
19import { fileURLToPath } from "url";
HighChild Process
Package source references child process execution.
bin/lib/update-check.mjsView on unpkg · L17 HighRuntime Package Install
Package source invokes a package manager install command at runtime.
bin/lib/update-check.mjsView on unpkg · L11 21export const STATE_PATH = join(homedir(), ".config", "agent-relay", "update-check.json");
22const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
23const SELF_PATH = fileURLToPath(import.meta.url);
25/** Numeric-dotted semver compare: 1 if a > b, -1 if a < b, 0 if equal. */
26export function compareSemver(a, b) {
27 const pa = String(a).split(".").map((n) => parseInt(n, 10) || 0);
28 const pb = String(b).split(".").map((n) => parseInt(n, 10) || 0);
29 for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
30 const da = pa[i] || 0;
31 const db = pb[i] || 0;
32 if (da !== db) return da > db ? 1 : -1;