diff --git a/package.json b/package.json index f000ad5e5..88a3f917b 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "dev": "bun run server/index.js", "start": "bun --production run server/index.js", "test": "bun test", - "screenshot": "bun run scripts/screenshot-antipatterns.js" + "screenshot": "bun run scripts/screenshot-antipatterns.js", + "og-image": "bun run scripts/generate-og-image.js" }, "type": "module" } diff --git a/public/index.html b/public/index.html index c770cfe64..c5fe96ad1 100644 --- a/public/index.html +++ b/public/index.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@ - + diff --git a/public/og-image.jpg b/public/og-image.jpg new file mode 100644 index 000000000..35bbdc24e Binary files /dev/null and b/public/og-image.jpg differ diff --git a/public/og-image.png b/public/og-image.png deleted file mode 100644 index fff71fca0..000000000 Binary files a/public/og-image.png and /dev/null differ diff --git a/public/og-image.svg b/public/og-image.svg deleted file mode 100644 index 2661f1c28..000000000 --- a/public/og-image.svg +++ /dev/null @@ -1,32 +0,0 @@ - diff --git a/scripts/build.js b/scripts/build.js index 7e02848e6..d15f39709 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -137,7 +137,7 @@ async function build() { await buildStaticSite(); // Copy root-level static assets that need stable (unhashed) URLs - const staticAssets = ['og-image.png', 'robots.txt', 'sitemap.xml', 'favicon.svg', 'apple-touch-icon.png']; + const staticAssets = ['og-image.jpg', 'robots.txt', 'sitemap.xml', 'favicon.svg', 'apple-touch-icon.png']; const buildDir = path.join(ROOT_DIR, 'build'); for (const asset of staticAssets) { const src = path.join(ROOT_DIR, 'public', asset); diff --git a/scripts/generate-og-image.js b/scripts/generate-og-image.js new file mode 100644 index 000000000..f1b6a1b04 --- /dev/null +++ b/scripts/generate-og-image.js @@ -0,0 +1,213 @@ +#!/usr/bin/env node + +/** + * Generate OG Image + * + * Renders the OG image using Playwright with proper Google Fonts. + * Counts skills and commands dynamically from the source/ directory. + * + * Usage: bun run og-image + */ + +import { chromium } from 'playwright'; +import path from 'path'; +import fs from 'fs'; +import { fileURLToPath } 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, 'public', 'og-image.jpg'); + +// Count skills and commands from source directory +function getCounts() { + const skillsDir = path.join(ROOT_DIR, 'source', 'skills'); + const commandsDir = path.join(ROOT_DIR, 'source', 'commands'); + + const skills = fs.existsSync(skillsDir) + ? fs.readdirSync(skillsDir).filter(f => fs.statSync(path.join(skillsDir, f)).isDirectory()).length + : 0; + + const commands = fs.existsSync(commandsDir) + ? fs.readdirSync(commandsDir).filter(f => f.endsWith('.md')).length + : 0; + + return { skills, commands }; +} + +async function generateOgImage() { + const { skills, commands } = getCounts(); + console.log(`Detected ${skills} skill(s), ${commands} command(s)`); + + const html = ` + +
+ + + + + + + +