Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596#!/usr/bin/env node// bills/bin/gen-illy.mjs — generate the editorial "illy" that heads each// bills update. A calm colored-pencil billing-desk still life via gpt-image-2.//// Prompt: bills/illy.txt// Output: bills/out/bills-illy.png (archival original)// system/public/bills.aesthetic.computer/illy.png (served on the site)//// Usage:// node bills/bin/gen-illy.mjs # cached if the site illy exists// node bills/bin/gen-illy.mjs --force # regenerate
import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync } from "node:fs";import { resolve, dirname } from "node:path";import { fileURLToPath } from "node:url";import { spawnSync } from "node:child_process";
const HERE = dirname(fileURLToPath(import.meta.url));const LANE = resolve(HERE, ".."); // bills/const REPO = resolve(LANE, ".."); // repo root
const flags = {};for (let i = 2; i < process.argv.length; i++) { if (process.argv[i].startsWith("--")) flags[process.argv[i].slice(2)] = true;}const FORCE = flags.force === true;const SIZE = "1536x1024"; // wide banner
const PROMPT_PATH = resolve(LANE, "illy.txt");const OUT_PATH = resolve(LANE, "out", "bills-illy.png"); // archival originalconst SITE_PATH = resolve(REPO, "system/public/bills.aesthetic.computer", "illy.jpg"); // web bannermkdirSync(resolve(LANE, "out"), { recursive: true });
// Optimize the served banner: 1280px-wide JPEG (~400KB) via macOS sips,// falling back to a raw PNG copy if sips is unavailable.function writeServed(srcPng) { const sips = spawnSync("sips", ["-Z", "1280", "-s", "format", "jpeg", "-s", "formatOptions", "80", srcPng, "--out", SITE_PATH], { stdio: "ignore" }); if (sips.status === 0 && existsSync(SITE_PATH)) return true; copyFileSync(srcPng, SITE_PATH.replace(/\.jpg$/, ".png")); return false;}
function loadOpenAIKey() { if (process.env.OPENAI_API_KEY) return process.env.OPENAI_API_KEY; const vault = `${REPO}/aesthetic-computer-vault/.devcontainer/envs/devcontainer.env`; if (existsSync(vault)) { for (const line of readFileSync(vault, "utf8").split("\n")) { if (line.startsWith("OPENAI_API_KEY=")) { return line.slice("OPENAI_API_KEY=".length).trim().replace(/^['"]|['"]$/g, ""); } } } throw new Error("OPENAI_API_KEY not set and not found in vault");}
if (existsSync(SITE_PATH) && !FORCE) { console.log(`✓ cached illy → ${SITE_PATH.replace(REPO + "/", "")} (use --force to regen)`); process.exit(0);}
const apiKey = loadOpenAIKey();const prompt = readFileSync(PROMPT_PATH, "utf8").trim();console.log(`▸ bills illy · ${SIZE}`);const t0 = Date.now();
const res = await fetch("https://api.openai.com/v1/images/generations", { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ model: "gpt-image-2", prompt, size: SIZE, quality: "high", n: 1, }),});if (!res.ok) { console.error(`✗ OpenAI ${res.status}: ${(await res.text()).slice(0, 600)}`); process.exit(1);}const json = await res.json();const b64 = json.data?.[0]?.b64_json;if (!b64) { console.error(`✗ no image: ${JSON.stringify(json).slice(0, 280)}`); process.exit(1);}const buf = Buffer.from(b64, "base64");writeFileSync(OUT_PATH, buf);const optimized = writeServed(OUT_PATH);console.log(`✓ ${((Date.now() - t0) / 1000).toFixed(1)}s → ${OUT_PATH.replace(REPO + "/", "")}`);console.log(`✓ served ${optimized ? "JPEG" : "PNG"} → ${SITE_PATH.replace(REPO + "/", "")}`);