import { ThumbnailGenerator } from "@mintel/thumbnail-generator"; import * as path from "node:path"; import * as fs from "node:fs/promises"; async function run() { const apiKey = process.env.REPLICATE_API_TOKEN || process.env.REPLICATE_API_KEY; if (!apiKey) { console.error("❌ Missing REPLICATE_API_TOKEN in environment."); process.exit(1); } const targetFile = process.argv[2]; if (!targetFile) { console.error( "❌ Usage: npx tsx scripts/generate-thumbnail.ts ", ); process.exit(1); } let topic = targetFile; let filename = "thumbnail.png"; // Try to parse the topic from the MDX frontmatter if a file is provided if (targetFile.endsWith(".mdx")) { try { const content = await fs.readFile(targetFile, "utf8"); const titleMatch = content.match(/title:\s*"?([^"\n]+)"?/); topic = titleMatch ? titleMatch[1] : path.basename(targetFile, ".mdx"); filename = `${path.basename(targetFile, ".mdx")}.png`; } catch (e) { console.warn( `⚠️ Could not read ${targetFile} as a file. Using literal argument as topic.`, ); topic = targetFile; } } console.log(`Generating abstract thumbnail for topic: "${topic}"`); const generator = new ThumbnailGenerator({ replicateApiKey: apiKey }); const isRoot = process.cwd().endsWith("mintel.me"); const baseDir = isRoot ? path.join(process.cwd(), "apps", "web") : process.cwd(); const outputPath = path.join(baseDir, "public", "blog", filename); // Check if thumbnail already exists to avoid redundant generation try { await fs.access(outputPath); console.log(`⏭️ Thumbnail already exists, skipping: ${filename}`); return; } catch { // File does not exist, proceed with generation } const inspirationPath = path.join( baseDir, "public", "blog", "inspiration.png", ); let hasInspiration = false; try { await fs.access(inspirationPath); hasInspiration = true; } catch { hasInspiration = false; } let customPrompt = `Extremely clean, flat, abstract geometric illustration. Use the provided image prompt ONLY as a STRICT color and texture reference. You MUST generate completely new, distinct geometric shapes that directly represent the topic. Characteristics: Flat vector design, 2D only (no 3D), tech/startup/agency aesthetics, highly professional, extensive use of whitespace. No text, no chaotic lines, no humans.`; if (topic.includes("Service") || topic.includes("Sorglos")) { customPrompt += " Visually depict the concept of 'effortless automation'. Use a large, distinct, central endless loop or a floating interconnected minimal machine."; } else if (topic.includes("Zero") || topic.includes("Overhead")) { customPrompt += " Visually depict the concept of 'cutting out the middleman'. Use a massive, heavy block being sliced in half or a direct, unfiltered sharp lightning/beam connecting two points."; } await generator.generateImage(topic, outputPath, { systemPrompt: customPrompt, imagePrompt: hasInspiration ? inspirationPath : undefined, }); } run().catch((e) => { console.error("❌ Thumbnail generation failed:", e); process.exit(1); });