Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174#!/usr/bin/env node// Run Chrome DevTools MCP against one leased browser on a fleet Mac.//// The wrapper owns all lifecycle edges: acquire the remote fleet-browser// lease, open a process-owned SSH tunnel, run the upstream MCP server, touch// the lease while alive, then release and close the tunnel on every normal or// signalled exit. A remote reaper handles SIGKILL or controller loss.
import { spawn, spawnSync } from "node:child_process";import { hostname } from "node:os";import net from "node:net";
function parse(argv) { const out = { leaseCommand: "~/.local/bin/fleet-browser", package: "chrome-devtools-mcp@latest", touchMs: 5 * 60 * 1000, }; for (const arg of argv) { const match = arg.match(/^--([^=]+)=(.*)$/); if (!match) continue; const [, key, value] = match; if (key === "host") out.host = value; else if (key === "lease-command") out.leaseCommand = value; else if (key === "expected-user") out.expectedUser = value; else if (key === "package") out.package = value; else if (key === "touch-ms") out.touchMs = Number(value); } if (!out.host || !/^[A-Za-z0-9._-]+$/.test(out.host)) { throw new Error("--host=<fleet-ssh-name> is required"); } if (!/^[A-Za-z0-9_@./~-]+$/.test(out.leaseCommand)) { throw new Error("--lease-command contains unsafe characters"); } return out;}
function freePort() { return new Promise((resolve, reject) => { const server = net.createServer(); server.unref(); server.on("error", reject); server.listen(0, "127.0.0.1", () => { const { port } = server.address(); server.close(error => (error ? reject(error) : resolve(port))); }); });}
function remoteLease(config, verb, owner, { quiet = false } = {}) { const args = [ config.host, config.leaseCommand, verb, "--owner", owner, "--json", ]; if (verb === "acquire" && config.expectedUser) args.push("--expected-user", config.expectedUser); const result = spawnSync("ssh", args, { encoding: "utf8", timeout: 25000 }); if (result.status !== 0 && !quiet) { throw new Error(result.stderr.trim() || result.stdout.trim() || `${verb} failed`); } if (result.status !== 0) return null; try { return JSON.parse(result.stdout || "{}"); } catch { if (!quiet) throw new Error(`${verb} returned invalid JSON`); return null; }}
async function waitForTunnel(port, tunnel, timeoutMs = 12000) { const deadline = Date.now() + timeoutMs; while (Date.now() < deadline) { if (tunnel.exitCode !== null) { throw new Error(`SSH tunnel exited ${tunnel.exitCode}`); } const ready = await new Promise(resolve => { const socket = net.createConnection({ host: "127.0.0.1", port }); socket.setTimeout(500); socket.once("connect", () => { socket.destroy(); resolve(true); }); socket.once("timeout", () => { socket.destroy(); resolve(false); }); socket.once("error", () => resolve(false)); }); if (ready) return; await new Promise(resolve => setTimeout(resolve, 200)); } throw new Error(`timed out waiting for fleet Chrome on local port ${port}`);}
function terminate(child, signal = "SIGTERM") { if (!child || child.exitCode !== null) return; try { child.kill(signal); } catch {}}
async function main() { const config = parse(process.argv.slice(2)); const owner = `${hostname()}:chrome-devtools:${process.pid}`.replace(/[^A-Za-z0-9._:@/-]/g, "-"); let acquired = false; let tunnel; let mcp; let touchTimer; let cleaning = false;
const cleanup = () => { if (cleaning) return; cleaning = true; clearInterval(touchTimer); terminate(mcp); terminate(tunnel); if (acquired) remoteLease(config, "release", owner, { quiet: true }); };
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) { process.once(signal, () => { cleanup(); process.exit(128 + ({ SIGHUP: 1, SIGINT: 2, SIGTERM: 15 })[signal]); }); } process.once("exit", cleanup);
try { const lease = remoteLease(config, "acquire", owner); if (!lease?.port || !lease?.webSocketPath) { throw new Error("fleet browser lease returned no DevTools endpoint"); } acquired = true; const localPort = await freePort(); tunnel = spawn( "ssh", [ "-N", "-o", "ExitOnForwardFailure=yes", "-o", "ServerAliveInterval=15", "-o", "ServerAliveCountMax=2", "-L", `${localPort}:127.0.0.1:${lease.port}`, config.host, ], { stdio: ["ignore", "ignore", "inherit"] }, ); await waitForTunnel(localPort, tunnel);
touchTimer = setInterval( () => remoteLease(config, "touch", owner, { quiet: true }), config.touchMs, ); touchTimer.unref();
mcp = spawn( "npx", [ "-y", config.package, `--ws-endpoint=ws://127.0.0.1:${localPort}${lease.webSocketPath}`, "--no-usage-statistics", ], { stdio: "inherit" }, ); const code = await new Promise((resolve, reject) => { mcp.once("error", reject); mcp.once("exit", value => resolve(value ?? 1)); }); cleanup(); process.exitCode = code; } catch (error) { console.error(`fleet-chrome-devtools: ${error.message || error}`); cleanup(); process.exitCode = 1; }}
main();