/ scripts / generate-icons.mjs
generate-icons.mjs
 1  /**
 2   * Icon generation script for Mnemonic
 3   * Generates extension icons from source logo
 4   */
 5  
 6  import sharp from 'sharp';
 7  import { mkdir } from 'fs/promises';
 8  import { dirname, join } from 'path';
 9  import { fileURLToPath } from 'url';
10  
11  const __dirname = dirname(fileURLToPath(import.meta.url));
12  const ROOT = join(__dirname, '..');
13  
14  // Icon sizes required for browser extensions
15  const SIZES = [16, 32, 48, 128];
16  
17  // Source logo path
18  const SOURCE_LOGO = join(ROOT, 'src', 'ChatGPT Image Dec 12, 2025, 12_43_49 PM.png');
19  
20  // Output directory (WXT expects public in src/)
21  const OUTPUT_DIR = join(ROOT, 'src', 'public', 'icons');
22  
23  async function generateIcons() {
24    console.log('Generating icons for Mnemonic...');
25    console.log('Source:', SOURCE_LOGO);
26  
27    // Ensure output directory exists
28    await mkdir(OUTPUT_DIR, { recursive: true });
29  
30    // Read source image
31    const source = sharp(SOURCE_LOGO);
32    const metadata = await source.metadata();
33    console.log(`Source image: ${metadata.width}x${metadata.height}`);
34  
35    // The logo image has the icon in the upper-left quadrant
36    // Let's crop to get just the icon (square with M)
37    // Based on the image layout, the icon is roughly in the left portion
38    const iconSize = Math.min(metadata.width, metadata.height);
39  
40    // Extract the icon portion (left side, roughly square)
41    // The M icon appears to be in the upper-left area
42    const cropSize = Math.floor(iconSize * 0.45); // Icon takes about 45% of height
43    const cropLeft = Math.floor(metadata.width * 0.05); // Small margin from left
44    const cropTop = Math.floor(metadata.height * 0.12); // Some margin from top
45  
46    console.log(`Cropping icon at (${cropLeft}, ${cropTop}) size ${cropSize}x${cropSize}`);
47  
48    for (const size of SIZES) {
49      const outputPath = join(OUTPUT_DIR, `icon-${size}.png`);
50  
51      await sharp(SOURCE_LOGO)
52        .extract({
53          left: cropLeft,
54          top: cropTop,
55          width: cropSize,
56          height: cropSize,
57        })
58        .resize(size, size, {
59          fit: 'contain',
60          background: { r: 13, g: 61, b: 61, alpha: 1 }, // #0d3d3d
61        })
62        .png()
63        .toFile(outputPath);
64  
65      console.log(`Generated: icon-${size}.png`);
66    }
67  
68    console.log('\nIcons generated successfully!');
69    console.log('Output directory:', OUTPUT_DIR);
70  }
71  
72  generateIcons().catch(console.error);