#!/usr/bin/env node /** * The Beacon — Enhanced Smoke Test * * Validates: * 1. All JS files parse without syntax errors * 2. HTML references valid script sources * 3. Game data structures are well-formed * 4. No banned provider references */ import { readFileSync, existsSync } from "fs"; import { execSync } from "child_process"; import { join } from "path"; const ROOT = process.cwd(); let failures = 0; function check(label, fn) { try { fn(); console.log(` ✔ ${label}`); } catch (e) { console.error(` ✘ ${label}: ${e.message}`); failures++; } } console.log("--- The Beacon Smoke Test ---\n"); // 1. All JS files parse console.log("[Syntax]"); const jsFiles = execSync("find . -name '*.js' -not -path './node_modules/*'", { encoding: "utf8" }) .trim().split("\n").filter(Boolean); for (const f of jsFiles) { check(`Parse ${f}`, () => { execSync(`node --check ${f}`, { encoding: "utf8" }); }); } // 2. HTML script references exist console.log("\n[HTML References]"); if (existsSync(join(ROOT, "index.html"))) { const html = readFileSync(join(ROOT, "index.html"), "utf8"); const scriptRefs = [...html.matchAll(/src=["']([^"']+\.js)["']/g)].map(m => m[1]); for (const ref of scriptRefs) { check(`Script ref: ${ref}`, () => { if (!existsSync(join(ROOT, ref))) throw new Error("File not found"); }); } } // 3. Game data structure check console.log("\n[Game Data]"); check("js/data.js exists", () => { if (!existsSync(join(ROOT, "js/data.js"))) throw new Error("Missing"); }); // 4. No banned providers console.log("\n[Policy]"); check("No Anthropic references", () => { try { const result = execSync( "grep -ril 'anthropic\\|claude-sonnet\\|claude-opus\\|sk-ant-' --include='*.js' --include='*.json' --include='*.html' . 2>/dev/null || true", { encoding: "utf8" } ).trim(); if (result) throw new Error(`Found in: ${result}`); } catch (e) { if (e.message.startsWith("Found")) throw e; } }); // Summary console.log(`\n--- ${failures === 0 ? "ALL PASSED" : `${failures} FAILURE(S)`} ---`); process.exit(failures > 0 ? 1 : 0);