export async function checkForUpdates()

in codex-cli/src/utils/check-updates.ts [74:146]


export async function checkForUpdates(): Promise<void> {
  const { CONFIG_DIR } = await import("./config");
  const stateFile = join(CONFIG_DIR, "update-check.json");

  // Load previous check timestamp
  let state: UpdateCheckState | undefined;
  try {
    state = JSON.parse(await readFile(stateFile, "utf8"));
  } catch {
    // ignore
  }

  // Bail out if we checked less than the configured frequency ago
  if (
    state?.lastUpdateCheck &&
    Date.now() - new Date(state.lastUpdateCheck).valueOf() <
      UPDATE_CHECK_FREQUENCY
  ) {
    return;
  }

  // Fetch current vs latest from the registry
  const { name: packageName } = await import("../../package.json");
  const packageInfo = await getUpdateCheckInfo(packageName);

  await writeState(stateFile, {
    ...state,
    lastUpdateCheck: new Date().toUTCString(),
  });

  if (
    !packageInfo ||
    !semver.gt(packageInfo.latestVersion, packageInfo.currentVersion)
  ) {
    return;
  }

  // Detect global installer
  let managerName = await detectInstallerByPath();

  // Fallback to the local package manager
  if (!managerName) {
    const local = getUserAgent();
    if (!local) {
      // No package managers found, skip it.
      return;
    }
    managerName = local;
  }

  const updateMessage = renderUpdateMessage({
    manager: managerName,
    packageName,
  });

  const box = boxen(
    `\
Update available! ${chalk.red(packageInfo.currentVersion)} → ${chalk.green(
      packageInfo.latestVersion,
    )}.
${updateMessage}`,
    {
      padding: 1,
      margin: 1,
      align: "center",
      borderColor: "yellow",
      borderStyle: "round",
    },
  );

  // eslint-disable-next-line no-console
  console.log(box);
}