#!/usr/bin/env node import { mkdir, access } from "node:fs/promises" import path from "node:path" import { fileURLToPath } from "node:url" import { spawn } from "node:child_process" const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const projectDir = path.resolve(__dirname, "..") function run(cmd, args, cwd = projectDir) { return new Promise((resolve, reject) => { const child = spawn(cmd, args, { cwd, stdio: "inherit", shell: false, }) child.on("error", reject) child.on("exit", (code) => { if (code === 0) { resolve() return } reject(new Error(`${cmd} ${args.join(" ")} exited with code ${code ?? -1}`)) }) }) } async function exists(filePath) { try { await access(filePath) return true } catch { return false } } function ensureNode20() { const major = Number.parseInt(process.versions.node.split(".")[0] ?? "0", 10) if (!Number.isFinite(major) || major < 20) { throw new Error(`Node.js 20+ required. Current: ${process.versions.node}`) } } async function main() { ensureNode20() await mkdir(path.join(projectDir, "artifacts"), { recursive: true }) await mkdir(path.join(projectDir, "config"), { recursive: true }) const lockPath = path.join(projectDir, "package-lock.json") if (await exists(lockPath)) { await run("npm", ["ci"]) } else { await run("npm", ["install"]) } await run("npm", ["run", "build"]) await run("npm", ["exec", "playwright", "install", "chromium"]) const distPath = path.join(projectDir, "dist", "server.js") const mcpConfig = { $schema: "https://opencode.ai/config.json", mcp: { "browser-tool": { type: "local", command: ["node", distPath], }, }, } process.stdout.write("\nInstall complete.\n") process.stdout.write("Suggested MCP config snippet:\n") process.stdout.write(`${JSON.stringify(mcpConfig, null, 2)}\n`) } main().catch((error) => { process.stderr.write(`Setup failed: ${error instanceof Error ? error.message : String(error)}\n`) process.exit(1) })