UNPKG

chrome-cmd

Version:

Control Chrome from the command line - List tabs, execute JavaScript, and more

118 lines (117 loc) 3.73 kB
import { existsSync, readFileSync, unlinkSync } from "node:fs"; import { Command } from "commander"; import { BRIDGE_CONFIG } from "../../bridge/bridge.config.js"; import { FILES_CONFIG } from "../../shared/configs/files.config.js"; import { logger } from "../../shared/utils/helpers/logger.js"; import { execAsync } from "../utils/cli-utils.js"; function createBridgeCommand() { const bridge = new Command("bridge").description("Manage the bridge process (internal/debug)"); bridge.command("status").description("Check if bridge is running").action(async () => { try { const result = await checkBridgeStatus(); if (result.running) { logger.success("\u2713 Bridge is running"); logger.dim(` PID: ${result.pid}`); logger.dim(` Port: ${BRIDGE_CONFIG.PORT}`); } else { logger.warning("\u25CB Bridge is not running"); } } catch (error) { logger.error("Error checking status:", error instanceof Error ? error.message : error); process.exit(1); } }); bridge.command("kill").description("Kill the bridge process").action(async () => { try { const killed = await killBridge(); if (killed) { logger.success("\u2713 Bridge process killed"); logger.dim("\nTip: The Chrome extension will restart it automatically when needed"); } else { logger.warning("\u25CB No bridge process found"); } } catch (error) { logger.error("Error killing bridge:", error instanceof Error ? error.message : error); process.exit(1); } }); bridge.command("restart").description("Restart the bridge process").action(async () => { try { logger.blue("\u27F3 Restarting bridge..."); logger.newline(); const lockCleaned = await cleanLockFile(); if (lockCleaned) { logger.dim(" \u2713 Cleaned stale lock file"); } const killed = await killBridge(); if (killed) { logger.dim(" \u2713 Killed old process"); } await new Promise((resolve) => setTimeout(resolve, 1e3)); logger.dim(" \u2713 Waiting for Chrome extension to restart it..."); logger.newline(); logger.warning("Please reload the Chrome extension at chrome://extensions/"); logger.dim("The extension will automatically start a new bridge instance"); logger.newline(); } catch (error) { logger.error("Error restarting bridge:", error instanceof Error ? error.message : error); process.exit(1); } }); return bridge; } async function checkBridgeStatus() { try { const { stdout } = await execAsync(`lsof -i :${BRIDGE_CONFIG.PORT} -t`); const pid = parseInt(stdout.trim(), 10); if (pid) { return { running: true, pid }; } } catch { } return { running: false }; } async function killBridge() { try { const { stdout } = await execAsync(`lsof -i :${BRIDGE_CONFIG.PORT} -t`); const pid = stdout.trim(); if (pid) { await execAsync(`kill -9 ${pid}`); return true; } } catch { } return false; } async function cleanLockFile() { if (!existsSync(FILES_CONFIG.BRIDGE_LOCK_FILE)) { return false; } try { const lockContent = readFileSync(FILES_CONFIG.BRIDGE_LOCK_FILE, "utf-8").trim(); let pid; try { const lockData = JSON.parse(lockContent); pid = lockData.pid; } catch { pid = parseInt(lockContent, 10); } try { process.kill(pid, 0); return false; } catch { unlinkSync(FILES_CONFIG.BRIDGE_LOCK_FILE); return true; } } catch { try { unlinkSync(FILES_CONFIG.BRIDGE_LOCK_FILE); return true; } catch { return false; } } } export { createBridgeCommand };