#!/usr/bin/env node /** * Generate OG Image (Neo Kinpaku brand) * * Renders the social sharing card with Playwright using the real Kinpaku * tokens (lacquer ground, champagne headline, kinpaku-gold accent) and the * kintsugi-seam hero art. Renders at 2x and downscales with sharp for crisp * text. The command count is read live from command-metadata.json so it can * never go stale. * * Output: site/public/og-image-v2.jpg (the cache-busted filename Base.astro * and index.astro reference). Bump the version suffix here and in those two * files together when you want social scrapers to re-fetch a fresh card. * * Usage: bun run og-image */ import { chromium } from 'playwright'; import sharp from 'sharp'; import os from 'os'; import path from 'path'; import fs from 'fs'; import { fileURLToPath, pathToFileURL } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const ROOT_DIR = path.resolve(__dirname, '..'); const OUTPUT_PATH = path.join(ROOT_DIR, 'site', 'public', 'og-image-v2.jpg'); const ART_PATH = path.join( ROOT_DIR, 'site', 'public', 'assets', 'neo-kinpaku', 'candidates', 'finalists', 'm-01-v2-01.png', ); // Count sub-commands from skill/scripts/command-metadata.json (the post-v3.0 // single source of truth), so the card's "N commands" tracks the real total. function getCommandCount() { const metadataPath = path.join(ROOT_DIR, 'skill', 'scripts', 'command-metadata.json'); if (!fs.existsSync(metadataPath)) return 0; const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); return Object.keys(metadata).length; } async function generateOgImage() { const commands = getCommandCount(); // Reference the art by file:// URL (not base64): goto + networkidle then // genuinely waits for it to load, where a data URL emits no network event // and paints black before it decodes. const artUrl = pathToFileURL(ART_PATH).href; console.log(`Detected ${commands} command(s)`); const html = `
Stop shipping generic frontend. A design skill, CLI, and Chrome extension for the tools you already build with.