File: C:/Users/fred/.codex/plugins/cache/openai-bundled/chrome/latest/scripts/installed-browsers.js
#!/usr/bin/env node
/* global console */
/* Report the default browser and known installed internet browsers. */
let fs;
let os;
let path;
let process;
let execFileSync;
const KNOWN_BROWSERS = [
{
name: "Google Chrome",
bundleIds: ["com.google.Chrome"],
appNames: ["Google Chrome.app"],
commands: ["google-chrome", "chrome"],
windowsExecutable: "chrome.exe",
},
];
const DEFAULT_BROWSER_SCHEMES = ["http", "https"];
async function loadNodeModules() {
fs = await import("node:fs");
os = await import("node:os");
path = await import("node:path");
process = (await import("node:process")).default;
({ execFileSync } = await import("node:child_process"));
}
function macosAppSearchDirs() {
return [
"/Applications",
"/System/Applications",
path.join(os.homedir(), "Applications"),
];
}
function runCommand(args) {
try {
return execFileSync(args[0], args.slice(1), {
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
}).trim();
} catch {
return null;
}
}
function readWindowsRegistryValue(keyPath, valueName) {
const args = ["reg", "query", keyPath, valueName == null ? "/ve" : "/v"];
if (valueName != null) args.push(valueName);
const output = runCommand(args);
if (!output) return null;
const label = valueName == null ? "(Default)" : valueName;
for (const line of output.split(/\r?\n/)) {
const match = line.match(/^\s*(.*?)\s+REG_\w+\s+(.+?)\s*$/);
if (match && match[1] === label) return stripRegistryString(match[2]);
}
return null;
}
function stripRegistryString(value) {
return value.replace(/^"(.*)"$/, "$1");
}
function windowsChromeInstallPaths() {
const appPathKeys = [
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe",
"HKLM\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe",
];
const candidates = appPathKeys
.map((keyPath) => readWindowsRegistryValue(keyPath, null))
.filter(Boolean);
const localAppData =
process.env.LOCALAPPDATA || path.join(os.homedir(), "AppData", "Local");
const standardRoots = [
localAppData,
process.env.PROGRAMFILES,
process.env["PROGRAMFILES(X86)"],
].filter(Boolean);
for (const root of standardRoots) {
candidates.push(
path.join(root, "Google", "Chrome", "Application", "chrome.exe"),
);
}
const pathChrome = commandPath("chrome");
if (pathChrome) candidates.push(pathChrome);
const found = new Map();
for (const candidate of candidates) {
const executablePath = path.resolve(candidate);
if (!fs.existsSync(executablePath)) continue;
found.set(executablePath.toLowerCase(), executablePath);
}
return [...found.values()];
}
function windowsChromeVersion() {
const uninstallKeys = [
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Google Chrome",
"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Google Chrome",
"HKLM\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Google Chrome",
];
for (const keyPath of uninstallKeys) {
const version = readWindowsRegistryValue(keyPath, "DisplayVersion");
if (version) return version;
}
return null;
}
function readPlistKey(plistPath, key) {
return runCommand(["plutil", "-extract", key, "raw", "-o", "-", plistPath]);
}
function readPlistJson(plistPath) {
const output = runCommand([
"plutil",
"-convert",
"json",
"-o",
"-",
plistPath,
]);
if (!output) return {};
try {
return JSON.parse(output);
} catch {
return {};
}
}
function readBundleInfo(appPath) {
const infoPath = path.join(appPath, "Contents", "Info.plist");
if (!fs.existsSync(infoPath)) return {};
const info = readPlistJson(infoPath);
if (Object.keys(info).length > 0) return info;
return {
CFBundleIdentifier: readPlistKey(infoPath, "CFBundleIdentifier"),
CFBundleShortVersionString: readPlistKey(
infoPath,
"CFBundleShortVersionString",
),
};
}
function knownBrowserByBundleId() {
const byBundleId = new Map();
for (const browser of KNOWN_BROWSERS)
for (const bundleId of browser.bundleIds) byBundleId.set(bundleId, browser);
return byBundleId;
}
function macosAppCandidates(browser) {
const candidates = [];
for (const baseDir of macosAppSearchDirs()) {
for (const appName of browser.appNames)
candidates.push(path.join(baseDir, appName));
}
return candidates;
}
function mdfindAppsForBundleId(bundleId) {
const output = runCommand([
"mdfind",
`kMDItemCFBundleIdentifier == '${bundleId}'`,
]);
if (!output) return [];
return output.split(/\r?\n/).filter((line) => line.endsWith(".app"));
}
function addMacosApp(
installedByBundleId,
browser,
appPath,
fallbackBundleId = null,
) {
if (!fs.existsSync(appPath)) return;
const info = readBundleInfo(appPath);
const bundleId =
info.CFBundleIdentifier || fallbackBundleId || browser.bundleIds[0];
if (!bundleId) return;
installedByBundleId.set(bundleId, {
name: browser.name,
bundle_id: bundleId,
path: appPath,
version: info.CFBundleShortVersionString || info.CFBundleVersion || null,
});
}
function findMacosApps() {
const installedByBundleId = new Map();
for (const browser of KNOWN_BROWSERS) {
for (const appPath of macosAppCandidates(browser))
addMacosApp(installedByBundleId, browser, appPath);
for (const bundleId of browser.bundleIds) {
for (const appPath of mdfindAppsForBundleId(bundleId))
addMacosApp(installedByBundleId, browser, appPath, bundleId);
}
}
const knownByBundleId = knownBrowserByBundleId();
for (const baseDir of macosAppSearchDirs()) {
if (!fs.existsSync(baseDir)) continue;
for (const entry of fs.readdirSync(baseDir, { withFileTypes: true })) {
if (!entry.isDirectory() || !entry.name.endsWith(".app")) continue;
const appPath = path.join(baseDir, entry.name);
const info = readBundleInfo(appPath);
const browser = knownByBundleId.get(info.CFBundleIdentifier);
if (!browser) continue;
addMacosApp(
installedByBundleId,
browser,
appPath,
info.CFBundleIdentifier,
);
}
}
return [...installedByBundleId.values()].sort((a, b) =>
a.name.localeCompare(b.name),
);
}
function resolveMacosAppByBundleId(bundleId) {
for (const appPath of mdfindAppsForBundleId(bundleId)) {
if (!fs.existsSync(appPath)) continue;
const info = readBundleInfo(appPath);
if (info.CFBundleIdentifier && info.CFBundleIdentifier !== bundleId)
continue;
return {
name:
info.CFBundleName ||
info.CFBundleDisplayName ||
path.basename(appPath, ".app"),
bundle_id: bundleId,
path: appPath,
version: info.CFBundleShortVersionString || info.CFBundleVersion || null,
};
}
return null;
}
function commandPath(command) {
if (process.platform === "win32")
return runCommand(["where", command])?.split(/\r?\n/)[0] || null;
return runCommand(["which", command]);
}
function findCommandBrowsers() {
const found = new Map();
for (const browser of KNOWN_BROWSERS) {
for (const command of browser.commands) {
const executable = commandPath(command);
if (!executable) continue;
found.set(browser.name, {
name: browser.name,
command,
path: executable,
bundle_id: browser.bundleIds[0] || null,
version: null,
});
break;
}
}
return [...found.values()].sort((a, b) => a.name.localeCompare(b.name));
}
function findWindowsApps() {
const found = new Map();
const version = windowsChromeVersion();
for (const browser of KNOWN_BROWSERS) {
if (!browser.windowsExecutable) continue;
for (const executablePath of windowsChromeInstallPaths()) {
if (
path.basename(executablePath).toLowerCase() !==
browser.windowsExecutable
)
continue;
found.set(executablePath.toLowerCase(), {
name: browser.name,
command: "chrome",
path: executablePath,
bundle_id: null,
version,
});
}
}
return [...found.values()].sort((a, b) => a.name.localeCompare(b.name));
}
function loadLaunchServicesHandlers() {
const plistPath = path.join(
os.homedir(),
"Library",
"Preferences",
"com.apple.LaunchServices",
"com.apple.launchservices.secure.plist",
);
if (!fs.existsSync(plistPath)) return [];
const output = runCommand([
"plutil",
"-extract",
"LSHandlers",
"json",
"-o",
"-",
plistPath,
]);
if (!output) return [];
try {
const handlers = JSON.parse(output);
return Array.isArray(handlers) ? handlers : [];
} catch {
return [];
}
}
function findDefaultBrowserMacos(installed) {
const byBundleId = new Map(
installed
.filter((item) => item.bundle_id)
.map((item) => [item.bundle_id, item]),
);
const knownByBundleId = knownBrowserByBundleId();
const schemes = {};
for (const handler of loadLaunchServicesHandlers()) {
const scheme = handler.LSHandlerURLScheme;
if (scheme !== "http" && scheme !== "https") continue;
const bundleId = handler.LSHandlerRoleAll || handler.LSHandlerRoleViewer;
if (!bundleId) continue;
const installedMatch = byBundleId.get(bundleId);
const knownMatch = knownByBundleId.get(bundleId);
const resolvedMatch =
installedMatch ||
(knownMatch ? null : resolveMacosAppByBundleId(bundleId));
schemes[scheme] = {
scheme,
bundle_id: bundleId,
name:
installedMatch?.name || knownMatch?.name || resolvedMatch?.name || null,
path: installedMatch?.path || resolvedMatch?.path || null,
version: installedMatch?.version || resolvedMatch?.version || null,
};
}
return { source: "LaunchServices", schemes };
}
function findDefaultBrowserLinux() {
return {
source: "xdg-settings",
desktop_file: runCommand(["xdg-settings", "get", "default-web-browser"]),
};
}
function findDefaultBrowserWindows() {
const schemes = {};
for (const scheme of DEFAULT_BROWSER_SCHEMES) {
const keyPath = `HKCU\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\${scheme}\\UserChoice`;
const progId = readWindowsRegistryValue(keyPath, "ProgId");
if (!progId) continue;
schemes[scheme] = {
scheme,
prog_id: progId,
name: progId.toLowerCase().startsWith("chrome") ? "Google Chrome" : null,
};
}
return { source: "registry", schemes };
}
function collectInventory() {
let installed;
let defaultBrowser;
if (process.platform === "darwin") {
installed = findMacosApps();
defaultBrowser = findDefaultBrowserMacos(installed);
} else if (process.platform === "linux") {
installed = findCommandBrowsers();
defaultBrowser = findDefaultBrowserLinux();
} else if (process.platform === "win32") {
installed = findWindowsApps();
defaultBrowser = findDefaultBrowserWindows();
} else {
installed = findCommandBrowsers();
defaultBrowser = { source: "unsupported", platform: process.platform };
}
return {
platform: process.platform,
default_browser: defaultBrowser,
installed_browsers: installed,
};
}
function printTextReport(inventory, check) {
if (check) {
console.log("Chrome plugin setup/configuration check");
console.log("status: ok");
console.log("");
}
console.log("Default browser");
const defaultBrowser = inventory.default_browser;
const schemes = defaultBrowser.schemes;
if (schemes && Object.keys(schemes).length > 0) {
for (const scheme of ["http", "https"]) {
const item = schemes[scheme];
if (!item) {
console.log(` ${scheme}: unknown`);
continue;
}
const name = item.name || "unknown app";
const identifier = item.bundle_id || item.prog_id || "unknown id";
console.log(` ${scheme}: ${name} (${identifier})`);
if (item.path) console.log(` path: ${item.path}`);
}
} else if (defaultBrowser.desktop_file)
console.log(` ${defaultBrowser.desktop_file}`);
else if (defaultBrowser.prog_id) console.log(` ${defaultBrowser.prog_id}`);
else console.log(` unknown (source: ${defaultBrowser.source || "unknown"})`);
console.log("");
console.log("Installed known internet browsers");
if (inventory.installed_browsers.length === 0) {
console.log(" none found");
return;
}
for (const item of inventory.installed_browsers) {
console.log(` - ${item.name}`);
if (item.bundle_id) console.log(` bundle id: ${item.bundle_id}`);
if (item.version) console.log(` version: ${item.version}`);
console.log(` path: ${item.path}`);
}
}
function parseArgs(argv) {
const flags = new Set(argv);
if (flags.has("-h") || flags.has("--help")) {
console.log("Usage: installed-browsers.js [--check] [--json]");
process.exit(0);
}
return {
check: flags.has("--check"),
json: flags.has("--json"),
};
}
function main() {
const args = parseArgs(process.argv.slice(2));
const inventory = collectInventory();
if (args.json) console.log(JSON.stringify(inventory, null, 2));
else printTextReport(inventory, args.check);
if (args.check && inventory.installed_browsers.length === 0)
process.exitCode = 1;
}
void loadNodeModules()
.then(() => {
main();
})
.catch((error) => {
console.error(error instanceof Error ? error.message : String(error));
(process || globalThis.process)?.exit(2);
});