HEX
Server: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/8.4.25
System: Windows NT DESKTOP-4TAV2RJ 10.0 build 19045 (Windows 10) AMD64
User: fred (0)
PHP: 8.4.25
Disabled: NONE
Upload Files
File: C:/Users/fred/.codex/plugins/cache/openai-bundled/chrome/latest/scripts/chrome-is-running.js
#!/usr/bin/env node
/* global console */
/* Detect whether Google Chrome is currently running. */

let path;
let process;
let execFileSync;
let readlinkSync;

const CHROME_PROCESS_NAMES_BY_PLATFORM = {
  darwin: new Set(["Google Chrome", "Google Chrome Helper"]),
  win32: new Set(["chrome.exe"]),
};

const MACOS_CHROME_APP_PATH_FRAGMENT = "/Google Chrome.app/Contents/";
const MACOS_CHROME_SINGLETON_LOCK_PATH = [
  "Library",
  "Application Support",
  "Google",
  "Chrome",
  "SingletonLock",
];

async function loadNodeModules() {
  path = await import("node:path");
  process = (await import("node:process")).default;
  ({ execFileSync } = await import("node:child_process"));
  ({ readlinkSync } = await import("node:fs"));
}

function usage() {
  console.error("Usage: scripts/chrome-is-running.js [--check] [--json]");
}

function formatCommandError(command, args, error) {
  const commandDisplay = [command, ...args].join(" ");
  const details = [
    error?.code,
    typeof error?.status === "number" ? `exit ${error.status}` : null,
    error?.stderr?.toString().trim(),
    error?.message,
  ].filter(Boolean);
  return `Failed to run ${commandDisplay}: ${details.join("; ")}`;
}

function runCommand(command, args) {
  try {
    return execFileSync(command, args, {
      encoding: "utf8",
      stdio: ["ignore", "pipe", "pipe"],
    }).trim();
  } catch (error) {
    throw new Error(formatCommandError(command, args, error), { cause: error });
  }
}

function stripCommandArguments(command) {
  return command.trim().replace(/\s--.*$/, "");
}

function chromeProcessNameForCommand(command) {
  const executable = stripCommandArguments(command);
  const processName = path.basename(executable);

  if (process.platform === "darwin") {
    if (!executable.includes(MACOS_CHROME_APP_PATH_FRAGMENT))
      return processName;

    if (
      processName === "Google Chrome" ||
      processName.startsWith("Google Chrome Helper")
    )
      return processName;
  }

  return processName;
}

function parseProcessList(output, processNames) {
  if (!output) return [];

  const processes = [];
  for (const line of output.split(/\r?\n/)) {
    const match = line.match(/^\s*(\d+)\s+(.+?)\s*$/);
    if (!match) continue;

    const [, pid, command] = match;
    const processName = chromeProcessNameForCommand(command);
    if (!processNames.has(processName)) continue;

    processes.push({
      pid: Number(pid),
      process_name: processName,
      command: stripCommandArguments(command),
    });
  }

  return processes;
}

function parseMacosApplicationProcessList(output) {
  const processes = parseProcessList(
    output,
    CHROME_PROCESS_NAMES_BY_PLATFORM.darwin,
  );

  return processes.filter((chromeProcess) => {
    return chromeProcess.command.includes(MACOS_CHROME_APP_PATH_FRAGMENT);
  });
}

function parseWindowsTaskList(output) {
  if (!output) return [];

  const processes = [];
  for (const line of output.split(/\r?\n/)) {
    const match = line.match(/^"([^"]+)","(\d+)",/);
    if (!match || match[1].toLowerCase() !== "chrome.exe") continue;

    processes.push({
      pid: Number(match[2]),
      process_name: match[1],
      command: match[1],
    });
  }

  return processes;
}

function getMacosChromeSingletonProcess() {
  if (!process.env.HOME) return null;

  let singletonLockTarget;
  try {
    singletonLockTarget = readlinkSync(
      path.join(process.env.HOME, ...MACOS_CHROME_SINGLETON_LOCK_PATH),
      "utf8",
    );
  } catch {
    return null;
  }

  const pidMatch = singletonLockTarget.match(/-(\d+)$/);
  if (!pidMatch) return null;

  const pid = Number(pidMatch[1]);
  if (!Number.isInteger(pid) || pid <= 0) return null;

  try {
    process.kill(pid, 0);
  } catch (error) {
    if (error?.code !== "EPERM") return null;
  }

  return {
    pid,
    process_name: "Google Chrome",
    command: "Google Chrome",
  };
}

function findRunningChromeProcesses() {
  const processNames =
    CHROME_PROCESS_NAMES_BY_PLATFORM[process.platform] || new Set(["chrome"]);

  if (process.platform === "win32") {
    return parseWindowsTaskList(
      runCommand("tasklist", [
        "/fo",
        "csv",
        "/nh",
        "/fi",
        "imagename eq chrome.exe",
      ]),
    );
  }

  const singletonProcess =
    process.platform === "darwin" ? getMacosChromeSingletonProcess() : null;

  let processList;
  try {
    processList = runCommand("ps", ["-A", "-o", "pid=", "-o", "comm="]);
  } catch (error) {
    if (singletonProcess != null) return [singletonProcess];

    throw error;
  }

  const processes = parseProcessList(processList, processNames);
  if (processes.length > 0 || process.platform !== "darwin") return processes;

  try {
    return parseMacosApplicationProcessList(
      runCommand("ps", ["-A", "-ww", "-o", "pid=", "-o", "command="]),
    );
  } catch (error) {
    if (singletonProcess != null) return [singletonProcess];

    throw error;
  }
}

function parseArgs(argv) {
  const flags = new Set(argv);
  if (flags.has("-h") || flags.has("--help")) {
    usage();
    process.exit(0);
  }

  const supportedFlags = new Set(["--check", "--json"]);
  const unsupportedFlags = argv.filter((arg) => !supportedFlags.has(arg));
  if (unsupportedFlags.length > 0) {
    usage();
    process.exit(2);
  }

  return {
    check: flags.has("--check"),
    json: flags.has("--json"),
  };
}

function printTextReport(result, check) {
  if (check) {
    console.log("Google Chrome running check");
    console.log(`status: ${result.running ? "ok" : "not running"}`);
    console.log("");
  }

  console.log(`Google Chrome running: ${result.running ? "yes" : "no"}`);
  if (result.processes.length === 0) return;

  console.log("Processes:");
  for (const chromeProcess of result.processes) {
    console.log(`  - pid: ${chromeProcess.pid}`);
    console.log(`    process: ${chromeProcess.process_name}`);
  }
}

function main() {
  const args = parseArgs(process.argv.slice(2));
  const processes = findRunningChromeProcesses();
  const result = {
    platform: process.platform,
    running: processes.length > 0,
    processes,
  };

  if (args.json) console.log(JSON.stringify(result, null, 2));
  else printTextReport(result, args.check);

  if (args.check && !result.running) process.exitCode = 1;
}

void loadNodeModules()
  .then(() => {
    main();
  })
  .catch((error) => {
    console.error(error instanceof Error ? error.message : String(error));
    (process || globalThis.process)?.exit(2);
  });