import { expect, test } from "bun:test"; import { Glob } from "bun"; // AGENTS.md: src/core runs in a browser, a userscript and Bun. const CORE_FORBIDDEN: [RegExp, string][] = [ [/\bdocument\b|\bwindow\b|\blocalStorage\b|\bsessionStorage\b/, "DOM global"], [/\bBun\./, "Bun API"], [/from\s+["']node:|import\(["']node:/, "node:* import"], [/\bGM_\w+|\bGM\./, "GM_* API"], [/from\s+["'](?:\.\.\/)+(?:web|server|userscript|cli)\//, "import from a front end"], ]; // spec ยง4: these server files stay web-standard so a Workers entry can be added later. const PORTABLE_SERVER = ["app.ts", "storage.ts", "rate-limit.ts", "config.ts", "assets-path.ts"]; const PORTABLE_FORBIDDEN: [RegExp, string][] = [ [/\bBun\./, "Bun API"], [/from\s+["']node:|import\(["']node:/, "node:* import"], ]; async function violations(pattern: string, rules: [RegExp, string][], only?: string[]) { const problems: string[] = []; for await (const file of new Glob(pattern).scan(".")) { if (only && !only.some((name) => file.endsWith(`/${name}`))) continue; const text = await Bun.file(file).text(); for (const [re, what] of rules) if (re.test(text)) problems.push(`${file}: ${what}`); } return problems; } test("src/core uses no platform APIs and imports no front end", async () => { expect(await violations("src/core/**/*.ts", CORE_FORBIDDEN)).toEqual([]); }); test("portable server files use only web-standard APIs", async () => { expect(await violations("src/server/*.ts", PORTABLE_FORBIDDEN, PORTABLE_SERVER)).toEqual([]); });