Files
fusion/packages/desktop/scripts/generate-icons.ts
gsxdsm 6dde53ff0d fix(desktop): app icon + harden auto-updater loading
Generate a 1024x1024 macOS app icon from the dashboard logo so packaged
builds carry the Fusion brand instead of the default Electron icon, and
load electron-updater dynamically inside a try/catch so packaged builds
tolerate CJS/ESM interop quirks and missing transitive deps. Widen the
electron-builder files whitelist to include electron-updater's
transitive dep tree so they are actually bundled into the asar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 12:51:12 -07:00

59 lines
1.9 KiB
TypeScript

import { mkdir, readFile } from "node:fs/promises";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import sharp from "sharp";
const scriptDir = dirname(fileURLToPath(import.meta.url));
const packageDir = resolve(scriptDir, "..");
const repoRoot = resolve(packageDir, "../..");
const sourceSvgPath = resolve(repoRoot, "packages/dashboard/app/public/logo.svg");
const outputDir = resolve(packageDir, "src/icons");
const iconSizes = [16, 32, 48] as const;
const APP_ICON_SIZE = 1024;
const APP_ICON_PADDING = 128;
const APP_ICON_BG = "#0d1117";
const APP_ICON_FG = "#58a6ff";
async function main(): Promise<void> {
const sourceSvg = await readFile(sourceSvgPath, "utf8");
const trayTintedSvg = sourceSvg.replaceAll("currentColor", "#333333");
const appTintedSvg = sourceSvg.replaceAll("currentColor", APP_ICON_FG);
await mkdir(outputDir, { recursive: true });
await Promise.all(
iconSizes.map(async (size) => {
const outputPath = resolve(outputDir, `tray-${size}.png`);
await sharp(Buffer.from(trayTintedSvg), { density: 1024 })
.resize(size, size, { fit: "contain" })
.png({ compressionLevel: 9 })
.toFile(outputPath);
}),
);
const markSize = APP_ICON_SIZE - APP_ICON_PADDING * 2;
const mark = await sharp(Buffer.from(appTintedSvg), { density: 2048 })
.resize(markSize, markSize, { fit: "contain", background: { r: 0, g: 0, b: 0, alpha: 0 } })
.png()
.toBuffer();
await sharp({
create: {
width: APP_ICON_SIZE,
height: APP_ICON_SIZE,
channels: 4,
background: APP_ICON_BG,
},
})
.composite([{ input: mark, top: APP_ICON_PADDING, left: APP_ICON_PADDING }])
.png({ compressionLevel: 9 })
.toFile(resolve(outputDir, "icon.png"));
console.log(`Generated ${iconSizes.length} tray icons and app icon in ${outputDir}`);
}
void main();