@spark-apps/piclet 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -21
- package/Readme.md +3 -2
- package/dist/cli.js +773 -594
- package/dist/cli.js.map +1 -1
- package/dist/gui/css/theme.css +1 -1
- package/dist/gui/js/piclet.js +10 -1
- package/dist/gui/loading.hta +5 -12
- package/dist/gui/piclet.html +31 -25
- package/package.json +2 -2
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/lib/banner.ts","../src/lib/config.ts","../src/lib/paths.ts","../src/lib/prompts.ts","../src/lib/registry.ts","../src/tools/iconpack.ts","../src/lib/gui-server.ts","../src/lib/presets.ts","../src/lib/logger.ts","../src/lib/magick.ts","../src/tools/makeicon.ts","../src/tools/piclet-main.ts","../src/tools/remove-bg.ts","../src/tools/rescale.ts","../src/tools/storepack.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { extname } from 'node:path';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport { showBanner } from './lib/banner.js';\nimport { getConfigPath, loadConfig, resetConfig } from './lib/config.js';\nimport { wslToWindows } from './lib/paths.js';\nimport { clearOverrides, setOverrides, setUseDefaults } from './lib/prompts.js';\nimport { addRegistryKey, deleteRegistryKey, isWSL } from './lib/registry.js';\nimport * as iconpack from './tools/iconpack.js';\nimport * as makeicon from './tools/makeicon.js';\nimport * as picletMain from './tools/piclet-main.js';\nimport * as removeBg from './tools/remove-bg.js';\nimport * as rescale from './tools/rescale.js';\nimport * as storepack from './tools/storepack.js';\n\n/** Tool configuration */\ninterface ToolConfig {\n\tid: string;\n\tname: string;\n\ticon: string;\n\textensions: string[];\n}\n\n/** Tool registration result */\ninterface RegistrationResult {\n\textension: string;\n\ttoolName: string;\n\tsuccess: boolean;\n}\n\n/** All available tools (individual) */\nconst tools = [\n\t{ config: makeicon.config, run: makeicon.run },\n\t{ config: removeBg.config, run: removeBg.run },\n\t{ config: rescale.config, run: rescale.run },\n\t{ config: iconpack.config, run: iconpack.run },\n\t{ config: storepack.config, run: storepack.run },\n];\n\n/** Unified PicLet tool (all-in-one) */\nconst picletTool = { config: picletMain.config, runGUI: picletMain.runGUI };\n\nconst program = new Command();\n\n/** Get dist directory */\nfunction getDistDir(): string {\n\tconst currentFile = fileURLToPath(import.meta.url);\n\treturn dirname(currentFile);\n}\n\n/** Get registry base path for PicLet menu on an extension */\nfunction getMenuBasePath(extension: string): string {\n\treturn `HKCU\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n}\n\n/** Get all unique extensions from tools */\nfunction getAllExtensions(): string[] {\n\tconst extensions = new Set<string>();\n\tfor (const { config } of tools) {\n\t\tfor (const ext of config.extensions) {\n\t\t\textensions.add(ext);\n\t\t}\n\t}\n\treturn Array.from(extensions);\n}\n\n/** Get tools that support a given extension */\nfunction getToolsForExtension(extension: string) {\n\treturn tools.filter((t) => t.config.extensions.includes(extension));\n}\n\n/** Tools that use TUI (terminal GUI) mode */\nconst tuiTools = ['makeicon', 'remove-bg', 'rescale', 'iconpack', 'storepack'];\n\n/** Register unified PicLet menu item directly on context menu (no submenu) */\nasync function registerUnifiedMenu(\n\textension: string,\n\ticonsDir: string,\n\tlauncherPath: string,\n): Promise<RegistrationResult> {\n\tconst basePath = `HKCU\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\n\t// Create direct PicLet menu item (not a submenu)\n\tconst menuSuccess = await addRegistryKey(basePath, 'MUIVerb', 'PicLet');\n\tconst iconSuccess = await addRegistryKey(basePath, 'Icon', `${iconsDirWin}\\\\banana.ico`);\n\n\t// Enable multi-select\n\tawait addRegistryKey(basePath, 'MultiSelectModel', 'Player');\n\n\t// Command - opens unified GUI\n\tconst commandValue = `wscript.exe //B \"${launcherWin}\" piclet \"%1\" -g`;\n\tconst cmdSuccess = await addRegistryKey(`${basePath}\\\\command`, '', commandValue);\n\n\treturn {\n\t\textension,\n\t\ttoolName: 'PicLet',\n\t\tsuccess: menuSuccess && iconSuccess && cmdSuccess,\n\t};\n}\n\n/** Register PicLet submenu for a single extension (legacy - individual tools) */\nasync function registerMenuForExtension(\n\textension: string,\n\ticonsDir: string,\n\tlauncherPath: string,\n): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\tconst basePath = getMenuBasePath(extension);\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\tconst extensionTools = getToolsForExtension(extension);\n\n\t// Create parent PicLet menu\n\tawait addRegistryKey(basePath, 'MUIVerb', 'PicLet');\n\tawait addRegistryKey(basePath, 'Icon', `${iconsDirWin}\\\\banana.ico`);\n\tawait addRegistryKey(basePath, 'SubCommands', '');\n\n\t// Create submenu for each tool\n\tfor (const { config } of extensionTools) {\n\t\tconst toolPath = `${basePath}\\\\shell\\\\${config.id}`;\n\n\t\tconst menuSuccess = await addRegistryKey(toolPath, 'MUIVerb', config.name);\n\t\tconst iconSuccess = await addRegistryKey(\n\t\t\ttoolPath,\n\t\t\t'Icon',\n\t\t\t`${iconsDirWin}\\\\${config.icon}`,\n\t\t);\n\n\t\t// Enable multi-select\n\t\tawait addRegistryKey(toolPath, 'MultiSelectModel', 'Player');\n\n\t\t// Command - use VBScript launcher for hidden cmd.exe window\n\t\tlet commandValue: string;\n\t\tif (tuiTools.includes(config.id)) {\n\t\t\t// GUI mode - opens Edge app window\n\t\t\tcommandValue = `wscript.exe //B \"${launcherWin}\" ${config.id} \"%1\" -g`;\n\t\t} else {\n\t\t\t// Run headless with defaults\n\t\t\tcommandValue = `wscript.exe //B \"${launcherWin}\" ${config.id} \"%1\" -y`;\n\t\t}\n\t\tconst cmdSuccess = await addRegistryKey(\n\t\t\t`${toolPath}\\\\command`,\n\t\t\t'',\n\t\t\tcommandValue,\n\t\t);\n\n\t\tresults.push({\n\t\t\textension,\n\t\t\ttoolName: config.name,\n\t\t\tsuccess: menuSuccess && iconSuccess && cmdSuccess,\n\t\t});\n\t}\n\n\treturn results;\n}\n\n/** Unregister PicLet menu for a single extension */\nasync function unregisterMenuForExtension(\n\textension: string,\n): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\tconst basePath = getMenuBasePath(extension);\n\tconst extensionTools = getToolsForExtension(extension);\n\n\t// Delete each tool's submenu\n\tfor (const { config } of extensionTools) {\n\t\tconst toolPath = `${basePath}\\\\shell\\\\${config.id}`;\n\t\tawait deleteRegistryKey(`${toolPath}\\\\command`);\n\t\tconst success = await deleteRegistryKey(toolPath);\n\n\t\tresults.push({\n\t\t\textension,\n\t\t\ttoolName: config.name,\n\t\t\tsuccess,\n\t\t});\n\t}\n\n\t// Delete the shell container\n\tawait deleteRegistryKey(`${basePath}\\\\shell`);\n\n\t// Delete parent PicLet menu\n\tawait deleteRegistryKey(basePath);\n\n\treturn results;\n}\n\n/** Register all tools - unified mode (single PicLet menu item) */\nasync function registerAllTools(\n\tdistDir: string,\n): Promise<RegistrationResult[]> {\n\tconst iconsDir = join(distDir, 'icons');\n\tconst launcherPath = join(distDir, 'launcher.vbs');\n\tconst results: RegistrationResult[] = [];\n\n\t// Register unified PicLet menu for each supported extension\n\tfor (const extension of picletTool.config.extensions) {\n\t\tconst result = await registerUnifiedMenu(extension, iconsDir, launcherPath);\n\t\tresults.push(result);\n\t}\n\n\treturn results;\n}\n\n/** Unregister all tools */\nasync function unregisterAllTools(): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\n\t// Unregister from all extensions (both unified and legacy)\n\tconst allExts = new Set([...getAllExtensions(), ...picletTool.config.extensions]);\n\tfor (const extension of allExts) {\n\t\tconst basePath = getMenuBasePath(extension);\n\n\t\t// Try to delete any submenus (legacy)\n\t\tconst extResults = await unregisterMenuForExtension(extension);\n\t\tresults.push(...extResults);\n\n\t\t// Also delete the unified command if it exists\n\t\tawait deleteRegistryKey(`${basePath}\\\\command`);\n\t\tawait deleteRegistryKey(basePath);\n\t}\n\n\treturn results;\n}\n\n/** Get tool by ID */\nfunction getTool(id: string) {\n\treturn tools.find((t) => t.config.id === id);\n}\n\n/** Validate files have correct extensions for the tool */\nfunction validateExtensions(\n\tfiles: string[],\n\tallowedExtensions: string[],\n): { valid: string[]; invalid: string[] } {\n\tconst valid: string[] = [];\n\tconst invalid: string[] = [];\n\n\tfor (const file of files) {\n\t\tconst ext = extname(file).toLowerCase();\n\t\tif (allowedExtensions.includes(ext)) {\n\t\t\tvalid.push(file);\n\t\t} else {\n\t\t\tinvalid.push(file);\n\t\t}\n\t}\n\n\treturn { valid, invalid };\n}\n\n/** Run tool on multiple files */\nasync function runToolOnFiles(\n\ttoolId: string,\n\tfiles: string[],\n\tuseYes: boolean,\n): Promise<boolean> {\n\tconst tool = getTool(toolId);\n\tif (!tool) {\n\t\tconsole.error(chalk.red(`Tool not found: ${toolId}`));\n\t\treturn false;\n\t}\n\n\t// Validate extensions\n\tconst { valid, invalid } = validateExtensions(files, tool.config.extensions);\n\n\tif (invalid.length > 0) {\n\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\tfor (const file of invalid) {\n\t\t\tconsole.error(chalk.red(` ✗ ${file}`));\n\t\t}\n\t\tconsole.error(\n\t\t\tchalk.yellow(\n\t\t\t\t`\\nSupported extensions: ${tool.config.extensions.join(', ')}`,\n\t\t\t),\n\t\t);\n\t\tif (valid.length === 0) return false;\n\t\tconsole.log();\n\t}\n\n\t// Enable defaults mode if --yes flag or multiple files\n\tif (useYes || valid.length > 1) {\n\t\tsetUseDefaults(true);\n\t}\n\n\t// Process files\n\tlet allSuccess = true;\n\tfor (let i = 0; i < valid.length; i++) {\n\t\tconst file = valid[i];\n\t\tif (valid.length > 1) {\n\t\t\tconsole.log(chalk.cyan(`\\n[${i + 1}/${valid.length}] ${file}`));\n\t\t}\n\t\tconst success = await tool.run(file);\n\t\tif (!success) allSuccess = false;\n\t}\n\n\treturn allSuccess;\n}\n\nfunction showHelp(): void {\n\tshowBanner();\n\n\tconst dim = chalk.gray;\n\tconst cmd = chalk.cyan;\n\tconst arg = chalk.yellow;\n\tconst opt = chalk.green;\n\tconst head = chalk.white.bold;\n\n\tconsole.log(\n\t\t` ${head('Usage:')} piclet ${cmd('<command>')} ${arg('<file>')} ${opt('[options]')}`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Unified'));\n\tconsole.log(\n\t\t` ${cmd('piclet')} ${arg('<file>')} Open all tools in one window`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Individual Tools'));\n\tconsole.log(\n\t\t` ${cmd('makeicon')} ${arg('<file>')} Convert PNG to multi-resolution ICO`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('remove-bg')} ${arg('<file>')} Remove solid background from image`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('scale')} ${arg('<file>')} Resize image with optional padding`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('iconpack')} ${arg('<file>')} Generate icon sets for Web/Android/iOS`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('storepack')} ${arg('<file>')} Generate assets for app stores`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Setup'));\n\tconsole.log(\n\t\t` ${cmd('install')} Add Windows right-click menu`,\n\t);\n\tconsole.log(` ${cmd('uninstall')} Remove right-click menu`);\n\tconsole.log();\n\tconsole.log(head(' Config'));\n\tconsole.log(` ${cmd('config')} Display current settings`);\n\tconsole.log(` ${cmd('config reset')} Restore defaults`);\n\tconsole.log();\n\tconsole.log(head(' Examples'));\n\tconsole.log(` ${dim('$')} piclet ${cmd('piclet')} ${arg('image.png')} ${dim('# All tools in one window')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('makeicon')} ${arg('logo.png')} ${dim('# Interactive')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('makeicon')} ${arg('*.png')} ${opt('-y')} ${dim('# Batch with defaults')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('remove-bg')} ${arg('photo.png')} ${dim('# Interactive prompts')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('scale')} ${arg('image.jpg')} ${dim('# Interactive resize')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('iconpack')} ${arg('icon.png')} ${opt('-y')} ${dim('# All platforms')}`);\n\tconsole.log();\n\tconsole.log(head(' Requirements'));\n\tconsole.log(' - WSL (Windows Subsystem for Linux)');\n\tconsole.log(' - ImageMagick: sudo apt install imagemagick');\n\tconsole.log();\n}\n\n// Override default help\nprogram.helpInformation = () => '';\nprogram.on('--help', () => {});\n\nprogram\n\t.name('piclet')\n\t.description('Image manipulation utility toolkit with Windows shell integration')\n\t.version('1.0.0')\n\t.action(() => {\n\t\tshowHelp();\n\t});\n\n// Help command\nprogram\n\t.command('help')\n\t.description('Show help')\n\t.action(() => {\n\t\tshowHelp();\n\t});\n\n// Install command\nprogram\n\t.command('install')\n\t.description('Install Windows shell context menu integration')\n\t.action(async () => {\n\t\tshowBanner();\n\t\tconsole.log(chalk.bold('Installing...\\n'));\n\n\t\tif (!isWSL()) {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow('! Not running in WSL. Registry integration skipped.'),\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow('! Run \"piclet install\" from WSL to add context menu.'),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Clean up existing entries first\n\t\tconsole.log(chalk.dim('Removing old entries...'));\n\t\tawait unregisterAllTools();\n\t\tconsole.log();\n\n\t\tconst results = await registerAllTools(getDistDir());\n\t\tconst successCount = results.filter((r) => r.success).length;\n\n\t\tfor (const result of results) {\n\t\t\tif (result.success) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${chalk.green('✓')} ${result.extension} → ${result.toolName}`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${chalk.red('✗')} ${result.extension} → ${result.toolName} (failed)`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconsole.log();\n\t\tif (successCount === results.length) {\n\t\t\tconsole.log(\n\t\t\t\tchalk.green(`✓ Registered ${successCount} context menu entries.`),\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(`! Registered ${successCount}/${results.length} entries.`),\n\t\t\t);\n\t\t}\n\n\t\tconsole.log(chalk.bold('\\nUsage:'));\n\t\tconsole.log(' Right-click any supported image in Windows Explorer.');\n\t\tconsole.log(' Multi-select supported for batch processing.');\n\t\tconsole.log();\n\t});\n\n// Uninstall command\nprogram\n\t.command('uninstall')\n\t.description('Remove Windows shell context menu integration')\n\t.action(async () => {\n\t\tshowBanner();\n\t\tconsole.log(chalk.bold('Uninstalling...\\n'));\n\n\t\tif (!isWSL()) {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow('! Not running in WSL. Registry cleanup skipped.'),\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(\n\t\t\t\t\t'! Run \"piclet uninstall\" from WSL to remove context menu.',\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst results = await unregisterAllTools();\n\t\tconst removedCount = results.filter((r) => r.success).length;\n\n\t\tfor (const result of results) {\n\t\t\tif (result.success) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${chalk.green('✓')} Removed: ${result.extension} → ${result.toolName}`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${chalk.gray('-')} Skipped: ${result.extension} → ${result.toolName}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconsole.log();\n\t\tconsole.log(\n\t\t\tchalk.green(\n\t\t\t\t`✓ Cleanup complete. Removed ${removedCount}/${results.length} entries.`,\n\t\t\t),\n\t\t);\n\t\tconsole.log(chalk.dim('\\nThanks for using PicLet!\\n'));\n\t});\n\n// Make Icon command\nprogram\n\t.command('makeicon <files...>')\n\t.description('Convert PNG to multi-resolution ICO file')\n\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t.option('-g, --gui', 'Use GUI for confirmation')\n\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t// GUI mode\n\t\tif (options.gui) {\n\t\t\tconst { valid, invalid } = validateExtensions(files, makeicon.config.extensions);\n\t\t\tif (invalid.length > 0) {\n\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (valid.length === 0) {\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tconst result = await makeicon.runGUI(valid[0]);\n\t\t\tprocess.exit(result ? 0 : 1);\n\t\t}\n\n\t\tconst success = await runToolOnFiles(\n\t\t\t'makeicon',\n\t\t\tfiles,\n\t\t\toptions.yes ?? false,\n\t\t);\n\t\tprocess.exit(success ? 0 : 1);\n\t});\n\n// Remove Background command\nprogram\n\t.command('remove-bg <files...>')\n\t.alias('removebg')\n\t.description('Remove solid background from image')\n\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t.option('-g, --gui', 'Use TUI (terminal GUI) for options')\n\t.option('-f, --fuzz <percent>', 'Fuzz tolerance 0-100 (default: 10)')\n\t.option('-t, --trim', 'Trim transparent edges (default: true)')\n\t.option('--no-trim', 'Do not trim transparent edges')\n\t.option('-p, --preserve-inner', 'Preserve inner areas of same color')\n\t.option('-s, --square', 'Make output square with padding')\n\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean; fuzz?: string; trim?: boolean; preserveInner?: boolean; square?: boolean }) => {\n\t\t// GUI mode - open HTML interface in browser\n\t\tif (options.gui) {\n\t\t\tconst { valid, invalid } = validateExtensions(files, removeBg.config.extensions);\n\t\t\tif (invalid.length > 0) {\n\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (valid.length === 0) {\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\t// Only process first file in GUI mode\n\t\t\tconst result = await removeBg.runGUI(valid[0]);\n\t\t\tprocess.exit(result ? 0 : 1);\n\t\t}\n\n\t\t// Set overrides from CLI args\n\t\tif (options.fuzz !== undefined) {\n\t\t\tsetOverrides({ 'fuzz': Number(options.fuzz) });\n\t\t}\n\t\tif (options.trim !== undefined) {\n\t\t\tsetOverrides({ 'trim': options.trim });\n\t\t}\n\t\tif (options.preserveInner) {\n\t\t\tsetOverrides({ 'preserve inner': true });\n\t\t}\n\t\tif (options.square) {\n\t\t\tsetOverrides({ 'square': true });\n\t\t}\n\n\t\tconst success = await runToolOnFiles(\n\t\t\t'remove-bg',\n\t\t\tfiles,\n\t\t\toptions.yes ?? false,\n\t\t);\n\t\tclearOverrides();\n\t\tprocess.exit(success ? 0 : 1);\n\t});\n\n// Scale command\nprogram\n\t.command('scale <files...>')\n\t.alias('rescale')\n\t.description('Resize image with optional padding')\n\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t.option('-g, --gui', 'Use GUI for options')\n\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t// GUI mode\n\t\tif (options.gui) {\n\t\t\tconst { valid, invalid } = validateExtensions(files, rescale.config.extensions);\n\t\t\tif (invalid.length > 0) {\n\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (valid.length === 0) {\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tconst result = await rescale.runGUI(valid[0]);\n\t\t\tprocess.exit(result ? 0 : 1);\n\t\t}\n\n\t\tconst success = await runToolOnFiles(\n\t\t\t'rescale',\n\t\t\tfiles,\n\t\t\toptions.yes ?? false,\n\t\t);\n\t\tprocess.exit(success ? 0 : 1);\n\t});\n\n// Icon Pack command\nprogram\n\t.command('iconpack <files...>')\n\t.description('Generate icon sets for Web, Android, iOS')\n\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t.option('-g, --gui', 'Use GUI for options')\n\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t// GUI mode\n\t\tif (options.gui) {\n\t\t\tconst { valid, invalid } = validateExtensions(files, iconpack.config.extensions);\n\t\t\tif (invalid.length > 0) {\n\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (valid.length === 0) {\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tconst result = await iconpack.runGUI(valid[0]);\n\t\t\tprocess.exit(result ? 0 : 1);\n\t\t}\n\n\t\tconst success = await runToolOnFiles(\n\t\t\t'iconpack',\n\t\t\tfiles,\n\t\t\toptions.yes ?? false,\n\t\t);\n\t\tprocess.exit(success ? 0 : 1);\n\t});\n\n// Store Pack command\nprogram\n\t.command('storepack <files...>')\n\t.description('Generate assets for app stores (Windows, Unity, Steam, etc.)')\n\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t.option('-g, --gui', 'Use GUI for options')\n\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t// GUI mode\n\t\tif (options.gui) {\n\t\t\tconst { valid, invalid } = validateExtensions(files, storepack.config.extensions);\n\t\t\tif (invalid.length > 0) {\n\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (valid.length === 0) {\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tconst result = await storepack.runGUI(valid[0]);\n\t\t\tprocess.exit(result ? 0 : 1);\n\t\t}\n\n\t\tconst success = await runToolOnFiles(\n\t\t\t'storepack',\n\t\t\tfiles,\n\t\t\toptions.yes ?? false,\n\t\t);\n\t\tprocess.exit(success ? 0 : 1);\n\t});\n\n// Unified PicLet command (all tools in one window)\nprogram\n\t.command('piclet <file>')\n\t.description('Open unified PicLet window with all tools')\n\t.option('-g, --gui', 'Use GUI (default)')\n\t.action(async (file: string) => {\n\t\tconst { valid, invalid } = validateExtensions([file], picletTool.config.extensions);\n\t\tif (invalid.length > 0) {\n\t\t\tconsole.error(chalk.red(`Invalid file type: ${file}`));\n\t\t\tconsole.error(chalk.yellow(`Supported: ${picletTool.config.extensions.join(', ')}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tconst result = await picletTool.runGUI(valid[0]);\n\t\tprocess.exit(result ? 0 : 1);\n\t});\n\n// Config command\nconst configCmd = program\n\t.command('config')\n\t.description('Display current settings')\n\t.action(() => {\n\t\tconst config = loadConfig();\n\t\tconsole.log(chalk.white.bold('\\n PicLet Configuration'));\n\t\tconsole.log(chalk.gray(` ${getConfigPath()}\\n`));\n\t\tconsole.log(JSON.stringify(config, null, 2));\n\t\tconsole.log();\n\t});\n\nconfigCmd\n\t.command('reset')\n\t.description('Restore defaults')\n\t.action(() => {\n\t\tresetConfig();\n\t\tconsole.log(chalk.green('Configuration reset to defaults.'));\n\t});\n\n// Parse and run\nprogram.parseAsync(process.argv).catch((error) => {\n\tconsole.error(chalk.red(`Error: ${error.message}`));\n\tprocess.exit(1);\n});\n","import figlet from 'figlet';\nimport gradient from 'gradient-string';\n\nconst GRADIENT_COLORS = ['#22c55e', '#84cc16', '#eab308', '#fcd34d'];\n\n/**\n * Render the PicLet ASCII art logo with gradient colors\n */\nfunction renderLogo(): string {\n\tconst ascii = figlet.textSync('PicLet', {\n\t\tfont: 'Slant',\n\t\thorizontalLayout: 'default',\n\t});\n\treturn gradient(GRADIENT_COLORS)(ascii);\n}\n\n/**\n * Display the PicLet banner with gradient colors\n */\nexport function showBanner(\n\tsubtitle = 'Image manipulation utility toolkit with Windows shell integration',\n): void {\n\ttry {\n\t\tconsole.log(`\\n${renderLogo()}`);\n\t\tif (subtitle) {\n\t\t\tconst subtleGradient = gradient(['#a8a8a8', '#d4d4d4']);\n\t\t\tconsole.log(subtleGradient(` ${subtitle}\\n`));\n\t\t}\n\t} catch {\n\t\t// Fallback if rendering fails\n\t\tconsole.log('\\n\\x1b[1mPicLet\\x1b[0m');\n\t\tif (subtitle) {\n\t\t\tconsole.log(`\\x1b[2m ${subtitle}\\x1b[0m\\n`);\n\t\t}\n\t}\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\n\n/** PicLet configuration */\nexport interface PicLetConfig {\n\tremoveBg: {\n\t\tfuzz: number;\n\t\ttrim: boolean;\n\t\tpreserveInner: boolean;\n\t\tmakeSquare: boolean;\n\t};\n\trescale: {\n\t\tdefaultScale: number;\n\t\tmakeSquare: boolean;\n\t};\n\ticonpack: {\n\t\tplatforms: ('web' | 'android' | 'ios')[];\n\t};\n}\n\n/** Default configuration */\nexport const DEFAULT_CONFIG: PicLetConfig = {\n\tremoveBg: {\n\t\tfuzz: 10,\n\t\ttrim: true,\n\t\tpreserveInner: false,\n\t\tmakeSquare: false,\n\t},\n\trescale: {\n\t\tdefaultScale: 50,\n\t\tmakeSquare: false,\n\t},\n\ticonpack: {\n\t\tplatforms: ['web', 'android', 'ios'],\n\t},\n};\n\n/** Get config directory path */\nfunction getConfigDir(): string {\n\treturn join(homedir(), '.config', 'piclet');\n}\n\n/** Get config file path */\nexport function getConfigPath(): string {\n\treturn join(getConfigDir(), 'config.json');\n}\n\n/** Load configuration from file */\nexport function loadConfig(): PicLetConfig {\n\tconst configPath = getConfigPath();\n\n\tif (!existsSync(configPath)) {\n\t\treturn { ...DEFAULT_CONFIG };\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(configPath, 'utf-8');\n\t\tconst loaded = JSON.parse(content) as Partial<PicLetConfig>;\n\t\treturn {\n\t\t\tremoveBg: { ...DEFAULT_CONFIG.removeBg, ...loaded.removeBg },\n\t\t\trescale: { ...DEFAULT_CONFIG.rescale, ...loaded.rescale },\n\t\t\ticonpack: { ...DEFAULT_CONFIG.iconpack, ...loaded.iconpack },\n\t\t};\n\t} catch {\n\t\treturn { ...DEFAULT_CONFIG };\n\t}\n}\n\n/** Save configuration to file */\nexport function saveConfig(config: PicLetConfig): void {\n\tconst configPath = getConfigPath();\n\tconst configDir = dirname(configPath);\n\n\tif (!existsSync(configDir)) {\n\t\tmkdirSync(configDir, { recursive: true });\n\t}\n\n\twriteFileSync(configPath, JSON.stringify(config, null, 2));\n}\n\n/** Reset configuration to defaults */\nexport function resetConfig(): void {\n\tconst configPath = getConfigPath();\n\tconst configDir = dirname(configPath);\n\n\tif (!existsSync(configDir)) {\n\t\tmkdirSync(configDir, { recursive: true });\n\t}\n\n\twriteFileSync(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2));\n}\n","import { basename, dirname, extname, resolve } from 'node:path';\n\n/**\n * Convert Windows path to WSL path\n * C:\\Users\\... → /mnt/c/Users/...\n */\nexport function windowsToWsl(winPath: string): string {\n\t// Already a WSL path\n\tif (winPath.startsWith('/mnt/')) {\n\t\treturn winPath;\n\t}\n\n\t// Windows path pattern: C:\\... or C:/...\n\tconst match = winPath.match(/^([A-Za-z]):[/\\\\](.*)$/);\n\tif (match) {\n\t\tconst drive = match[1].toLowerCase();\n\t\tconst rest = match[2].replace(/\\\\/g, '/');\n\t\treturn `/mnt/${drive}/${rest}`;\n\t}\n\n\treturn winPath;\n}\n\n/**\n * Convert WSL path to Windows path\n * /mnt/c/Users/... → C:\\Users\\...\n */\nexport function wslToWindows(wslPath: string): string {\n\tconst match = wslPath.match(/^\\/mnt\\/([a-z])\\/(.*)$/i);\n\tif (match) {\n\t\tconst drive = match[1].toUpperCase();\n\t\tconst rest = match[2].replace(/\\//g, '\\\\');\n\t\treturn `${drive}:\\\\${rest}`;\n\t}\n\treturn wslPath;\n}\n\n/**\n * Normalize a path - convert Windows paths if needed, resolve relative paths\n */\nexport function normalizePath(inputPath: string): string {\n\tif (/^[A-Za-z]:[/\\\\]/.test(inputPath)) {\n\t\treturn windowsToWsl(inputPath);\n\t}\n\treturn resolve(inputPath);\n}\n\n/**\n * Get file info from a path\n */\nexport interface FileInfo {\n\tdirname: string;\n\tbasename: string;\n\tfilename: string;\n\textension: string;\n}\n\nexport function getFileInfo(filePath: string): FileInfo {\n\tconst dir = dirname(filePath);\n\tconst base = basename(filePath);\n\tconst ext = extname(filePath);\n\tconst name = base.slice(0, -ext.length);\n\n\treturn {\n\t\tdirname: dir,\n\t\tbasename: base,\n\t\tfilename: name,\n\t\textension: ext,\n\t};\n}\n\n/**\n * Generate output path with suffix\n */\nexport function getOutputPath(\n\tinputPath: string,\n\tsuffix: string,\n\tnewExtension?: string,\n): string {\n\tconst info = getFileInfo(inputPath);\n\tconst ext = newExtension ?? info.extension;\n\treturn `${info.dirname}/${info.filename}${suffix}${ext}`;\n}\n","import prompts from 'prompts';\n\n/** When true, all prompts return their default values without user interaction */\nlet useDefaults = false;\n\n/** Override values from CLI arguments - keyed by prompt message substring */\nconst overrides: Record<string, string | number | boolean | string[]> = {};\n\n/**\n * Enable or disable default mode (for --yes flag)\n */\nexport function setUseDefaults(value: boolean): void {\n\tuseDefaults = value;\n}\n\n/**\n * Check if defaults mode is enabled\n */\nexport function isUsingDefaults(): boolean {\n\treturn useDefaults;\n}\n\n/**\n * Set override values from CLI arguments\n */\nexport function setOverrides(values: Record<string, string | number | boolean | string[]>): void {\n\tObject.assign(overrides, values);\n}\n\n/**\n * Clear all overrides\n */\nexport function clearOverrides(): void {\n\tfor (const key of Object.keys(overrides)) {\n\t\tdelete overrides[key];\n\t}\n}\n\n/**\n * Get override value for a prompt message (matches substring)\n */\nfunction getOverride(message: string): string | number | boolean | string[] | undefined {\n\tconst msgLower = message.toLowerCase();\n\tfor (const [key, value] of Object.entries(overrides)) {\n\t\tif (msgLower.includes(key.toLowerCase())) {\n\t\t\treturn value;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Prompt for text input with optional default\n */\nexport async function text(\n\tmessage: string,\n\tdefaultValue?: string,\n): Promise<string> {\n\tif (useDefaults) return defaultValue ?? '';\n\n\tconst response = await prompts({\n\t\ttype: 'text',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t});\n\treturn response.value ?? defaultValue ?? '';\n}\n\n/**\n * Prompt for number input with optional default\n */\nexport async function number(\n\tmessage: string,\n\tdefaultValue?: number,\n\tmin?: number,\n\tmax?: number,\n): Promise<number> {\n\tconst override = getOverride(message);\n\tif (override !== undefined) return Number(override);\n\tif (useDefaults) return defaultValue ?? 0;\n\n\tconst response = await prompts({\n\t\ttype: 'number',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t\tmin,\n\t\tmax,\n\t});\n\treturn response.value ?? defaultValue ?? 0;\n}\n\n/**\n * Prompt for yes/no confirmation\n */\nexport async function confirm(\n\tmessage: string,\n\tdefaultValue = true,\n): Promise<boolean> {\n\tconst override = getOverride(message);\n\tif (override !== undefined) return Boolean(override);\n\tif (useDefaults) return defaultValue;\n\n\tconst response = await prompts({\n\t\ttype: 'confirm',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t});\n\treturn response.value ?? defaultValue;\n}\n\n/**\n * Single-select from options\n */\nexport interface SelectOption {\n\ttitle: string;\n\tvalue: string | number;\n\tdescription?: string;\n}\n\nexport async function select<T extends string | number>(\n\tmessage: string,\n\toptions: SelectOption[],\n\tdefaultValue?: T,\n): Promise<T | null> {\n\tif (useDefaults) return defaultValue ?? (options[0]?.value as T) ?? null;\n\n\tconst response = await prompts({\n\t\ttype: 'select',\n\t\tname: 'value',\n\t\tmessage,\n\t\tchoices: options.map((opt) => ({\n\t\t\ttitle: opt.title,\n\t\t\tvalue: opt.value,\n\t\t\tdescription: opt.description,\n\t\t})),\n\t});\n\treturn (response.value as T) ?? null;\n}\n\n/**\n * Multi-select from options\n */\nexport async function multiSelect<T extends string | number>(\n\tmessage: string,\n\toptions: SelectOption[],\n\tdefaultValues?: T[],\n): Promise<T[]> {\n\tif (useDefaults) return defaultValues ?? [];\n\n\tconst response = await prompts({\n\t\ttype: 'multiselect',\n\t\tname: 'value',\n\t\tmessage,\n\t\tchoices: options.map((opt) => ({\n\t\t\ttitle: opt.title,\n\t\t\tvalue: opt.value,\n\t\t\tdescription: opt.description,\n\t\t})),\n\t\tinstructions: false,\n\t\thint: '- Space to select, Enter to confirm',\n\t});\n\treturn (response.value as T[]) ?? [];\n}\n\n/**\n * Handle Ctrl+C gracefully\n */\nexport function onCancel(): void {\n\tprompts.override({ value: undefined });\n}\n\n// Set up cancel handler\nprompts.override({});\n\n/**\n * Pause and wait for user to press Enter (useful for errors in batch mode)\n * Only pauses when running with -y flag so user can see error messages\n */\nexport async function pauseOnError(message = 'Press Enter to close...'): Promise<void> {\n\tif (!useDefaults) return; // Interactive mode - no need to pause\n\n\tconsole.log();\n\tawait prompts({\n\t\ttype: 'text',\n\t\tname: 'value',\n\t\tmessage,\n\t});\n}\n","import { exec } from 'node:child_process';\nimport { dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\n/**\n * Check if running inside WSL\n */\nexport function isWSL(): boolean {\n\treturn (\n\t\tprocess.platform === 'linux' &&\n\t\t(process.env.WSL_DISTRO_NAME !== undefined ||\n\t\t\tprocess.env.WSLENV !== undefined)\n\t);\n}\n\n/**\n * Convert WSL path to Windows path\n */\nexport function wslToWindows(wslPath: string): string {\n\tconst match = wslPath.match(/^\\/mnt\\/([a-z])\\/(.*)$/i);\n\tif (match) {\n\t\tconst drive = match[1].toUpperCase();\n\t\tconst rest = match[2].replace(/\\//g, '\\\\');\n\t\treturn `${drive}:\\\\${rest}`;\n\t}\n\treturn wslPath;\n}\n\n/**\n * Convert Windows path to WSL path\n */\nexport function windowsToWsl(winPath: string): string {\n\tconst match = winPath.match(/^([A-Za-z]):\\\\(.*)$/);\n\tif (match) {\n\t\tconst drive = match[1].toLowerCase();\n\t\tconst rest = match[2].replace(/\\\\/g, '/');\n\t\treturn `/mnt/${drive}/${rest}`;\n\t}\n\treturn winPath;\n}\n\n/**\n * Get the directory where this module is located\n */\nexport function getModuleDir(): string {\n\tconst currentFile = fileURLToPath(import.meta.url);\n\treturn dirname(currentFile);\n}\n\n/**\n * Add a registry key with value\n */\nexport async function addRegistryKey(\n\tkeyPath: string,\n\tvalueName: string,\n\tvalue: string,\n\ttype = 'REG_SZ',\n): Promise<boolean> {\n\tconst valueArg = valueName ? `/v \"${valueName}\"` : '/ve';\n\t// Escape inner quotes for Windows command line\n\tconst escapedValue = value.replace(/\"/g, '\\\\\"');\n\tconst cmd = `reg.exe add \"${keyPath}\" ${valueArg} /t ${type} /d \"${escapedValue}\" /f`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch (error) {\n\t\tconst message = (error as Error).message;\n\t\t// Silently ignore WSL interop errors (can't run reg.exe)\n\t\tconst ignoredErrors = ['Exec format error', 'not found'];\n\t\tconst shouldIgnore = ignoredErrors.some((e) =>\n\t\t\tmessage.toLowerCase().includes(e.toLowerCase()),\n\t\t);\n\t\tif (!shouldIgnore) {\n\t\t\tconsole.error(`Failed to add registry key: ${keyPath}`);\n\t\t\tconsole.error(message);\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Delete a registry key\n */\nexport async function deleteRegistryKey(keyPath: string): Promise<boolean> {\n\tconst cmd = `reg.exe delete \"${keyPath}\" /f`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch (error) {\n\t\tconst message = (error as Error).message;\n\t\t// Silently ignore expected errors:\n\t\t// - \"unable to find\" = key doesn't exist\n\t\t// - \"Exec format error\" = WSL can't run reg.exe (interop disabled)\n\t\t// - \"not found\" = reg.exe not in PATH\n\t\tconst ignoredErrors = ['unable to find', 'Exec format error', 'not found'];\n\t\tconst shouldIgnore = ignoredErrors.some((e) =>\n\t\t\tmessage.toLowerCase().includes(e.toLowerCase()),\n\t\t);\n\t\tif (!shouldIgnore) {\n\t\t\tconsole.error(`Failed to delete registry key: ${keyPath}`);\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if a registry key exists\n */\nexport async function registryKeyExists(keyPath: string): Promise<boolean> {\n\tconst cmd = `reg.exe query \"${keyPath}\" 2>/dev/null`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { basename, dirname } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tDIM,\n\tRESET,\n\tclearLine,\n\terror,\n\theader,\n\tinfo,\n\tseparator,\n\tstep,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tcreateIcoFromMultiple,\n\tgetDimensions,\n\tscaleToSize,\n\tsquarify,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { multiSelect as promptMultiSelect, pauseOnError } from '../lib/prompts.js';\n\n// Icon definitions for each platform\ninterface IconDef {\n\tfilename: string;\n\tsize: number;\n}\n\nconst WEB_ICONS: IconDef[] = [\n\t{ filename: 'favicon-16x16.png', size: 16 },\n\t{ filename: 'favicon-32x32.png', size: 32 },\n\t{ filename: 'favicon-48x48.png', size: 48 },\n\t{ filename: 'apple-touch-icon.png', size: 180 },\n\t{ filename: 'android-chrome-192x192.png', size: 192 },\n\t{ filename: 'android-chrome-512x512.png', size: 512 },\n\t{ filename: 'mstile-150x150.png', size: 150 },\n];\n\nconst ANDROID_ICONS: IconDef[] = [\n\t{ filename: 'mipmap-mdpi/ic_launcher.png', size: 48 },\n\t{ filename: 'mipmap-hdpi/ic_launcher.png', size: 72 },\n\t{ filename: 'mipmap-xhdpi/ic_launcher.png', size: 96 },\n\t{ filename: 'mipmap-xxhdpi/ic_launcher.png', size: 144 },\n\t{ filename: 'mipmap-xxxhdpi/ic_launcher.png', size: 192 },\n\t{ filename: 'playstore-icon.png', size: 512 },\n];\n\nconst IOS_ICONS: IconDef[] = [\n\t// 20pt - Notifications\n\t{ filename: 'AppIcon-20.png', size: 20 },\n\t{ filename: 'AppIcon-20@2x.png', size: 40 },\n\t{ filename: 'AppIcon-20@3x.png', size: 60 },\n\t// 29pt - Settings\n\t{ filename: 'AppIcon-29.png', size: 29 },\n\t{ filename: 'AppIcon-29@2x.png', size: 58 },\n\t{ filename: 'AppIcon-29@3x.png', size: 87 },\n\t// 40pt - Spotlight\n\t{ filename: 'AppIcon-40.png', size: 40 },\n\t{ filename: 'AppIcon-40@2x.png', size: 80 },\n\t{ filename: 'AppIcon-40@3x.png', size: 120 },\n\t// 60pt - iPhone App\n\t{ filename: 'AppIcon-60@2x.png', size: 120 },\n\t{ filename: 'AppIcon-60@3x.png', size: 180 },\n\t// 76pt - iPad App\n\t{ filename: 'AppIcon-76.png', size: 76 },\n\t{ filename: 'AppIcon-76@2x.png', size: 152 },\n\t// 83.5pt - iPad Pro\n\t{ filename: 'AppIcon-83.5@2x.png', size: 167 },\n\t// App Store\n\t{ filename: 'AppIcon-1024.png', size: 1024 },\n];\n\n/**\n * Generate icons for a platform\n */\nasync function generateIcons(\n\toutputDir: string,\n\tsourceImg: string,\n\ticons: IconDef[],\n): Promise<number> {\n\tconst total = icons.length;\n\tlet current = 0;\n\tlet failed = 0;\n\n\tfor (const icon of icons) {\n\t\tcurrent++;\n\t\tconst outputPath = `${outputDir}/${icon.filename}`;\n\n\t\t// Create subdirectory if needed\n\t\tconst subdir = dirname(outputPath);\n\t\tif (!existsSync(subdir)) {\n\t\t\tmkdirSync(subdir, { recursive: true });\n\t\t}\n\n\t\tclearLine();\n\t\twip(`[${current}/${total}] Generating ${icon.filename}...`);\n\n\t\tif (await scaleToSize(sourceImg, outputPath, icon.size)) {\n\t\t\tclearLine();\n\t\t\tsuccess(\n\t\t\t\t`[${current}/${total}] ${icon.filename} (${icon.size}x${icon.size})`,\n\t\t\t);\n\t\t} else {\n\t\t\tclearLine();\n\t\t\terror(`[${current}/${total}] Failed: ${icon.filename}`);\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Generate favicon.ico from multiple sizes\n */\nasync function generateFavicon(\n\toutputDir: string,\n\tsourceImg: string,\n): Promise<boolean> {\n\twip('Generating favicon.ico...');\n\n\tconst temp16 = `${outputDir}/.temp_16.png`;\n\tconst temp32 = `${outputDir}/.temp_32.png`;\n\tconst temp48 = `${outputDir}/.temp_48.png`;\n\n\tawait scaleToSize(sourceImg, temp16, 16);\n\tawait scaleToSize(sourceImg, temp32, 32);\n\tawait scaleToSize(sourceImg, temp48, 48);\n\n\tconst result = await createIcoFromMultiple(\n\t\t[temp16, temp32, temp48],\n\t\t`${outputDir}/favicon.ico`,\n\t);\n\n\tcleanup(temp16, temp32, temp48);\n\n\tif (result) {\n\t\twipDone(true, 'favicon.ico (16, 32, 48)');\n\t\treturn true;\n\t}\n\twipDone(false, 'favicon.ico failed');\n\treturn false;\n}\n\n/**\n * Generate icon sets for Web, Android, iOS platforms\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Get file info\n\tconst fileInfo = getFileInfo(input);\n\n\theader('PicLet Icon Pack Generator');\n\n\t// Analyze source image\n\twip('Analyzing source image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\tconst [origW, origH] = dims;\n\twipDone(true, `Source: ${origW}x${origH}`);\n\n\t// Warn if small source\n\tif (origW < 1024 || origH < 1024) {\n\t\twarn(\n\t\t\t'Source image is smaller than 1024px. Larger images produce better quality.',\n\t\t);\n\t}\n\n\t// Check if square\n\tif (origW !== origH) {\n\t\twarn('Image is not square. Will add transparent padding.');\n\t}\n\n\t// Select platforms\n\tconsole.log('');\n\tconst platforms = await promptMultiSelect<string>(\n\t\t'Select target platforms:',\n\t\t[\n\t\t\t{ title: 'Web (PWA, favicon, apple-touch-icon)', value: 'web' },\n\t\t\t{ title: 'Android (mipmap icons, Play Store)', value: 'android' },\n\t\t\t{ title: 'iOS (App icons, App Store)', value: 'ios' },\n\t\t],\n\t\t['web', 'android', 'ios'], // Default: all platforms\n\t);\n\n\tif (platforms.length === 0) {\n\t\terror('No platforms selected');\n\t\treturn false;\n\t}\n\n\tconst doWeb = platforms.includes('web');\n\tconst doAndroid = platforms.includes('android');\n\tconst doIos = platforms.includes('ios');\n\n\t// Create output directory\n\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\tmkdirSync(outputDir, { recursive: true });\n\tinfo(`Output directory: ${outputDir}`);\n\n\t// Prepare source: make square and scale to 1024px for best quality\n\tconsole.log('');\n\twip('Preparing source image...');\n\tconst tempSource = `${outputDir}/.source_1024.png`;\n\tconst tempSquare = `${outputDir}/.temp_square.png`;\n\n\t// First squarify\n\tif (!(await squarify(input, tempSquare))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\treturn false;\n\t}\n\n\t// Then scale to 1024 for high quality source\n\tif (!(await scaleToSize(tempSquare, tempSource, 1024))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\tcleanup(tempSquare);\n\t\treturn false;\n\t}\n\tcleanup(tempSquare);\n\twipDone(true, 'Prepared 1024x1024 source');\n\n\tlet totalFailed = 0;\n\n\t// Generate Web icons\n\tif (doWeb) {\n\t\tconsole.log('');\n\t\theader('Web Icons');\n\t\tconst webDir = `${outputDir}/web`;\n\t\tmkdirSync(webDir, { recursive: true });\n\n\t\tif (!(await generateFavicon(webDir, tempSource))) {\n\t\t\ttotalFailed++;\n\t\t}\n\n\t\ttotalFailed += await generateIcons(webDir, tempSource, WEB_ICONS);\n\t}\n\n\t// Generate Android icons\n\tif (doAndroid) {\n\t\tconsole.log('');\n\t\theader('Android Icons');\n\t\tconst androidDir = `${outputDir}/android`;\n\t\tmkdirSync(androidDir, { recursive: true });\n\n\t\ttotalFailed += await generateIcons(androidDir, tempSource, ANDROID_ICONS);\n\t}\n\n\t// Generate iOS icons\n\tif (doIos) {\n\t\tconsole.log('');\n\t\theader('iOS Icons');\n\t\tconst iosDir = `${outputDir}/ios`;\n\t\tmkdirSync(iosDir, { recursive: true });\n\n\t\ttotalFailed += await generateIcons(iosDir, tempSource, IOS_ICONS);\n\t}\n\n\t// Cleanup\n\tcleanup(tempSource);\n\n\t// Summary\n\tconsole.log('');\n\tseparator();\n\n\tif (totalFailed === 0) {\n\t\tsuccess('All icons generated successfully!');\n\t} else {\n\t\twarn(`${totalFailed} icon(s) failed to generate`);\n\t}\n\n\tconsole.log('');\n\tinfo(`Icons saved to: ${outputDir}`);\n\n\tif (doWeb) {\n\t\tstep('web/ - Favicon, PWA icons, Apple touch icon');\n\t}\n\tif (doAndroid) {\n\t\tstep('android/ - mipmap folders, Play Store icon');\n\t}\n\tif (doIos) {\n\t\tstep('ios/ - All iOS app icon sizes');\n\t}\n\n\treturn totalFailed === 0;\n}\n\n/**\n * Generate icon pack (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'iconpack.html',\n\t\ttitle: 'PicLet - Icon Pack',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tweb: true,\n\t\t\tandroid: true,\n\t\t\tios: true,\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst doWeb = (opts.web as boolean) ?? true;\n\t\t\tconst doAndroid = (opts.android as boolean) ?? true;\n\t\t\tconst doIos = (opts.ios as boolean) ?? true;\n\n\t\t\tif (!doWeb && !doAndroid && !doIos) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'No platforms selected',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'No platforms selected' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Create output directory\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\t\t\tlogs.push({ type: 'info', message: `Output: ${outputDir}` });\n\n\t\t\t// Prepare source: make square and scale to 1024px\n\t\t\tlogs.push({ type: 'info', message: 'Preparing source image...' });\n\t\t\tconst tempSource = `${outputDir}/.source_1024.png`;\n\t\t\tconst tempSquare = `${outputDir}/.temp_square.png`;\n\n\t\t\tif (!(await squarify(input, tempSquare))) {\n\t\t\t\treturn { success: false, error: 'Failed to prepare source', logs };\n\t\t\t}\n\n\t\t\tif (!(await scaleToSize(tempSquare, tempSource, 1024))) {\n\t\t\t\tcleanup(tempSquare);\n\t\t\t\treturn { success: false, error: 'Failed to prepare source', logs };\n\t\t\t}\n\t\t\tcleanup(tempSquare);\n\t\t\tlogs.push({ type: 'success', message: 'Prepared 1024x1024 source' });\n\n\t\t\tlet totalFailed = 0;\n\n\t\t\t// Generate Web icons\n\t\t\tif (doWeb) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating Web icons...' });\n\t\t\t\tconst webDir = `${outputDir}/web`;\n\t\t\t\tmkdirSync(webDir, { recursive: true });\n\n\t\t\t\tif (!(await generateFaviconSilent(webDir, tempSource))) {\n\t\t\t\t\ttotalFailed++;\n\t\t\t\t}\n\t\t\t\ttotalFailed += await generateIconsSilent(webDir, tempSource, WEB_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `Web: ${WEB_ICONS.length + 1} icons` });\n\t\t\t}\n\n\t\t\t// Generate Android icons\n\t\t\tif (doAndroid) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating Android icons...' });\n\t\t\t\tconst androidDir = `${outputDir}/android`;\n\t\t\t\tmkdirSync(androidDir, { recursive: true });\n\t\t\t\ttotalFailed += await generateIconsSilent(androidDir, tempSource, ANDROID_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `Android: ${ANDROID_ICONS.length} icons` });\n\t\t\t}\n\n\t\t\t// Generate iOS icons\n\t\t\tif (doIos) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating iOS icons...' });\n\t\t\t\tconst iosDir = `${outputDir}/ios`;\n\t\t\t\tmkdirSync(iosDir, { recursive: true });\n\t\t\t\ttotalFailed += await generateIconsSilent(iosDir, tempSource, IOS_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `iOS: ${IOS_ICONS.length} icons` });\n\t\t\t}\n\n\t\t\tcleanup(tempSource);\n\n\t\t\tif (totalFailed === 0) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `Icons saved to ${fileInfo.filename}_icons/`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `${totalFailed} icon(s) failed`,\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Silent version of generateIcons for GUI mode\n */\nasync function generateIconsSilent(\n\toutputDir: string,\n\tsourceImg: string,\n\ticons: IconDef[],\n\t_logs: Array<{ type: string; message: string }>,\n): Promise<number> {\n\tlet failed = 0;\n\n\tfor (const icon of icons) {\n\t\tconst outputPath = `${outputDir}/${icon.filename}`;\n\t\tconst subdir = dirname(outputPath);\n\t\tif (!existsSync(subdir)) {\n\t\t\tmkdirSync(subdir, { recursive: true });\n\t\t}\n\n\t\tif (!(await scaleToSize(sourceImg, outputPath, icon.size))) {\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Silent version of generateFavicon for GUI mode\n */\nasync function generateFaviconSilent(\n\toutputDir: string,\n\tsourceImg: string,\n): Promise<boolean> {\n\tconst temp16 = `${outputDir}/.temp_16.png`;\n\tconst temp32 = `${outputDir}/.temp_32.png`;\n\tconst temp48 = `${outputDir}/.temp_48.png`;\n\n\tawait scaleToSize(sourceImg, temp16, 16);\n\tawait scaleToSize(sourceImg, temp32, 32);\n\tawait scaleToSize(sourceImg, temp48, 48);\n\n\tconst result = await createIcoFromMultiple(\n\t\t[temp16, temp32, temp48],\n\t\t`${outputDir}/favicon.ico`,\n\t);\n\n\tcleanup(temp16, temp32, temp48);\n\treturn result;\n}\n\nexport const config = {\n\tid: 'iconpack',\n\tname: 'Icon Pack',\n\ticon: 'iconpack.ico',\n\textensions: ['.png', '.jpg', '.jpeg'],\n};\n","/**\n * GUI Server - Serves HTML interface and handles API calls\n */\nimport { spawn } from 'node:child_process';\nimport { createServer } from 'node:http';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport express from 'express';\nimport { deletePreset, savePreset, type Preset } from './presets.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Signal the loading HTA to close by creating a temp file\n */\nfunction signalReady(): void {\n\t// Write ready signal to Windows temp directory\n\tspawn('cmd.exe', ['/c', 'echo.>', '%TEMP%\\\\piclet-ready.tmp'], {\n\t\tstdio: 'ignore',\n\t\twindowsHide: true,\n\t});\n}\n\n/**\n * Open URL in Edge app mode (standalone window without browser UI)\n */\nfunction openAppWindow(url: string): void {\n\t// Use cmd.exe with start command - windowsHide hides the cmd window\n\t// The start command launches Edge which creates its own visible window\n\tspawn('cmd.exe', ['/c', 'start', '\"\"', 'msedge', `--app=${url}`], {\n\t\tdetached: true,\n\t\tstdio: 'ignore',\n\t\twindowsHide: true,\n\t}).unref();\n\n\t// Signal loading window to close after a brief delay for Edge to appear\n\tsetTimeout(signalReady, 500);\n}\n\nexport interface GuiServerOptions {\n\thtmlFile: string;\n\ttitle: string;\n\timageInfo: {\n\t\tfilePath: string;\n\t\tfileName: string;\n\t\twidth: number;\n\t\theight: number;\n\t\tborderColor: string | null;\n\t};\n\tdefaults: Record<string, unknown>;\n\tonPreview?: (options: Record<string, unknown>) => Promise<{\n\t\tsuccess: boolean;\n\t\timageData?: string; // Base64 data URL\n\t\twidth?: number;\n\t\theight?: number;\n\t\terror?: string;\n\t}>;\n\tonProcess: (options: Record<string, unknown>) => Promise<{\n\t\tsuccess: boolean;\n\t\toutput?: string;\n\t\terror?: string;\n\t\tlogs: Array<{ type: string; message: string }>;\n\t}>;\n\tonLoadImage?: (data: { fileName: string; data: string; mimeType: string }) => Promise<{\n\t\tsuccess: boolean;\n\t\tfilePath?: string;\n\t\tfileName?: string;\n\t\twidth?: number;\n\t\theight?: number;\n\t\tborderColor?: string | null;\n\t\terror?: string;\n\t}>;\n}\n\n/**\n * Start GUI server and open Edge app window\n * Returns a promise that resolves when the window is closed\n */\nexport function startGuiServer(options: GuiServerOptions): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst app = express();\n\t\tapp.use(express.json({ limit: '50mb' })); // Allow large base64 images\n\n\t\t// Handle JSON parse errors\n\t\tapp.use((err: Error, _req: express.Request, res: express.Response, next: express.NextFunction) => {\n\t\t\tif (err instanceof SyntaxError && 'body' in err) {\n\t\t\t\tres.status(400).json({ success: false, error: 'Invalid JSON: ' + err.message });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnext(err);\n\t\t});\n\n\t\tlet processResult: boolean | null = null;\n\t\tlet server: ReturnType<typeof createServer> | null = null;\n\n\t\t// Serve static files (CSS, JS, etc.)\n\t\tconst guiDir = join(__dirname, 'gui');\n\t\tconst iconsDir = join(__dirname, 'icons');\n\t\tapp.use(express.static(guiDir));\n\t\tapp.use('/icons', express.static(iconsDir));\n\n\t\t// Serve favicon from icons directory\n\t\tapp.get('/favicon.ico', (_req, res) => {\n\t\t\tres.sendFile(join(iconsDir, 'banana.ico'));\n\t\t});\n\n\t\t// API: Get image info and defaults\n\t\tapp.get('/api/info', (_req, res) => {\n\t\t\tres.json({\n\t\t\t\tfileName: options.imageInfo.fileName,\n\t\t\t\twidth: options.imageInfo.width,\n\t\t\t\theight: options.imageInfo.height,\n\t\t\t\tborderColor: options.imageInfo.borderColor,\n\t\t\t\tdefaults: options.defaults,\n\t\t\t});\n\t\t});\n\n\t\t// API: Preview image (if supported)\n\t\tapp.post('/api/preview', async (req, res) => {\n\t\t\tif (!options.onPreview) {\n\t\t\t\tres.json({ success: false, error: 'Preview not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await options.onPreview(req.body);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (err as Error).message,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// API: Process image\n\t\tapp.post('/api/process', async (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst result = await options.onProcess(req.body);\n\t\t\t\tprocessResult = result.success;\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tprocessResult = false;\n\t\t\t\tres.json({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (err as Error).message,\n\t\t\t\t\tlogs: [{ type: 'error', message: (err as Error).message }],\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// API: Load new image\n\t\tapp.post('/api/load', async (req, res) => {\n\t\t\tif (!options.onLoadImage) {\n\t\t\t\tres.json({ success: false, error: 'Load not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await options.onLoadImage(req.body);\n\t\t\t\tif (result.success) {\n\t\t\t\t\t// Update current image info\n\t\t\t\t\toptions.imageInfo.filePath = result.filePath!;\n\t\t\t\t\toptions.imageInfo.fileName = result.fileName!;\n\t\t\t\t\toptions.imageInfo.width = result.width!;\n\t\t\t\t\toptions.imageInfo.height = result.height!;\n\t\t\t\t\toptions.imageInfo.borderColor = result.borderColor ?? null;\n\t\t\t\t}\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Cancel/close\n\t\tapp.post('/api/cancel', (_req, res) => {\n\t\t\tprocessResult = false;\n\t\t\tres.json({ ok: true });\n\t\t\tshutdown();\n\t\t});\n\n\t\t// API: Close after completion\n\t\tapp.post('/api/close', (_req, res) => {\n\t\t\tres.json({ ok: true });\n\t\t\tshutdown();\n\t\t});\n\n\t\t// API: Save preset\n\t\tapp.post('/api/save-preset', (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst preset = req.body as Preset;\n\t\t\t\tif (!preset.id || !preset.name || !preset.icons?.length) {\n\t\t\t\t\tres.json({ success: false, error: 'Invalid preset data' });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsavePreset(preset);\n\t\t\t\tres.json({ success: true });\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Delete preset\n\t\tapp.post('/api/delete-preset', (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst { id } = req.body;\n\t\t\t\tif (!id) {\n\t\t\t\t\tres.json({ success: false, error: 'Missing preset ID' });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = deletePreset(id);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\tfunction shutdown() {\n\t\t\tsetTimeout(() => {\n\t\t\t\tserver?.close();\n\t\t\t\tresolve(processResult ?? false);\n\t\t\t}, 100);\n\t\t}\n\n\t\t// Find available port and start\n\t\tserver = createServer(app);\n\t\tserver.listen(0, '127.0.0.1', () => {\n\t\t\tconst addr = server!.address();\n\t\t\tif (typeof addr === 'object' && addr) {\n\t\t\t\tconst port = addr.port;\n\t\t\t\tconst url = `http://127.0.0.1:${port}/${options.htmlFile}`;\n\n\t\t\t\topenAppWindow(url);\n\n\t\t\t\t// Auto-close after 5 minutes of inactivity\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (processResult === null) {\n\t\t\t\t\t\tshutdown();\n\t\t\t\t\t}\n\t\t\t\t}, 5 * 60 * 1000);\n\t\t\t}\n\t\t});\n\n\t\tserver.on('error', (err) => {\n\t\t\tconsole.error('GUI server error:', err.message);\n\t\t\tresolve(false);\n\t\t});\n\t});\n}\n","/**\n * Presets configuration for store icon packs\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\n\n/** Single icon definition in a preset */\nexport interface PresetIcon {\n\tfilename: string;\n\twidth: number;\n\theight: number;\n}\n\n/** A complete preset definition */\nexport interface Preset {\n\tid: string;\n\tname: string;\n\tdescription: string;\n\ticons: PresetIcon[];\n}\n\n/** Presets file structure */\nexport interface PresetsConfig {\n\tversion: number;\n\tpresets: Preset[];\n}\n\n/** Built-in presets */\nconst BUILT_IN_PRESETS: Preset[] = [\n\t// ── Game Asset Stores ──\n\t{\n\t\tid: 'unity-asset',\n\t\tname: 'Unity Asset Store',\n\t\tdescription: 'Unity Asset Store package images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-160.png', width: 160, height: 160 },\n\t\t\t{ filename: 'card-420x280.png', width: 420, height: 280 },\n\t\t\t{ filename: 'cover-1200x630.png', width: 1200, height: 630 },\n\t\t\t{ filename: 'screenshot-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'unreal-fab',\n\t\tname: 'Unreal / Fab',\n\t\tdescription: 'Unreal Marketplace & Fab assets',\n\t\ticons: [\n\t\t\t{ filename: 'icon-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'thumbnail-284.png', width: 284, height: 284 },\n\t\t\t{ filename: 'featured-894x488.png', width: 894, height: 488 },\n\t\t\t{ filename: 'gallery-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'godot-asset',\n\t\tname: 'Godot Asset Library',\n\t\tdescription: 'Godot Asset Library images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-64.png', width: 64, height: 64 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'screenshot-1280x720.png', width: 1280, height: 720 },\n\t\t\t{ filename: 'screenshot-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'blender-market',\n\t\tname: 'Blender Market',\n\t\tdescription: 'Blender Market product images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'thumbnail-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'preview-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'steam',\n\t\tname: 'Steam',\n\t\tdescription: 'Steam store assets',\n\t\ticons: [\n\t\t\t{ filename: 'capsule-small-231x87.png', width: 231, height: 87 },\n\t\t\t{ filename: 'capsule-main-616x353.png', width: 616, height: 353 },\n\t\t\t{ filename: 'header-460x215.png', width: 460, height: 215 },\n\t\t\t{ filename: 'hero-1920x620.png', width: 1920, height: 620 },\n\t\t\t{ filename: 'library-capsule-600x900.png', width: 600, height: 900 },\n\t\t\t{ filename: 'library-hero-3840x1240.png', width: 3840, height: 1240 },\n\t\t],\n\t},\n\t{\n\t\tid: 'itch-io',\n\t\tname: 'itch.io',\n\t\tdescription: 'itch.io game page assets',\n\t\ticons: [\n\t\t\t{ filename: 'cover-630x500.png', width: 630, height: 500 },\n\t\t\t{ filename: 'thumbnail-315x250.png', width: 315, height: 250 },\n\t\t\t{ filename: 'banner-960x540.png', width: 960, height: 540 },\n\t\t],\n\t},\n\t// ── Extensions & Packages ──\n\t{\n\t\tid: 'chrome-extension',\n\t\tname: 'Chrome Extension',\n\t\tdescription: 'Chrome Web Store extension icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-16.png', width: 16, height: 16 },\n\t\t\t{ filename: 'icon-32.png', width: 32, height: 32 },\n\t\t\t{ filename: 'icon-48.png', width: 48, height: 48 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'promo-440x280.png', width: 440, height: 280 },\n\t\t\t{ filename: 'promo-1400x560.png', width: 1400, height: 560 },\n\t\t],\n\t},\n\t{\n\t\tid: 'firefox-addon',\n\t\tname: 'Firefox Add-on',\n\t\tdescription: 'Firefox Add-ons icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-48.png', width: 48, height: 48 },\n\t\t\t{ filename: 'icon-96.png', width: 96, height: 96 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t],\n\t},\n\t{\n\t\tid: 'vscode-extension',\n\t\tname: 'VS Code Extension',\n\t\tdescription: 'VS Code Marketplace icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'icon-256.png', width: 256, height: 256 },\n\t\t],\n\t},\n\t{\n\t\tid: 'npm-package',\n\t\tname: 'npm Package',\n\t\tdescription: 'npm package icons',\n\t\ticons: [\n\t\t\t{ filename: 'logo-64.png', width: 64, height: 64 },\n\t\t\t{ filename: 'logo-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'logo-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'banner-1200x600.png', width: 1200, height: 600 },\n\t\t],\n\t},\n\t{\n\t\tid: 'windows-store',\n\t\tname: 'Windows Store',\n\t\tdescription: 'Microsoft Store app icons',\n\t\ticons: [\n\t\t\t{ filename: 'Square44x44Logo.png', width: 44, height: 44 },\n\t\t\t{ filename: 'Square150x150Logo.png', width: 150, height: 150 },\n\t\t\t{ filename: 'Square310x310Logo.png', width: 310, height: 310 },\n\t\t\t{ filename: 'Wide310x150Logo.png', width: 310, height: 150 },\n\t\t\t{ filename: 'StoreLogo-50.png', width: 50, height: 50 },\n\t\t\t{ filename: 'SplashScreen-620x300.png', width: 620, height: 300 },\n\t\t],\n\t},\n];\n\n/** Get presets file path */\nexport function getPresetsPath(): string {\n\tconst picletDir = join(homedir(), '.piclet');\n\treturn join(picletDir, 'presets.json');\n}\n\n/** Ensure presets directory exists */\nfunction ensurePresetsDir(): void {\n\tconst presetsPath = getPresetsPath();\n\tconst dir = dirname(presetsPath);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n}\n\n/** Load presets (built-in + user-defined) */\nexport function loadPresets(): Preset[] {\n\tconst presetsPath = getPresetsPath();\n\tlet userPresets: Preset[] = [];\n\n\tif (existsSync(presetsPath)) {\n\t\ttry {\n\t\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\t\tuserPresets = config.presets || [];\n\t\t} catch {\n\t\t\t// Ignore parse errors, use built-in only\n\t\t}\n\t}\n\n\t// Merge: built-in first, then user presets (user can override built-in by ID)\n\tconst presetMap = new Map<string, Preset>();\n\tfor (const preset of BUILT_IN_PRESETS) {\n\t\tpresetMap.set(preset.id, preset);\n\t}\n\tfor (const preset of userPresets) {\n\t\tpresetMap.set(preset.id, preset);\n\t}\n\n\treturn Array.from(presetMap.values());\n}\n\n/** Get a single preset by ID */\nexport function getPreset(id: string): Preset | undefined {\n\tconst presets = loadPresets();\n\treturn presets.find((p) => p.id === id);\n}\n\n/** Save user presets */\nexport function savePresets(presets: Preset[]): void {\n\tensurePresetsDir();\n\tconst config: PresetsConfig = {\n\t\tversion: 1,\n\t\tpresets,\n\t};\n\twriteFileSync(getPresetsPath(), JSON.stringify(config, null, 2));\n}\n\n/** Add or update a preset */\nexport function savePreset(preset: Preset): void {\n\tconst presetsPath = getPresetsPath();\n\tlet userPresets: Preset[] = [];\n\n\tif (existsSync(presetsPath)) {\n\t\ttry {\n\t\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\t\tuserPresets = config.presets || [];\n\t\t} catch {\n\t\t\t// Start fresh\n\t\t}\n\t}\n\n\t// Update or add\n\tconst idx = userPresets.findIndex((p) => p.id === preset.id);\n\tif (idx >= 0) {\n\t\tuserPresets[idx] = preset;\n\t} else {\n\t\tuserPresets.push(preset);\n\t}\n\n\tsavePresets(userPresets);\n}\n\n/** Get built-in preset IDs (for UI distinction) */\nexport function getBuiltInPresetIds(): string[] {\n\treturn BUILT_IN_PRESETS.map((p) => p.id);\n}\n\n/** Delete a user-defined preset by ID */\nexport function deletePreset(id: string): { success: boolean; error?: string } {\n\t// Cannot delete built-in presets\n\tif (BUILT_IN_PRESETS.some((p) => p.id === id)) {\n\t\treturn { success: false, error: 'Cannot delete built-in presets' };\n\t}\n\n\tconst presetsPath = getPresetsPath();\n\tif (!existsSync(presetsPath)) {\n\t\treturn { success: false, error: 'Preset not found' };\n\t}\n\n\ttry {\n\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\tconst userPresets = config.presets || [];\n\n\t\tconst idx = userPresets.findIndex((p) => p.id === id);\n\t\tif (idx < 0) {\n\t\t\treturn { success: false, error: 'Preset not found' };\n\t\t}\n\n\t\tuserPresets.splice(idx, 1);\n\t\tsavePresets(userPresets);\n\t\treturn { success: true };\n\t} catch {\n\t\treturn { success: false, error: 'Failed to delete preset' };\n\t}\n}\n","/**\n * Colored console output utilities\n */\n\n// ANSI color codes\nconst RED = '\\x1b[31m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst BLUE = '\\x1b[34m';\nconst CYAN = '\\x1b[36m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\n\n// Status symbols\nconst CHECK = '✓';\nconst CROSS = '✗';\nconst ARROW = '→';\nconst BULLET = '•';\nconst SPINNER = '⠋';\n\n/** Print success message with checkmark */\nexport function success(message: string): void {\n\tconsole.log(`${GREEN}${CHECK}${RESET} ${message}`);\n}\n\n/** Print error message with X */\nexport function error(message: string): void {\n\tconsole.log(`${RED}${CROSS}${RESET} ${message}`);\n}\n\n/** Print warning message */\nexport function warn(message: string): void {\n\tconsole.log(`${YELLOW}${BULLET}${RESET} ${message}`);\n}\n\n/** Print info message */\nexport function info(message: string): void {\n\tconsole.log(`${BLUE}${ARROW}${RESET} ${message}`);\n}\n\n/** Print step message (for multi-step processes) */\nexport function step(message: string): void {\n\tconsole.log(`${CYAN}${BULLET}${RESET} ${message}`);\n}\n\n/** Print header with separator */\nexport function header(title: string): void {\n\tconsole.log('');\n\tconsole.log(`${BOLD}${title}${RESET}`);\n\tconsole.log(`${DIM}${'─'.repeat(40)}${RESET}`);\n}\n\n/** Print separator line */\nexport function separator(): void {\n\tconsole.log(`${DIM}${'─'.repeat(40)}${RESET}`);\n}\n\n/** Work-in-progress indicator (inline, no newline) */\nexport function wip(message: string): void {\n\tprocess.stdout.write(`${YELLOW}${SPINNER}${RESET} ${message}`);\n}\n\n/** Complete a WIP indicator with result */\nexport function wipDone(isSuccess: boolean, message: string): void {\n\t// Clear line and print result\n\tprocess.stdout.write('\\r\\x1b[K');\n\tif (isSuccess) {\n\t\tsuccess(message);\n\t} else {\n\t\terror(message);\n\t}\n}\n\n/** Clear current line */\nexport function clearLine(): void {\n\tprocess.stdout.write('\\r\\x1b[K');\n}\n\nexport { RESET, BOLD, DIM, GREEN, RED, YELLOW, BLUE, CYAN };\n","import { exec } from 'node:child_process';\nimport { copyFileSync, existsSync, mkdirSync, unlinkSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\n/**\n * Get input path with frame selector for multi-frame formats (ICO, GIF)\n * ICO files contain multiple resolutions - [0] selects the largest\n */\nfunction getInputSelector(imagePath: string): string {\n\tconst lowerPath = imagePath.toLowerCase();\n\tif (lowerPath.endsWith('.ico')) {\n\t\treturn `\"${imagePath}[0]\"`;\n\t}\n\treturn `\"${imagePath}\"`;\n}\n\n/**\n * Check if ImageMagick is installed\n */\nexport async function checkImageMagick(): Promise<boolean> {\n\ttry {\n\t\tawait execAsync('command -v convert');\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get image dimensions\n * Returns [width, height] or null on error\n */\nexport async function getDimensions(\n\timagePath: string,\n): Promise<[number, number] | null> {\n\ttry {\n\t\tconst input = getInputSelector(imagePath);\n\t\tconst { stdout } = await execAsync(\n\t\t\t`convert ${input} -ping -format \"%w %h\" info:`,\n\t\t);\n\t\tconst [w, h] = stdout.trim().split(' ').map(Number);\n\t\tif (Number.isNaN(w) || Number.isNaN(h)) return null;\n\t\treturn [w, h];\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Get border color (samples top-left pixel)\n */\nexport async function getBorderColor(\n\timagePath: string,\n): Promise<string | null> {\n\ttry {\n\t\tconst input = getInputSelector(imagePath);\n\t\tconst { stdout } = await execAsync(\n\t\t\t`convert ${input} -format \"%[pixel:u.p{0,0}]\" info:`,\n\t\t);\n\t\treturn stdout.trim();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Trim transparent/whitespace edges from image\n */\nexport async function trim(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst input = getInputSelector(inputPath);\n\t\tawait execAsync(`convert ${input} -trim +repage \"${outputPath}\"`);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Make image square by adding transparent padding\n */\nexport async function squarify(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\tconst dims = await getDimensions(inputPath);\n\tif (!dims) return false;\n\n\tconst [width, height] = dims;\n\n\t// Already square - just copy\n\tif (width === height) {\n\t\tif (inputPath !== outputPath) {\n\t\t\tcopyFileSync(inputPath, outputPath);\n\t\t}\n\t\treturn true;\n\t}\n\n\tconst size = Math.max(width, height);\n\tconst input = getInputSelector(inputPath);\n\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert ${input} -background none -gravity center -extent ${size}x${size} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to specific size with transparent padding\n */\nexport async function scaleToSize(\n\tinputPath: string,\n\toutputPath: string,\n\tsize: number,\n): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -resize ${size}x${size} -background none -gravity center -extent ${size}x${size} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image with custom dimensions and padding\n */\nexport async function scaleWithPadding(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -resize ${width}x${height} -background none -gravity center -extent ${width}x${height} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to exact dimensions (may distort)\n */\nexport async function resize(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -resize ${width}x${height}! \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to fill area and crop to exact size (cover mode)\n */\nexport async function scaleFillCrop(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -resize ${width}x${height}^ -background none -gravity center -extent ${width}x${height} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Remove background color from image\n */\nexport async function removeBackground(\n\tinputPath: string,\n\toutputPath: string,\n\tcolor: string,\n\tfuzz: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst input = getInputSelector(inputPath);\n\t\tawait execAsync(\n\t\t\t`convert ${input} -fuzz ${fuzz}% -transparent \"${color}\" \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Remove background using flood-fill from edges only\n */\nexport async function removeBackgroundBorderOnly(\n\tinputPath: string,\n\toutputPath: string,\n\tcolor: string,\n\tfuzz: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst input = getInputSelector(inputPath);\n\t\tawait execAsync(\n\t\t\t`convert ${input} -bordercolor \"${color}\" -border 1x1 -fill none -fuzz ${fuzz}% -draw \"matte 0,0 floodfill\" -shave 1x1 \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Create ICO file with multiple resolutions\n */\nexport async function createIco(\n\tinputPath: string,\n\toutputPath: string,\n\tsizes: number[] = [256, 128, 64, 48, 32, 16],\n): Promise<boolean> {\n\ttry {\n\t\tconst sizeStr = sizes.join(',');\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -define icon:auto-resize=${sizeStr} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Create ICO from multiple PNG files\n */\nexport async function createIcoFromMultiple(\n\tpngPaths: string[],\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst inputs = pngPaths.map((p) => `\"${p}\"`).join(' ');\n\t\tawait execAsync(`convert ${inputs} \"${outputPath}\"`);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Ensure output directory exists\n */\nexport function ensureDir(filePath: string): void {\n\tconst dir = dirname(filePath);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n}\n\n/**\n * Clean up temporary files\n */\nexport function cleanup(...files: string[]): void {\n\tfor (const file of files) {\n\t\ttry {\n\t\t\tif (existsSync(file)) {\n\t\t\t\tunlinkSync(file);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t}\n}\n","import { existsSync, readFileSync } from 'node:fs';\r\nimport { tmpdir } from 'node:os';\r\nimport { basename, join } from 'node:path';\r\nimport { startGuiServer } from '../lib/gui-server.js';\r\nimport { error, header, success, wip, wipDone } from '../lib/logger.js';\r\nimport {\r\n\tcheckImageMagick,\r\n\tcleanup,\r\n\tcreateIco,\r\n\tgetDimensions,\r\n\tscaleToSize,\r\n\tsquarify,\r\n\ttrim,\r\n} from '../lib/magick.js';\r\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\r\nimport { pauseOnError } from '../lib/prompts.js';\r\n\r\n/** Processing options for makeicon */\r\ninterface ProcessOptions {\r\n\ttrim: boolean;\r\n\tmakeSquare: boolean;\r\n}\r\n\r\n/**\r\n * Convert PNG to ICO with multiple resolutions\r\n */\r\nexport async function run(inputRaw: string): Promise<boolean> {\r\n\t// Check dependencies\r\n\tif (!(await checkImageMagick())) {\r\n\t\terror('ImageMagick not found. Please install it:');\r\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\r\n\t\tawait pauseOnError();\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Normalize path\r\n\tconst input = normalizePath(inputRaw);\r\n\r\n\tif (!existsSync(input)) {\r\n\t\terror(`File not found: ${input}`);\r\n\t\tawait pauseOnError();\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Get file info\r\n\tconst fileInfo = getFileInfo(input);\r\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\r\n\tconst tempTrimmed = `${fileInfo.dirname}/${fileInfo.filename}_trimmed.png`;\r\n\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square.png`;\r\n\tconst tempScaled = `${fileInfo.dirname}/${fileInfo.filename}_scaled.png`;\r\n\r\n\theader('PicLet Make Icon');\r\n\r\n\t// Get original dimensions\r\n\twip('Analyzing image...');\r\n\tconst dims = await getDimensions(input);\r\n\tif (!dims) {\r\n\t\twipDone(false, 'Failed to read image');\r\n\t\treturn false;\r\n\t}\r\n\twipDone(true, `Original size: ${dims[0]}x${dims[1]}`);\r\n\r\n\t// Step 1: Trim transparent areas\r\n\twip('Trimming transparent areas...');\r\n\tif (!(await trim(input, tempTrimmed))) {\r\n\t\twipDone(false, 'Trim failed');\r\n\t\tcleanup(tempTrimmed);\r\n\t\treturn false;\r\n\t}\r\n\twipDone(true, 'Trimmed');\r\n\r\n\t// Step 2: Make square\r\n\twip('Making square...');\r\n\tif (!(await squarify(tempTrimmed, tempSquare))) {\r\n\t\twipDone(false, 'Square padding failed');\r\n\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempTrimmed);\r\n\twipDone(true, 'Made square');\r\n\r\n\t// Step 3: Scale to 512px for best quality source\r\n\twip('Scaling to 512px...');\r\n\tif (!(await scaleToSize(tempSquare, tempScaled, 512))) {\r\n\t\twipDone(false, 'Scaling failed');\r\n\t\tcleanup(tempSquare, tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempSquare);\r\n\twipDone(true, 'Scaled to 512x512');\r\n\r\n\t// Step 4: Create ICO with multiple resolutions\r\n\twip('Creating icon (256, 128, 64, 48, 32, 16)...');\r\n\tif (!(await createIco(tempScaled, output))) {\r\n\t\twipDone(false, 'Icon creation failed');\r\n\t\tcleanup(tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempScaled);\r\n\twipDone(true, 'Icon created');\r\n\r\n\tconsole.log('');\r\n\tsuccess(`Output: ${output}`);\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * Process image for icon creation (shared logic)\r\n */\r\nasync function processForIcon(\r\n\tinput: string,\r\n\toutput: string,\r\n\toptions: ProcessOptions,\r\n\tlogs?: Array<{ type: string; message: string }>,\r\n): Promise<boolean> {\r\n\tconst fileInfo = getFileInfo(input);\r\n\tconst tempTrimmed = `${fileInfo.dirname}/${fileInfo.filename}_trimmed.png`;\r\n\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square.png`;\r\n\tconst tempScaled = `${fileInfo.dirname}/${fileInfo.filename}_scaled.png`;\r\n\r\n\tlet currentInput = input;\r\n\r\n\t// Step 1: Trim (optional)\r\n\tif (options.trim) {\r\n\t\tlogs?.push({ type: 'info', message: 'Trimming transparent areas...' });\r\n\t\tif (!(await trim(currentInput, tempTrimmed))) {\r\n\t\t\tcleanup(tempTrimmed);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tcurrentInput = tempTrimmed;\r\n\t\tlogs?.push({ type: 'success', message: 'Trimmed' });\r\n\t}\r\n\r\n\t// Step 2: Squarify (optional)\r\n\tif (options.makeSquare) {\r\n\t\tlogs?.push({ type: 'info', message: 'Making square...' });\r\n\t\tif (!(await squarify(currentInput, tempSquare))) {\r\n\t\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tif (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\t\tcurrentInput = tempSquare;\r\n\t\tlogs?.push({ type: 'success', message: 'Made square' });\r\n\t}\r\n\r\n\t// Step 3: Scale to 512px\r\n\tlogs?.push({ type: 'info', message: 'Scaling to 512px...' });\r\n\tif (!(await scaleToSize(currentInput, tempScaled, 512))) {\r\n\t\tcleanup(tempTrimmed, tempSquare, tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tif (currentInput === tempSquare) cleanup(tempSquare);\r\n\telse if (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\tlogs?.push({ type: 'success', message: 'Scaled to 512x512' });\r\n\r\n\t// Step 4: Create ICO\r\n\tlogs?.push({ type: 'info', message: 'Creating icon (256, 128, 64, 48, 32, 16)...' });\r\n\tif (!(await createIco(tempScaled, output))) {\r\n\t\tcleanup(tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempScaled);\r\n\tlogs?.push({ type: 'success', message: 'Icon created' });\r\n\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * Generate preview image as base64 data URL\r\n */\r\nasync function generatePreview(\r\n\tinput: string,\r\n\toptions: ProcessOptions,\r\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\r\n\tconst tempDir = tmpdir();\r\n\tconst timestamp = Date.now();\r\n\tconst tempTrimmed = join(tempDir, `piclet-preview-trimmed-${timestamp}.png`);\r\n\tconst tempSquare = join(tempDir, `piclet-preview-square-${timestamp}.png`);\r\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\r\n\r\n\ttry {\r\n\t\tlet currentInput = input;\r\n\r\n\t\t// Trim if enabled\r\n\t\tif (options.trim) {\r\n\t\t\tif (!(await trim(currentInput, tempTrimmed))) {\r\n\t\t\t\tcleanup(tempTrimmed);\r\n\t\t\t\treturn { success: false, error: 'Trim failed' };\r\n\t\t\t}\r\n\t\t\tcurrentInput = tempTrimmed;\r\n\t\t}\r\n\r\n\t\t// Squarify if enabled\r\n\t\tif (options.makeSquare) {\r\n\t\t\tif (!(await squarify(currentInput, tempSquare))) {\r\n\t\t\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\t\t\treturn { success: false, error: 'Square failed' };\r\n\t\t\t}\r\n\t\t\tif (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\t\t\tcurrentInput = tempSquare;\r\n\t\t}\r\n\r\n\t\t// Scale to preview size (256px)\r\n\t\tif (!(await scaleToSize(currentInput, tempOutput, 256))) {\r\n\t\t\tcleanup(tempTrimmed, tempSquare, tempOutput);\r\n\t\t\treturn { success: false, error: 'Scale failed' };\r\n\t\t}\r\n\t\tif (currentInput === tempSquare) cleanup(tempSquare);\r\n\t\telse if (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\r\n\t\tconst buffer = readFileSync(tempOutput);\r\n\t\tconst base64 = buffer.toString('base64');\r\n\t\tconst imageData = `data:image/png;base64,${base64}`;\r\n\r\n\t\tconst dims = await getDimensions(tempOutput);\r\n\t\tcleanup(tempOutput);\r\n\r\n\t\treturn {\r\n\t\t\tsuccess: true,\r\n\t\t\timageData,\r\n\t\t\twidth: dims?.[0],\r\n\t\t\theight: dims?.[1],\r\n\t\t};\r\n\t} catch (err) {\r\n\t\tcleanup(tempTrimmed, tempSquare, tempOutput);\r\n\t\treturn { success: false, error: (err as Error).message };\r\n\t}\r\n}\r\n\r\n/**\r\n * Convert PNG to ICO (GUI mode)\r\n */\r\nexport async function runGUI(inputRaw: string): Promise<boolean> {\r\n\tconst input = normalizePath(inputRaw);\r\n\r\n\tif (!existsSync(input)) {\r\n\t\terror(`File not found: ${input}`);\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst dims = await getDimensions(input);\r\n\tif (!dims) {\r\n\t\terror('Failed to read image dimensions');\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst fileInfo = getFileInfo(input);\r\n\r\n\treturn startGuiServer({\r\n\t\thtmlFile: 'makeicon.html',\r\n\t\ttitle: 'PicLet - Make Icon',\r\n\t\timageInfo: {\r\n\t\t\tfilePath: input,\r\n\t\t\tfileName: basename(input),\r\n\t\t\twidth: dims[0],\r\n\t\t\theight: dims[1],\r\n\t\t\tborderColor: null,\r\n\t\t},\r\n\t\tdefaults: {\r\n\t\t\ttrim: true,\r\n\t\t\tmakeSquare: true,\r\n\t\t},\r\n\t\tonPreview: async (opts) => {\r\n\t\t\tconst options: ProcessOptions = {\r\n\t\t\t\ttrim: (opts.trim as boolean) ?? true,\r\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? true,\r\n\t\t\t};\r\n\t\t\treturn generatePreview(input, options);\r\n\t\t},\r\n\t\tonProcess: async (opts) => {\r\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\r\n\r\n\t\t\tif (!(await checkImageMagick())) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: false,\r\n\t\t\t\t\terror: 'ImageMagick not found',\r\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\tconst options: ProcessOptions = {\r\n\t\t\t\ttrim: (opts.trim as boolean) ?? true,\r\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? true,\r\n\t\t\t};\r\n\r\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\r\n\r\n\t\t\tconst success = await processForIcon(input, output, options, logs);\r\n\r\n\t\t\tif (success) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: true,\r\n\t\t\t\t\toutput: `${fileInfo.filename}.ico`,\r\n\t\t\t\t\tlogs,\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\treturn { success: false, error: 'Icon creation failed', logs };\r\n\t\t},\r\n\t});\r\n}\r\n\r\nexport const config = {\r\n\tid: 'makeicon',\r\n\tname: 'Make Icon',\r\n\ticon: 'makeicon.ico',\r\n\textensions: ['.png'],\r\n};\r\n","/**\n * Unified PicLet tool - combines all tools with chaining support\n */\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, dirname, extname, join } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport { error } from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tcreateIco,\n\tcreateIcoFromMultiple,\n\tgetBorderColor,\n\tgetDimensions,\n\tremoveBackground,\n\tremoveBackgroundBorderOnly,\n\tresize,\n\tscaleFillCrop,\n\tscaleToSize,\n\tscaleWithPadding,\n\tsquarify,\n\ttrim,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { loadPresets } from '../lib/presets.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface PreviewResult {\n\tsuccess: boolean;\n\timageData?: string;\n\twidth?: number;\n\theight?: number;\n\terror?: string;\n}\n\ninterface ProcessResult {\n\tsuccess: boolean;\n\toutput?: string;\n\terror?: string;\n\tlogs: Array<{ type: string; message: string }>;\n}\n\ninterface Dimension {\n\twidth: number;\n\theight: number;\n\tfilename?: string;\n}\n\ninterface ToolOptions {\n\ttools: string[];\n\toriginal?: boolean;\n\tremovebg?: { fuzz: number; trim: boolean; preserveInner: boolean };\n\tscale?: { width: number; height: number; makeSquare: boolean };\n\ticons?: {\n\t\ttrim: boolean;\n\t\tmakeSquare: boolean;\n\t\tico: boolean;\n\t\tweb: boolean;\n\t\tandroid: boolean;\n\t\tios: boolean;\n\t};\n\tstorepack?: { dimensions: Dimension[]; scaleMode: string; presetName?: string };\n}\n\n// Tool execution order (for chaining)\nconst TOOL_ORDER = ['removebg', 'scale', 'icons', 'storepack'];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Preview - Chains enabled tools\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function generateCombinedPreview(\n\tinput: string,\n\tborderColor: string | null,\n\topts: ToolOptions,\n): Promise<PreviewResult> {\n\tconst tempDir = tmpdir();\n\tconst ts = Date.now();\n\tconst temps: string[] = [];\n\n\tconst makeTempPath = (suffix: string) => {\n\t\tconst p = join(tempDir, `piclet-${ts}-${suffix}.png`);\n\t\ttemps.push(p);\n\t\treturn p;\n\t};\n\n\ttry {\n\t\tlet current = input;\n\n\t\t// If just showing original, scale it for preview and return\n\t\tif (opts.original || opts.tools.length === 0) {\n\t\t\tconst dims = await getDimensions(input);\n\t\t\tlet previewPath = input;\n\n\t\t\tif (dims && (dims[0] > 512 || dims[1] > 512)) {\n\t\t\t\tconst scaled = makeTempPath('orig-preview');\n\t\t\t\tconst targetSize = Math.min(512, Math.max(dims[0], dims[1]));\n\t\t\t\tif (await scaleToSize(input, scaled, targetSize)) {\n\t\t\t\t\tpreviewPath = scaled;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst buffer = readFileSync(previewPath);\n\t\t\tconst finalDims = await getDimensions(previewPath);\n\t\t\tcleanup(...temps);\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\t\twidth: finalDims?.[0] ?? dims?.[0],\n\t\t\t\theight: finalDims?.[1] ?? dims?.[1],\n\t\t\t};\n\t\t}\n\n\t\t// Get ordered list of active tools\n\t\tconst activeTools = TOOL_ORDER.filter(t => opts.tools.includes(t));\n\n\t\t// Process each tool in order\n\t\tfor (const tool of activeTools) {\n\t\t\tswitch (tool) {\n\t\t\t\tcase 'removebg': {\n\t\t\t\t\tconst rbOpts = opts.removebg!;\n\t\t\t\t\tconst out = makeTempPath('removebg');\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tif (rbOpts.preserveInner && borderColor) {\n\t\t\t\t\t\tsuccess = await removeBackgroundBorderOnly(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\t}\n\t\t\t\t\tif (!success && borderColor) {\n\t\t\t\t\t\tsuccess = await removeBackground(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\t}\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\t\treturn { success: false, error: 'Background removal failed' };\n\t\t\t\t\t}\n\n\t\t\t\t\t// Trim if enabled\n\t\t\t\t\tif (rbOpts.trim) {\n\t\t\t\t\t\tconst trimOut = makeTempPath('trim');\n\t\t\t\t\t\tif (await trim(out, trimOut)) {\n\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase 'scale': {\n\t\t\t\t\tconst scOpts = opts.scale!;\n\t\t\t\t\tconst out = makeTempPath('scale');\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tif (scOpts.makeSquare) {\n\t\t\t\t\t\tconst max = Math.max(scOpts.width, scOpts.height);\n\t\t\t\t\t\tsuccess = await scaleWithPadding(current, out, max, max);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsuccess = await resize(current, out, scOpts.width, scOpts.height);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\t\treturn { success: false, error: 'Scale failed' };\n\t\t\t\t\t}\n\t\t\t\t\tcurrent = out;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase 'icons': {\n\t\t\t\t\t// For preview, show what the icon source would look like after trim/squarify\n\t\t\t\t\tconst icOpts = opts.icons!;\n\n\t\t\t\t\tif (icOpts.trim && current === input) {\n\t\t\t\t\t\tconst trimOut = makeTempPath('ic-trim');\n\t\t\t\t\t\tif (await trim(current, trimOut)) {\n\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.makeSquare) {\n\t\t\t\t\t\tconst sqOut = makeTempPath('ic-sq');\n\t\t\t\t\t\tif (await squarify(current, sqOut)) {\n\t\t\t\t\t\t\tcurrent = sqOut;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// storepack doesn't affect preview\n\t\t\t}\n\t\t}\n\n\t\t// Scale down for preview display if needed\n\t\tconst dims = await getDimensions(current);\n\t\tlet previewPath = current;\n\n\t\tif (dims && (dims[0] > 512 || dims[1] > 512)) {\n\t\t\tconst scaled = makeTempPath('preview');\n\t\t\tconst targetSize = Math.min(512, Math.max(dims[0], dims[1]));\n\t\t\tif (await scaleToSize(current, scaled, targetSize)) {\n\t\t\t\tpreviewPath = scaled;\n\t\t\t}\n\t\t}\n\n\t\tconst buffer = readFileSync(previewPath);\n\t\tconst finalDims = await getDimensions(previewPath);\n\t\tcleanup(...temps);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\twidth: finalDims?.[0],\n\t\t\theight: finalDims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(...temps);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Process - Chains enabled tools and produces output\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function processCombined(\n\tinput: string,\n\tborderColor: string | null,\n\topts: ToolOptions,\n\tlogs: Array<{ type: string; message: string }>,\n): Promise<string[]> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputs: string[] = [];\n\tconst temps: string[] = [];\n\n\tconst makeTempPath = (suffix: string) => {\n\t\tconst p = `${fileInfo.dirname}/${fileInfo.filename}_${suffix}.png`;\n\t\ttemps.push(p);\n\t\treturn p;\n\t};\n\n\tlet current = input;\n\tconst activeTools = TOOL_ORDER.filter(t => opts.tools.includes(t));\n\n\tfor (const tool of activeTools) {\n\t\tswitch (tool) {\n\t\t\tcase 'removebg': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Removing background...' });\n\t\t\t\tconst rbOpts = opts.removebg!;\n\t\t\t\tconst out = makeTempPath('nobg');\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (rbOpts.preserveInner && borderColor) {\n\t\t\t\t\tsuccess = await removeBackgroundBorderOnly(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tlogs.push({ type: 'warn', message: 'Border-only failed, trying full removal' });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!success && borderColor) {\n\t\t\t\t\tsuccess = await removeBackground(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t}\n\t\t\t\tif (!success) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Background removal failed' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\tlogs.push({ type: 'success', message: 'Background removed' });\n\n\t\t\t\tif (rbOpts.trim) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Trimming edges...' });\n\t\t\t\t\tconst trimOut = makeTempPath('trimmed');\n\t\t\t\t\tif (await trim(out, trimOut)) {\n\t\t\t\t\t\tcleanup(out);\n\t\t\t\t\t\ttemps.splice(temps.indexOf(out), 1);\n\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcurrent = out;\n\t\t\t\t}\n\n\t\t\t\t// If this is the last tool, save output\n\t\t\t\tif (activeTools.indexOf(tool) === activeTools.length - 1) {\n\t\t\t\t\tconst finalOut = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;\n\t\t\t\t\trenameSync(current, finalOut);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t\toutputs.push(basename(finalOut));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'scale': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Scaling image...' });\n\t\t\t\tconst scOpts = opts.scale!;\n\t\t\t\tconst out = makeTempPath('scaled');\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (scOpts.makeSquare) {\n\t\t\t\t\tconst max = Math.max(scOpts.width, scOpts.height);\n\t\t\t\t\tsuccess = await scaleWithPadding(current, out, max, max);\n\t\t\t\t} else {\n\t\t\t\t\tsuccess = await resize(current, out, scOpts.width, scOpts.height);\n\t\t\t\t}\n\n\t\t\t\tif (!success) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Scale failed' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\tconst dims = await getDimensions(out);\n\t\t\t\tlogs.push({ type: 'success', message: `Scaled to ${dims?.[0]}×${dims?.[1]}` });\n\n\t\t\t\t// Clean up previous temp if it's not the input\n\t\t\t\tif (current !== input && temps.includes(current)) {\n\t\t\t\t\tcleanup(current);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t}\n\t\t\t\tcurrent = out;\n\n\t\t\t\t// If this is the last tool, save output\n\t\t\t\tif (activeTools.indexOf(tool) === activeTools.length - 1) {\n\t\t\t\t\tconst finalOut = `${fileInfo.dirname}/${fileInfo.filename}_scaled${fileInfo.extension}`;\n\t\t\t\t\trenameSync(current, finalOut);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t\toutputs.push(basename(finalOut));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'icons': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating icons...' });\n\t\t\t\tconst icOpts = opts.icons!;\n\n\t\t\t\t// Need at least one output format\n\t\t\t\tif (!icOpts.ico && !icOpts.web && !icOpts.android && !icOpts.ios) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'No output format selected' });\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\t// Prepare source - apply trim and squarify\n\t\t\t\tlet iconSource = current;\n\n\t\t\t\tif (icOpts.trim && current === input) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Trimming edges...' });\n\t\t\t\t\tconst trimOut = makeTempPath('ic-trim');\n\t\t\t\t\tif (await trim(current, trimOut)) {\n\t\t\t\t\t\ticonSource = trimOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (icOpts.makeSquare) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Making square...' });\n\t\t\t\t\tconst sqOut = makeTempPath('ic-sq');\n\t\t\t\t\tif (await squarify(iconSource, sqOut)) {\n\t\t\t\t\t\tif (iconSource !== current && iconSource !== input) cleanup(iconSource);\n\t\t\t\t\t\ticonSource = sqOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Made square' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Prepare high-res source (1024px for packs, 512px for ICO only)\n\t\t\t\tconst maxSize = icOpts.web || icOpts.android || icOpts.ios ? 1024 : 512;\n\t\t\t\tconst srcTemp = makeTempPath('ic-src');\n\t\t\t\tif (!(await scaleToSize(iconSource, srcTemp, maxSize))) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Failed to prepare icon source' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\tif (iconSource !== current && iconSource !== input) cleanup(iconSource);\n\n\t\t\t\tlet totalCount = 0;\n\n\t\t\t\t// Generate ICO file\n\t\t\t\tif (icOpts.ico) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Creating ICO file...' });\n\t\t\t\t\tconst icoOut = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\n\t\t\t\t\tif (await createIco(srcTemp, icoOut)) {\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'ICO: 6 sizes (256, 128, 64, 48, 32, 16)' });\n\t\t\t\t\t\toutputs.push(basename(icoOut));\n\t\t\t\t\t\ttotalCount += 6;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogs.push({ type: 'warn', message: 'ICO creation failed' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Generate icon packs (Web, Android, iOS)\n\t\t\t\tconst needsPacks = icOpts.web || icOpts.android || icOpts.ios;\n\t\t\t\tif (needsPacks) {\n\t\t\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\t\t\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\t\t\tif (icOpts.web) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating Web icons...' });\n\t\t\t\t\t\tconst webDir = `${outputDir}/web`;\n\t\t\t\t\t\tmkdirSync(webDir, { recursive: true });\n\n\t\t\t\t\t\t// Favicon.ico\n\t\t\t\t\t\tconst t16 = `${webDir}/.t16.png`, t32 = `${webDir}/.t32.png`, t48 = `${webDir}/.t48.png`;\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t16, 16);\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t32, 32);\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t48, 48);\n\t\t\t\t\t\tawait createIcoFromMultiple([t16, t32, t48], `${webDir}/favicon.ico`);\n\t\t\t\t\t\tcleanup(t16, t32, t48);\n\t\t\t\t\t\ttotalCount++;\n\n\t\t\t\t\t\tconst webIcons = [\n\t\t\t\t\t\t\t{ name: 'favicon-16x16.png', size: 16 }, { name: 'favicon-32x32.png', size: 32 },\n\t\t\t\t\t\t\t{ name: 'apple-touch-icon.png', size: 180 }, { name: 'android-chrome-192x192.png', size: 192 },\n\t\t\t\t\t\t\t{ name: 'android-chrome-512x512.png', size: 512 }, { name: 'mstile-150x150.png', size: 150 },\n\t\t\t\t\t\t];\n\t\t\t\t\t\tfor (const i of webIcons) {\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, `${webDir}/${i.name}`, i.size);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Web: 7 icons' });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.android) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating Android icons...' });\n\t\t\t\t\t\tconst androidDir = `${outputDir}/android`;\n\t\t\t\t\t\tconst androidIcons = [\n\t\t\t\t\t\t\t{ name: 'mipmap-mdpi/ic_launcher.png', size: 48 },\n\t\t\t\t\t\t\t{ name: 'mipmap-hdpi/ic_launcher.png', size: 72 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xhdpi/ic_launcher.png', size: 96 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xxhdpi/ic_launcher.png', size: 144 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xxxhdpi/ic_launcher.png', size: 192 },\n\t\t\t\t\t\t\t{ name: 'playstore-icon.png', size: 512 },\n\t\t\t\t\t\t];\n\t\t\t\t\t\tfor (const i of androidIcons) {\n\t\t\t\t\t\t\tconst p = `${androidDir}/${i.name}`;\n\t\t\t\t\t\t\tmkdirSync(dirname(p), { recursive: true });\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, p, i.size);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Android: 6 icons' });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.ios) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating iOS icons...' });\n\t\t\t\t\t\tconst iosDir = `${outputDir}/ios`;\n\t\t\t\t\t\tmkdirSync(iosDir, { recursive: true });\n\t\t\t\t\t\tconst iosSizes = [20, 29, 40, 58, 60, 76, 80, 87, 120, 152, 167, 180, 1024];\n\t\t\t\t\t\tfor (const s of iosSizes) {\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, `${iosDir}/AppIcon-${s}.png`, s);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: `iOS: ${iosSizes.length} icons` });\n\t\t\t\t\t}\n\n\t\t\t\t\toutputs.push(`${totalCount} icons → ${fileInfo.filename}_icons/`);\n\t\t\t\t}\n\n\t\t\t\tcleanup(srcTemp);\n\t\t\t\tlogs.push({ type: 'success', message: `Generated ${totalCount} total icons` });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'storepack': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating store assets...' });\n\t\t\t\tconst spOpts = opts.storepack!;\n\n\t\t\t\tif (!spOpts.dimensions || spOpts.dimensions.length === 0) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'No dimensions specified' });\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\tconst folderName = spOpts.presetName || 'assets';\n\t\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${folderName}`;\n\t\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\t\tlet count = 0;\n\t\t\t\tfor (const dim of spOpts.dimensions) {\n\t\t\t\t\tconst filename = dim.filename || `${dim.width}x${dim.height}.png`;\n\t\t\t\t\tconst out = join(outputDir, filename);\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tswitch (spOpts.scaleMode) {\n\t\t\t\t\t\tcase 'fill':\n\t\t\t\t\t\t\tsuccess = await scaleFillCrop(current, out, dim.width, dim.height);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'stretch':\n\t\t\t\t\t\t\tsuccess = await resize(current, out, dim.width, dim.height);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tsuccess = await scaleWithPadding(current, out, dim.width, dim.height);\n\t\t\t\t\t}\n\t\t\t\t\tif (success) count++;\n\t\t\t\t}\n\n\t\t\t\tlogs.push({ type: 'success', message: `Generated ${count}/${spOpts.dimensions.length} images` });\n\t\t\t\toutputs.push(`${count} images → ${fileInfo.filename}_${folderName}/`);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Cleanup any remaining temps\n\tcleanup(...temps);\n\treturn outputs;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Main GUI Entry Point\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tlet currentInput = normalizePath(inputRaw);\n\n\tif (!existsSync(currentInput)) {\n\t\terror(`File not found: ${currentInput}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(currentInput);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tlet currentBorderColor = await getBorderColor(currentInput);\n\tconst presets = loadPresets();\n\n\treturn startGuiServer({\n\t\thtmlFile: 'piclet.html',\n\t\ttitle: 'PicLet',\n\t\timageInfo: {\n\t\t\tfilePath: currentInput,\n\t\t\tfileName: basename(currentInput),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: currentBorderColor,\n\t\t},\n\t\tdefaults: {\n\t\t\t// Return full preset data for the UI\n\t\t\tpresets: presets.map(p => ({\n\t\t\t\tid: p.id,\n\t\t\t\tname: p.name,\n\t\t\t\tdescription: p.description,\n\t\t\t\ticons: p.icons,\n\t\t\t})),\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst toolOpts = opts as unknown as ToolOptions;\n\t\t\t// Allow empty tools array - will show original image\n\t\t\tif (!toolOpts.tools) {\n\t\t\t\ttoolOpts.tools = [];\n\t\t\t}\n\t\t\treturn generateCombinedPreview(currentInput, currentBorderColor, toolOpts);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\t\t\tconst toolOpts = opts as unknown as ToolOptions;\n\n\t\t\tif (!toolOpts.tools || toolOpts.tools.length === 0) {\n\t\t\t\treturn { success: false, error: 'No tools selected', logs };\n\t\t\t}\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst outputs = await processCombined(currentInput, currentBorderColor, toolOpts, logs);\n\n\t\t\tif (outputs.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: outputs.join('\\n'),\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn { success: false, error: 'Processing failed', logs };\n\t\t},\n\t\tonLoadImage: async (data) => {\n\t\t\ttry {\n\t\t\t\t// Save base64 data to temp file\n\t\t\t\tconst ext = extname(data.fileName) || '.png';\n\t\t\t\tconst tempPath = join(tmpdir(), `piclet-load-${Date.now()}${ext}`);\n\t\t\t\tconst buffer = Buffer.from(data.data, 'base64');\n\t\t\t\twriteFileSync(tempPath, buffer);\n\n\t\t\t\t// Get dimensions and border color\n\t\t\t\tconst newDims = await getDimensions(tempPath);\n\t\t\t\tif (!newDims) {\n\t\t\t\t\tcleanup(tempPath);\n\t\t\t\t\treturn { success: false, error: 'Failed to read image dimensions' };\n\t\t\t\t}\n\n\t\t\t\tconst newBorderColor = await getBorderColor(tempPath);\n\n\t\t\t\t// Update current image\n\t\t\t\tcurrentInput = tempPath;\n\t\t\t\tcurrentBorderColor = newBorderColor;\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tfilePath: tempPath,\n\t\t\t\t\tfileName: data.fileName,\n\t\t\t\t\twidth: newDims[0],\n\t\t\t\t\theight: newDims[1],\n\t\t\t\t\tborderColor: newBorderColor,\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\treturn { success: false, error: (err as Error).message };\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport const config = {\n\tid: 'piclet',\n\tname: 'PicLet',\n\ticon: 'banana.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico'],\n};\n","import { existsSync, readFileSync, renameSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, dirname, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tgetBorderColor,\n\tgetDimensions,\n\tremoveBackground,\n\tremoveBackgroundBorderOnly,\n\tsquarify,\n\ttrim,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tconfirm as promptConfirm,\n\tisUsingDefaults,\n\tnumber as promptNumber,\n\tpauseOnError,\n} from '../lib/prompts.js';\n\n/** Processing options for remove-bg */\ninterface ProcessOptions {\n\tfuzz: number;\n\tdoTrim: boolean;\n\tpreserveInner: boolean;\n\tmakeSquare: boolean;\n}\n\n/**\n * Core processing logic for background removal\n */\nasync function processImage(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;\n\tconst tempFile = `${fileInfo.dirname}/${fileInfo.filename}_temp.png`;\n\n\twip('Removing background...');\n\n\tlet bgRemoved = false;\n\tif (options.preserveInner && borderColor) {\n\t\tbgRemoved = await removeBackgroundBorderOnly(\n\t\t\tinput,\n\t\t\ttempFile,\n\t\t\tborderColor,\n\t\t\toptions.fuzz,\n\t\t);\n\t\tif (!bgRemoved) {\n\t\t\twarn('Border-only removal failed, using standard method');\n\t\t}\n\t}\n\n\tif (!bgRemoved && borderColor) {\n\t\tbgRemoved = await removeBackground(input, tempFile, borderColor, options.fuzz);\n\t}\n\n\tif (!bgRemoved) {\n\t\twipDone(false, 'Background removal failed');\n\t\tcleanup(tempFile);\n\t\treturn false;\n\t}\n\twipDone(true, 'Background removed');\n\n\t// Trim if requested\n\tif (options.doTrim) {\n\t\twip('Trimming transparent edges...');\n\t\tif (await trim(tempFile, output)) {\n\t\t\twipDone(true, 'Trimmed');\n\t\t\tcleanup(tempFile);\n\t\t} else {\n\t\t\twipDone(false, 'Trim failed, keeping untrimmed');\n\t\t\trenameSync(tempFile, output);\n\t\t}\n\t} else {\n\t\trenameSync(tempFile, output);\n\t}\n\n\t// Make square if requested\n\tif (options.makeSquare) {\n\t\twip('Making square...');\n\t\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square_temp.png`;\n\t\tif (await squarify(output, tempSquare)) {\n\t\t\trenameSync(tempSquare, output);\n\t\t\twipDone(true, 'Made square');\n\t\t} else {\n\t\t\twipDone(false, 'Square padding failed');\n\t\t\tcleanup(tempSquare);\n\t\t}\n\t}\n\n\t// Final dimensions\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tsuccess(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tsuccess(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Fuzz Value:${RESET} Controls color matching strictness`);\n\tconsole.log(` ${DIM}0-10% = Only exact or very similar colors${RESET}`);\n\tconsole.log(` ${DIM}10-30% = Somewhat similar colors${RESET}`);\n\tconsole.log(` ${DIM}30-70% = Aggressive removal${RESET}`);\n\tconsole.log(` ${DIM}70-100% = May affect non-background areas${RESET}`);\n\tconsole.log('');\n\n\tlet fuzz = await promptNumber('Fuzz value (0-100)', 10, 0, 100);\n\tif (fuzz < 0 || fuzz > 100) {\n\t\twarn('Invalid fuzz value, using 10');\n\t\tfuzz = 10;\n\t}\n\n\tconsole.log('');\n\tconst doTrim = await promptConfirm(\n\t\t'Trim transparent edges after removal?',\n\t\ttrue,\n\t);\n\n\tconsole.log('');\n\tconst preserveInner = await promptConfirm(\n\t\t'Preserve inner areas of same color? (border-only removal)',\n\t\tfalse,\n\t);\n\n\tconsole.log('');\n\tconst makeSquare = await promptConfirm(\n\t\t'Make output square with transparent padding?',\n\t\tfalse,\n\t);\n\n\treturn { fuzz, doTrim, preserveInner, makeSquare };\n}\n\n\n/**\n * Remove solid background from image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Remove Background');\n\n\t// Get original dimensions\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\n\t// Detect border color\n\tconst borderColor = await getBorderColor(input);\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\tif (borderColor) {\n\t\tinfo(`Detected border color: ${borderColor}`);\n\t}\n\n\t// Collect options via CLI or TUI\n\tconst options = await collectOptionsCLI();\n\n\tconsole.log('');\n\treturn processImage(input, borderColor, options);\n}\n\n/**\n * Remove solid background from image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\t// Get original dimensions\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\t// Detect border color\n\tconst borderColor = await getBorderColor(input);\n\n\t// Load config defaults\n\tconst config = loadConfig();\n\tconst defaults = config.removeBg;\n\n\t// Start GUI server\n\treturn startGuiServer({\n\t\thtmlFile: 'remove-bg.html',\n\t\ttitle: 'PicLet - Remove Background',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor,\n\t\t},\n\t\tdefaults: {\n\t\t\tfuzz: defaults.fuzz,\n\t\t\ttrim: defaults.trim,\n\t\t\tpreserveInner: defaults.preserveInner,\n\t\t\tmakeSquare: defaults.makeSquare,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\tfuzz: (opts.fuzz as number) ?? defaults.fuzz,\n\t\t\t\tdoTrim: (opts.trim as boolean) ?? defaults.trim,\n\t\t\t\tpreserveInner: (opts.preserveInner as boolean) ?? defaults.preserveInner,\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? defaults.makeSquare,\n\t\t\t};\n\t\t\treturn generatePreview(input, borderColor, options);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\t// Check dependencies\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\tfuzz: (opts.fuzz as number) ?? defaults.fuzz,\n\t\t\t\tdoTrim: (opts.trim as boolean) ?? defaults.trim,\n\t\t\t\tpreserveInner: (opts.preserveInner as boolean) ?? defaults.preserveInner,\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? defaults.makeSquare,\n\t\t\t};\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;\n\n\t\t\t// Process the image\n\t\t\tlogs.push({ type: 'info', message: 'Removing background...' });\n\n\t\t\tconst success = await processImageSilent(input, borderColor, options, logs);\n\n\t\t\tif (success) {\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Silent version of processImage for GUI mode (logs to array instead of console)\n */\nasync function processImageSilent(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n\tlogs: Array<{ type: string; message: string }>,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;\n\tconst tempFile = `${fileInfo.dirname}/${fileInfo.filename}_temp.png`;\n\n\tlet bgRemoved = false;\n\tif (options.preserveInner && borderColor) {\n\t\tbgRemoved = await removeBackgroundBorderOnly(\n\t\t\tinput,\n\t\t\ttempFile,\n\t\t\tborderColor,\n\t\t\toptions.fuzz,\n\t\t);\n\t\tif (!bgRemoved) {\n\t\t\tlogs.push({ type: 'warn', message: 'Border-only removal failed, using standard method' });\n\t\t}\n\t}\n\n\tif (!bgRemoved && borderColor) {\n\t\tbgRemoved = await removeBackground(input, tempFile, borderColor, options.fuzz);\n\t}\n\n\tif (!bgRemoved) {\n\t\tlogs.push({ type: 'error', message: 'Background removal failed' });\n\t\tcleanup(tempFile);\n\t\treturn false;\n\t}\n\tlogs.push({ type: 'success', message: 'Background removed' });\n\n\t// Trim if requested\n\tif (options.doTrim) {\n\t\tlogs.push({ type: 'info', message: 'Trimming transparent edges...' });\n\t\tif (await trim(tempFile, output)) {\n\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\tcleanup(tempFile);\n\t\t} else {\n\t\t\tlogs.push({ type: 'warn', message: 'Trim failed, keeping untrimmed' });\n\t\t\trenameSync(tempFile, output);\n\t\t}\n\t} else {\n\t\trenameSync(tempFile, output);\n\t}\n\n\t// Make square if requested\n\tif (options.makeSquare) {\n\t\tlogs.push({ type: 'info', message: 'Making square...' });\n\t\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square_temp.png`;\n\t\tif (await squarify(output, tempSquare)) {\n\t\t\trenameSync(tempSquare, output);\n\t\t\tlogs.push({ type: 'success', message: 'Made square' });\n\t\t} else {\n\t\t\tlogs.push({ type: 'warn', message: 'Square padding failed' });\n\t\t\tcleanup(tempSquare);\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempFile = join(tempDir, `piclet-preview-${timestamp}.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}-out.png`);\n\n\ttry {\n\t\t// Remove background\n\t\tlet bgRemoved = false;\n\t\tif (options.preserveInner && borderColor) {\n\t\t\tbgRemoved = await removeBackgroundBorderOnly(input, tempFile, borderColor, options.fuzz);\n\t\t}\n\t\tif (!bgRemoved && borderColor) {\n\t\t\tbgRemoved = await removeBackground(input, tempFile, borderColor, options.fuzz);\n\t\t}\n\t\tif (!bgRemoved) {\n\t\t\treturn { success: false, error: 'Background removal failed' };\n\t\t}\n\n\t\t// Trim if requested\n\t\tlet currentFile = tempFile;\n\t\tif (options.doTrim) {\n\t\t\tif (await trim(tempFile, tempOutput)) {\n\t\t\t\tcleanup(tempFile);\n\t\t\t\tcurrentFile = tempOutput;\n\t\t\t}\n\t\t}\n\n\t\t// Make square if requested\n\t\tif (options.makeSquare) {\n\t\t\tconst squareFile = join(tempDir, `piclet-preview-${timestamp}-sq.png`);\n\t\t\tif (await squarify(currentFile, squareFile)) {\n\t\t\t\tcleanup(currentFile);\n\t\t\t\tcurrentFile = squareFile;\n\t\t\t}\n\t\t}\n\n\t\t// Read as base64\n\t\tconst buffer = readFileSync(currentFile);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\t// Get dimensions\n\t\tconst dims = await getDimensions(currentFile);\n\n\t\t// Cleanup\n\t\tcleanup(currentFile, tempFile, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempFile, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'remove-bg',\n\tname: 'Remove Background',\n\ticon: 'removebg.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.ico'],\n};\n","import { existsSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tgetDimensions,\n\tresize,\n\tscaleWithPadding,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tconfirm as promptConfirm,\n\tnumber as promptNumber,\n\tpauseOnError,\n} from '../lib/prompts.js';\n\n/** Processing options for rescale */\ninterface ProcessOptions {\n\twidth: number;\n\theight: number;\n\tmakeSquare: boolean;\n}\n\n/**\n * Scale image with optional padding\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Get file info\n\tconst fileInfo = getFileInfo(input);\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_scaled${fileInfo.extension}`;\n\n\theader('PicLet Scale Image');\n\n\t// Get original dimensions\n\twip('Reading image dimensions...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\tconst [origW, origH] = dims;\n\twipDone(true, `Original size: ${origW}x${origH}`);\n\n\t// Check if image is square\n\tif (origW !== origH) {\n\t\twarn(`Image is not square (${origW}x${origH})`);\n\t}\n\n\tconsole.log('');\n\tconsole.log(`${BOLD}Scaling Options:${RESET}`);\n\tconsole.log(\n\t\t` ${DIM}Enter 0 for auto-calculate based on other dimension${RESET}`,\n\t);\n\tconsole.log(\n\t\t` ${DIM}Enter single number for both to make square output${RESET}`,\n\t);\n\tconsole.log('');\n\n\t// Get target dimensions\n\tlet targetW = await promptNumber('Width (0 for auto)', 0, 0);\n\tlet targetH = await promptNumber('Height (0 for auto)', 0, 0);\n\n\t// Determine scaling mode\n\tlet makeSquare = false;\n\n\tif (targetW === 0 && targetH === 0) {\n\t\t// Default: scale to 50%\n\t\ttargetW = Math.floor(origW / 2);\n\t\ttargetH = Math.floor(origH / 2);\n\t\tinfo(`Using default: 50% scale (${targetW}x${targetH})`);\n\t} else if (targetW > 0 && targetH === 0) {\n\t\t// Width specified, calculate height\n\t\ttargetH = Math.floor((targetW * origH) / origW);\n\t\tinfo(`Calculated height: ${targetH}`);\n\t} else if (targetW === 0 && targetH > 0) {\n\t\t// Height specified, calculate width\n\t\ttargetW = Math.floor((targetH * origW) / origH);\n\t\tinfo(`Calculated width: ${targetW}`);\n\t}\n\n\t// Ask about square padding\n\tconsole.log('');\n\tmakeSquare = await promptConfirm(\n\t\t'Make output square with transparent padding?',\n\t\tfalse,\n\t);\n\n\tif (makeSquare) {\n\t\tconst maxDim = Math.max(targetW, targetH);\n\t\ttargetW = maxDim;\n\t\ttargetH = maxDim;\n\t\tinfo(`Output will be ${targetW}x${targetH} (square with padding)`);\n\t}\n\n\tconsole.log('');\n\twip('Scaling image...');\n\n\tlet scaled = false;\n\tif (makeSquare) {\n\t\t// Scale and add transparent padding for square output\n\t\tscaled = await scaleWithPadding(input, output, targetW, targetH);\n\t} else {\n\t\t// Standard resize\n\t\tscaled = await resize(input, output, targetW, targetH);\n\t}\n\n\tif (!scaled || !existsSync(output)) {\n\t\twipDone(false, 'Scaling failed');\n\t\treturn false;\n\t}\n\n\t// Get final dimensions\n\tconst finalDims = await getDimensions(output);\n\tif (finalDims) {\n\t\twipDone(true, `Scaled to ${finalDims[0]}x${finalDims[1]}`);\n\t} else {\n\t\twipDone(true, 'Scaled');\n\t}\n\n\tconsole.log('');\n\tsuccess(`Output: ${output}`);\n\treturn true;\n}\n\n/**\n * Scale image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'rescale.html',\n\t\ttitle: 'PicLet - Scale Image',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tmakeSquare: false,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\twidth: (opts.width as number) ?? Math.round(dims[0] / 2),\n\t\t\t\theight: (opts.height as number) ?? Math.round(dims[1] / 2),\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? false,\n\t\t\t};\n\t\t\treturn generatePreview(input, options);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\twidth: (opts.width as number) ?? Math.round(dims[0] / 2),\n\t\t\t\theight: (opts.height as number) ?? Math.round(dims[1] / 2),\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? false,\n\t\t\t};\n\n\t\t\tlogs.push({ type: 'info', message: `Scaling to ${options.width}x${options.height}...` });\n\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_scaled${fileInfo.extension}`;\n\t\t\tlet scaled = false;\n\n\t\t\tif (options.makeSquare) {\n\t\t\t\tconst maxDim = Math.max(options.width, options.height);\n\t\t\t\tscaled = await scaleWithPadding(input, output, maxDim, maxDim);\n\t\t\t} else {\n\t\t\t\tscaled = await resize(input, output, options.width, options.height);\n\t\t\t}\n\n\t\t\tif (scaled && existsSync(output)) {\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\tlogs.push({ type: 'success', message: 'Scaled successfully' });\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Scaling failed' });\n\t\t\treturn { success: false, error: 'Scaling failed', logs };\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\tlet scaled = false;\n\t\tlet targetW = options.width;\n\t\tlet targetH = options.height;\n\n\t\tif (options.makeSquare) {\n\t\t\tconst maxDim = Math.max(targetW, targetH);\n\t\t\ttargetW = maxDim;\n\t\t\ttargetH = maxDim;\n\t\t\tscaled = await scaleWithPadding(input, tempOutput, targetW, targetH);\n\t\t} else {\n\t\t\tscaled = await resize(input, tempOutput, targetW, targetH);\n\t\t}\n\n\t\tif (!scaled || !existsSync(tempOutput)) {\n\t\t\treturn { success: false, error: 'Scaling failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\t\tcleanup(tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'rescale',\n\tname: 'Scale Image',\n\ticon: 'rescale.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],\n};\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { basename, join } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport { error, header, info, success, wip, wipDone } from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tgetDimensions,\n\tresize,\n\tscaleFillCrop,\n\tscaleWithPadding,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { loadPresets, type Preset } from '../lib/presets.js';\nimport { pauseOnError, select as promptSelect } from '../lib/prompts.js';\n\ntype ScaleMode = 'fit' | 'fill' | 'stretch';\n\n/**\n * Scale image using the specified mode\n */\nasync function scaleImage(\n\tinput: string,\n\toutput: string,\n\twidth: number,\n\theight: number,\n\tmode: ScaleMode,\n): Promise<boolean> {\n\tswitch (mode) {\n\t\tcase 'fill':\n\t\t\treturn scaleFillCrop(input, output, width, height);\n\t\tcase 'stretch':\n\t\t\treturn resize(input, output, width, height);\n\t\tcase 'fit':\n\t\tdefault:\n\t\t\treturn scaleWithPadding(input, output, width, height);\n\t}\n}\n\n/**\n * Generate images for a preset\n */\nasync function generatePresetImages(\n\tsourceImg: string,\n\toutputDir: string,\n\tpreset: Preset,\n\tscaleMode: ScaleMode = 'fit',\n\tlogs?: Array<{ type: string; message: string }>,\n): Promise<number> {\n\tlet failed = 0;\n\tconst total = preset.icons.length;\n\n\tfor (let i = 0; i < total; i++) {\n\t\tconst icon = preset.icons[i];\n\t\tconst outputPath = join(outputDir, icon.filename);\n\n\t\tif (logs) {\n\t\t\tlogs.push({ type: 'info', message: `[${i + 1}/${total}] ${icon.filename}` });\n\t\t} else {\n\t\t\twip(`[${i + 1}/${total}] Generating ${icon.filename}...`);\n\t\t}\n\n\t\tconst scaled = await scaleImage(\n\t\t\tsourceImg,\n\t\t\toutputPath,\n\t\t\ticon.width,\n\t\t\ticon.height,\n\t\t\tscaleMode,\n\t\t);\n\n\t\tif (scaled) {\n\t\t\tif (!logs) {\n\t\t\t\twipDone(true, `[${i + 1}/${total}] ${icon.filename} (${icon.width}x${icon.height})`);\n\t\t\t}\n\t\t} else {\n\t\t\tif (logs) {\n\t\t\t\tlogs.push({ type: 'error', message: `Failed: ${icon.filename}` });\n\t\t\t} else {\n\t\t\t\twipDone(false, `[${i + 1}/${total}] Failed: ${icon.filename}`);\n\t\t\t}\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Generate store assets (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\theader('PicLet Store Pack');\n\n\t// Analyze source image\n\twip('Analyzing source image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\twipDone(true, `Source: ${dims[0]}x${dims[1]}`);\n\n\t// Load presets\n\tconst presets = loadPresets();\n\tconst choices = presets.map((p) => ({\n\t\ttitle: p.name,\n\t\tvalue: p.id,\n\t\tdescription: p.description,\n\t}));\n\n\t// Select preset\n\tconsole.log('');\n\tconst selectedId = await promptSelect('Select target store:', choices, presets[0].id);\n\tconst preset = presets.find((p) => p.id === selectedId);\n\n\tif (!preset) {\n\t\terror('Preset not found');\n\t\treturn false;\n\t}\n\n\t// Create output directory\n\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${preset.id}`;\n\tmkdirSync(outputDir, { recursive: true });\n\tinfo(`Output: ${outputDir}`);\n\n\t// Prepare source (make square for consistent scaling)\n\tconsole.log('');\n\twip('Preparing source...');\n\tconst tempSource = join(outputDir, '.source.png');\n\n\tif (!(await squarify(input, tempSource))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\treturn false;\n\t}\n\twipDone(true, 'Source prepared');\n\n\t// Generate images\n\tconsole.log('');\n\theader(`Generating ${preset.name} Images`);\n\n\tconst failed = await generatePresetImages(tempSource, outputDir, preset);\n\tcleanup(tempSource);\n\n\tconsole.log('');\n\tif (failed === 0) {\n\t\tsuccess(`All ${preset.icons.length} images generated!`);\n\t} else {\n\t\terror(`${failed}/${preset.icons.length} images failed`);\n\t}\n\n\tinfo(`Output: ${outputDir}`);\n\treturn failed === 0;\n}\n\n/**\n * Generate store assets (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\tconst presets = loadPresets();\n\n\treturn startGuiServer({\n\t\thtmlFile: 'storepack.html',\n\t\ttitle: 'PicLet - Store Pack',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tpresets: presets.map((p) => ({\n\t\t\t\tid: p.id,\n\t\t\t\tname: p.name,\n\t\t\t\tdescription: p.description,\n\t\t\t\ticons: p.icons,\n\t\t\t})),\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst presetId = opts.preset as string;\n\t\t\tconst scaleMode = (opts.scaleMode as ScaleMode) || 'fit';\n\t\t\tconst preset = presets.find((p) => p.id === presetId);\n\n\t\t\tif (!preset) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'Preset not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'No preset selected' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Create output directory\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${preset.id}`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\t\t\tlogs.push({ type: 'info', message: `Output: ${outputDir}` });\n\t\t\tlogs.push({ type: 'info', message: `Scale mode: ${scaleMode}` });\n\n\t\t\t// Generate images directly from source\n\t\t\tlogs.push({ type: 'info', message: `Generating ${preset.icons.length} images...` });\n\t\t\tconst failed = await generatePresetImages(input, outputDir, preset, scaleMode, logs);\n\n\t\t\tif (failed === 0) {\n\t\t\t\tlogs.push({ type: 'success', message: `All ${preset.icons.length} images generated` });\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${preset.icons.length} images saved to ${fileInfo.filename}_${preset.id}/`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `${failed} image(s) failed`,\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\nexport const config = {\n\tid: 'storepack',\n\tname: 'Store Pack',\n\ticon: 'storepack.ico',\n\textensions: ['.png', '.jpg', '.jpeg'],\n};\n"],"mappings":"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","names":["extname","dirname","join","fileURLToPath","dirname","dirname","error","existsSync","mkdirSync","basename","dirname","dirname","join","fileURLToPath","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","homedir","config","config","writeFileSync","existsSync","readFileSync","existsSync","readFileSync","config","__dirname","dirname","fileURLToPath","resolve","join","exec","existsSync","mkdirSync","dirname","promisify","execAsync","squarify","existsSync","dirname","existsSync","mkdirSync","squarify","basename","existsSync","readFileSync","basename","join","run","existsSync","squarify","join","readFileSync","runGUI","basename","success","config","existsSync","mkdirSync","readFileSync","writeFileSync","tmpdir","basename","dirname","extname","join","tmpdir","join","dims","previewPath","buffer","readFileSync","finalDims","success","squarify","basename","mkdirSync","dirname","runGUI","existsSync","extname","writeFileSync","config","existsSync","readFileSync","renameSync","tmpdir","basename","join","renameSync","squarify","run","existsSync","runGUI","config","basename","generatePreview","success","tmpdir","join","readFileSync","existsSync","readFileSync","tmpdir","basename","join","run","existsSync","runGUI","basename","generatePreview","tmpdir","join","readFileSync","config","existsSync","mkdirSync","basename","join","join","run","existsSync","mkdirSync","runGUI","basename","config","config","run","runGUI","fileURLToPath","dirname","config","success","join","extname","runGUI","error"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/cli/index.ts","../src/lib/banner.ts","../src/cli/commands/config.ts","../src/lib/config.ts","../src/cli/commands/help.ts","../src/cli/commands/iconpack.ts","../src/tools/iconpack.ts","../src/lib/gui-server.ts","../src/lib/presets.ts","../src/lib/logger.ts","../src/lib/magick.ts","../src/lib/paths.ts","../src/lib/prompts.ts","../src/cli/utils.ts","../src/tools/makeicon.ts","../src/tools/piclet-main.ts","../src/tools/remove-bg.ts","../src/tools/rescale.ts","../src/tools/storepack.ts","../src/cli/tools.ts","../src/cli/commands/install.ts","../src/lib/registry.ts","../src/cli/registry.ts","../src/cli/commands/makeicon.ts","../src/cli/commands/piclet.ts","../src/cli/commands/remove-bg.ts","../src/cli/commands/scale.ts","../src/cli/commands/storepack.ts","../src/cli/commands/uninstall.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport chalk from 'chalk';\nimport { createProgram } from './cli/index.js';\n\nconst program = createProgram();\n\nprogram.parseAsync(process.argv).catch((error) => {\n\tconsole.error(chalk.red(`Error: ${error.message}`));\n\tprocess.exit(1);\n});\n","import chalk from 'chalk';\nimport { Command } from 'commander';\nimport { showBanner } from '../lib/banner.js';\nimport { registerConfigCommand } from './commands/config.js';\nimport { registerHelpCommand } from './commands/help.js';\nimport { registerIconpackCommand } from './commands/iconpack.js';\nimport { registerInstallCommand } from './commands/install.js';\nimport { registerMakeiconCommand } from './commands/makeicon.js';\nimport { registerPicletCommand } from './commands/piclet.js';\nimport { registerRemoveBgCommand } from './commands/remove-bg.js';\nimport { registerScaleCommand } from './commands/scale.js';\nimport { registerStorepackCommand } from './commands/storepack.js';\nimport { registerUninstallCommand } from './commands/uninstall.js';\n\nexport function showHelp(): void {\n\tshowBanner();\n\n\tconst dim = chalk.gray;\n\tconst cmd = chalk.cyan;\n\tconst arg = chalk.yellow;\n\tconst opt = chalk.green;\n\tconst head = chalk.white.bold;\n\n\tconsole.log(\n\t\t` ${head('Usage:')} piclet ${cmd('<command>')} ${arg('<file>')} ${opt('[options]')}`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Unified'));\n\tconsole.log(\n\t\t` ${cmd('piclet')} ${arg('<file>')} Open all tools in one window`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Individual Tools'));\n\tconsole.log(\n\t\t` ${cmd('makeicon')} ${arg('<file>')} Convert PNG to multi-resolution ICO`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('remove-bg')} ${arg('<file>')} Remove solid background from image`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('scale')} ${arg('<file>')} Resize image with optional padding`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('iconpack')} ${arg('<file>')} Generate icon sets for Web/Android/iOS`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('storepack')} ${arg('<file>')} Generate assets for app stores`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Setup'));\n\tconsole.log(\n\t\t` ${cmd('install')} Add Windows right-click menu`,\n\t);\n\tconsole.log(` ${cmd('uninstall')} Remove right-click menu`);\n\tconsole.log();\n\tconsole.log(head(' Config'));\n\tconsole.log(` ${cmd('config')} Display current settings`);\n\tconsole.log(` ${cmd('config reset')} Restore defaults`);\n\tconsole.log();\n\tconsole.log(head(' Examples'));\n\tconsole.log(` ${dim('$')} piclet ${cmd('piclet')} ${arg('image.png')} ${dim('# All tools in one window')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('makeicon')} ${arg('logo.png')} ${dim('# Interactive')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('makeicon')} ${arg('*.png')} ${opt('-y')} ${dim('# Batch with defaults')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('remove-bg')} ${arg('photo.png')} ${dim('# Interactive prompts')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('scale')} ${arg('image.jpg')} ${dim('# Interactive resize')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('iconpack')} ${arg('icon.png')} ${opt('-y')} ${dim('# All platforms')}`);\n\tconsole.log();\n\tconsole.log(head(' Requirements'));\n\tconsole.log(' - WSL (Windows Subsystem for Linux)');\n\tconsole.log(' - ImageMagick: sudo apt install imagemagick');\n\tconsole.log();\n}\n\nexport function createProgram(): Command {\n\tconst program = new Command();\n\n\t// Override default help\n\tprogram.helpInformation = () => '';\n\tprogram.on('--help', () => {});\n\n\tprogram\n\t\t.name('piclet')\n\t\t.description('Image manipulation utility toolkit with Windows shell integration')\n\t\t.version('1.0.0')\n\t\t.action(() => {\n\t\t\tshowHelp();\n\t\t});\n\n\t// Register all commands\n\tregisterHelpCommand(program);\n\tregisterInstallCommand(program);\n\tregisterUninstallCommand(program);\n\tregisterMakeiconCommand(program);\n\tregisterRemoveBgCommand(program);\n\tregisterScaleCommand(program);\n\tregisterIconpackCommand(program);\n\tregisterStorepackCommand(program);\n\tregisterPicletCommand(program);\n\tregisterConfigCommand(program);\n\n\treturn program;\n}\n\nexport * from './tools.js';\nexport * from './utils.js';\nexport * from './registry.js';\n","import figlet from 'figlet';\nimport gradient from 'gradient-string';\n\nconst GRADIENT_COLORS = ['#22c55e', '#84cc16', '#eab308', '#fcd34d'];\n\n/**\n * Render the PicLet ASCII art logo with gradient colors\n */\nfunction renderLogo(): string {\n\tconst ascii = figlet.textSync('PicLet', {\n\t\tfont: 'Slant',\n\t\thorizontalLayout: 'default',\n\t});\n\treturn gradient(GRADIENT_COLORS)(ascii);\n}\n\n/**\n * Display the PicLet banner with gradient colors\n */\nexport function showBanner(\n\tsubtitle = 'Image manipulation utility toolkit with Windows shell integration',\n): void {\n\ttry {\n\t\tconsole.log(`\\n${renderLogo()}`);\n\t\tif (subtitle) {\n\t\t\tconst subtleGradient = gradient(['#a8a8a8', '#d4d4d4']);\n\t\t\tconsole.log(subtleGradient(` ${subtitle}\\n`));\n\t\t}\n\t} catch {\n\t\t// Fallback if rendering fails\n\t\tconsole.log('\\n\\x1b[1mPicLet\\x1b[0m');\n\t\tif (subtitle) {\n\t\t\tconsole.log(`\\x1b[2m ${subtitle}\\x1b[0m\\n`);\n\t\t}\n\t}\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { getConfigPath, loadConfig, resetConfig } from '../../lib/config.js';\n\nexport function registerConfigCommand(program: Command): void {\n\tconst configCmd = program\n\t\t.command('config')\n\t\t.description('Display current settings')\n\t\t.action(() => {\n\t\t\tconst config = loadConfig();\n\t\t\tconsole.log(chalk.white.bold('\\n PicLet Configuration'));\n\t\t\tconsole.log(chalk.gray(` ${getConfigPath()}\\n`));\n\t\t\tconsole.log(JSON.stringify(config, null, 2));\n\t\t\tconsole.log();\n\t\t});\n\n\tconfigCmd\n\t\t.command('reset')\n\t\t.description('Restore defaults')\n\t\t.action(() => {\n\t\t\tresetConfig();\n\t\t\tconsole.log(chalk.green('Configuration reset to defaults.'));\n\t\t});\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\n\n/** PicLet configuration */\nexport interface PicLetConfig {\n\tremoveBg: {\n\t\tfuzz: number;\n\t\ttrim: boolean;\n\t\tpreserveInner: boolean;\n\t\tmakeSquare: boolean;\n\t};\n\trescale: {\n\t\tdefaultScale: number;\n\t\tmakeSquare: boolean;\n\t};\n\ticonpack: {\n\t\tplatforms: ('web' | 'android' | 'ios')[];\n\t};\n}\n\n/** Default configuration */\nexport const DEFAULT_CONFIG: PicLetConfig = {\n\tremoveBg: {\n\t\tfuzz: 10,\n\t\ttrim: true,\n\t\tpreserveInner: false,\n\t\tmakeSquare: false,\n\t},\n\trescale: {\n\t\tdefaultScale: 50,\n\t\tmakeSquare: false,\n\t},\n\ticonpack: {\n\t\tplatforms: ['web', 'android', 'ios'],\n\t},\n};\n\n/** Get config directory path */\nfunction getConfigDir(): string {\n\treturn join(homedir(), '.config', 'piclet');\n}\n\n/** Get config file path */\nexport function getConfigPath(): string {\n\treturn join(getConfigDir(), 'config.json');\n}\n\n/** Load configuration from file */\nexport function loadConfig(): PicLetConfig {\n\tconst configPath = getConfigPath();\n\n\tif (!existsSync(configPath)) {\n\t\treturn { ...DEFAULT_CONFIG };\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(configPath, 'utf-8');\n\t\tconst loaded = JSON.parse(content) as Partial<PicLetConfig>;\n\t\treturn {\n\t\t\tremoveBg: { ...DEFAULT_CONFIG.removeBg, ...loaded.removeBg },\n\t\t\trescale: { ...DEFAULT_CONFIG.rescale, ...loaded.rescale },\n\t\t\ticonpack: { ...DEFAULT_CONFIG.iconpack, ...loaded.iconpack },\n\t\t};\n\t} catch {\n\t\treturn { ...DEFAULT_CONFIG };\n\t}\n}\n\n/** Save configuration to file */\nexport function saveConfig(config: PicLetConfig): void {\n\tconst configPath = getConfigPath();\n\tconst configDir = dirname(configPath);\n\n\tif (!existsSync(configDir)) {\n\t\tmkdirSync(configDir, { recursive: true });\n\t}\n\n\twriteFileSync(configPath, JSON.stringify(config, null, 2));\n}\n\n/** Reset configuration to defaults */\nexport function resetConfig(): void {\n\tconst configPath = getConfigPath();\n\tconst configDir = dirname(configPath);\n\n\tif (!existsSync(configDir)) {\n\t\tmkdirSync(configDir, { recursive: true });\n\t}\n\n\twriteFileSync(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2));\n}\n","import type { Command } from 'commander';\nimport { showHelp } from '../index.js';\n\nexport function registerHelpCommand(program: Command): void {\n\tprogram\n\t\t.command('help')\n\t\t.description('Show help')\n\t\t.action(() => {\n\t\t\tshowHelp();\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as iconpack from '../../tools/iconpack.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerIconpackCommand(program: Command): void {\n\tprogram\n\t\t.command('iconpack <files...>')\n\t\t.description('Generate icon sets for Web, Android, iOS')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, iconpack.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await iconpack.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'iconpack',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { basename, dirname } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tDIM,\n\tRESET,\n\tclearLine,\n\terror,\n\theader,\n\tinfo,\n\tseparator,\n\tstep,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tcreateIcoFromMultiple,\n\tgetDimensions,\n\tscaleToSize,\n\tsquarify,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { multiSelect as promptMultiSelect, pauseOnError } from '../lib/prompts.js';\n\n// Icon definitions for each platform\ninterface IconDef {\n\tfilename: string;\n\tsize: number;\n}\n\nconst WEB_ICONS: IconDef[] = [\n\t{ filename: 'favicon-16x16.png', size: 16 },\n\t{ filename: 'favicon-32x32.png', size: 32 },\n\t{ filename: 'favicon-48x48.png', size: 48 },\n\t{ filename: 'apple-touch-icon.png', size: 180 },\n\t{ filename: 'android-chrome-192x192.png', size: 192 },\n\t{ filename: 'android-chrome-512x512.png', size: 512 },\n\t{ filename: 'mstile-150x150.png', size: 150 },\n];\n\nconst ANDROID_ICONS: IconDef[] = [\n\t{ filename: 'mipmap-mdpi/ic_launcher.png', size: 48 },\n\t{ filename: 'mipmap-hdpi/ic_launcher.png', size: 72 },\n\t{ filename: 'mipmap-xhdpi/ic_launcher.png', size: 96 },\n\t{ filename: 'mipmap-xxhdpi/ic_launcher.png', size: 144 },\n\t{ filename: 'mipmap-xxxhdpi/ic_launcher.png', size: 192 },\n\t{ filename: 'playstore-icon.png', size: 512 },\n];\n\nconst IOS_ICONS: IconDef[] = [\n\t// 20pt - Notifications\n\t{ filename: 'AppIcon-20.png', size: 20 },\n\t{ filename: 'AppIcon-20@2x.png', size: 40 },\n\t{ filename: 'AppIcon-20@3x.png', size: 60 },\n\t// 29pt - Settings\n\t{ filename: 'AppIcon-29.png', size: 29 },\n\t{ filename: 'AppIcon-29@2x.png', size: 58 },\n\t{ filename: 'AppIcon-29@3x.png', size: 87 },\n\t// 40pt - Spotlight\n\t{ filename: 'AppIcon-40.png', size: 40 },\n\t{ filename: 'AppIcon-40@2x.png', size: 80 },\n\t{ filename: 'AppIcon-40@3x.png', size: 120 },\n\t// 60pt - iPhone App\n\t{ filename: 'AppIcon-60@2x.png', size: 120 },\n\t{ filename: 'AppIcon-60@3x.png', size: 180 },\n\t// 76pt - iPad App\n\t{ filename: 'AppIcon-76.png', size: 76 },\n\t{ filename: 'AppIcon-76@2x.png', size: 152 },\n\t// 83.5pt - iPad Pro\n\t{ filename: 'AppIcon-83.5@2x.png', size: 167 },\n\t// App Store\n\t{ filename: 'AppIcon-1024.png', size: 1024 },\n];\n\n/**\n * Generate icons for a platform\n */\nasync function generateIcons(\n\toutputDir: string,\n\tsourceImg: string,\n\ticons: IconDef[],\n): Promise<number> {\n\tconst total = icons.length;\n\tlet current = 0;\n\tlet failed = 0;\n\n\tfor (const icon of icons) {\n\t\tcurrent++;\n\t\tconst outputPath = `${outputDir}/${icon.filename}`;\n\n\t\t// Create subdirectory if needed\n\t\tconst subdir = dirname(outputPath);\n\t\tif (!existsSync(subdir)) {\n\t\t\tmkdirSync(subdir, { recursive: true });\n\t\t}\n\n\t\tclearLine();\n\t\twip(`[${current}/${total}] Generating ${icon.filename}...`);\n\n\t\tif (await scaleToSize(sourceImg, outputPath, icon.size)) {\n\t\t\tclearLine();\n\t\t\tsuccess(\n\t\t\t\t`[${current}/${total}] ${icon.filename} (${icon.size}x${icon.size})`,\n\t\t\t);\n\t\t} else {\n\t\t\tclearLine();\n\t\t\terror(`[${current}/${total}] Failed: ${icon.filename}`);\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Generate favicon.ico from multiple sizes\n */\nasync function generateFavicon(\n\toutputDir: string,\n\tsourceImg: string,\n): Promise<boolean> {\n\twip('Generating favicon.ico...');\n\n\tconst temp16 = `${outputDir}/.temp_16.png`;\n\tconst temp32 = `${outputDir}/.temp_32.png`;\n\tconst temp48 = `${outputDir}/.temp_48.png`;\n\n\tawait scaleToSize(sourceImg, temp16, 16);\n\tawait scaleToSize(sourceImg, temp32, 32);\n\tawait scaleToSize(sourceImg, temp48, 48);\n\n\tconst result = await createIcoFromMultiple(\n\t\t[temp16, temp32, temp48],\n\t\t`${outputDir}/favicon.ico`,\n\t);\n\n\tcleanup(temp16, temp32, temp48);\n\n\tif (result) {\n\t\twipDone(true, 'favicon.ico (16, 32, 48)');\n\t\treturn true;\n\t}\n\twipDone(false, 'favicon.ico failed');\n\treturn false;\n}\n\n/**\n * Generate icon sets for Web, Android, iOS platforms\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Get file info\n\tconst fileInfo = getFileInfo(input);\n\n\theader('PicLet Icon Pack Generator');\n\n\t// Analyze source image\n\twip('Analyzing source image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\tconst [origW, origH] = dims;\n\twipDone(true, `Source: ${origW}x${origH}`);\n\n\t// Warn if small source\n\tif (origW < 1024 || origH < 1024) {\n\t\twarn(\n\t\t\t'Source image is smaller than 1024px. Larger images produce better quality.',\n\t\t);\n\t}\n\n\t// Check if square\n\tif (origW !== origH) {\n\t\twarn('Image is not square. Will add transparent padding.');\n\t}\n\n\t// Select platforms\n\tconsole.log('');\n\tconst platforms = await promptMultiSelect<string>(\n\t\t'Select target platforms:',\n\t\t[\n\t\t\t{ title: 'Web (PWA, favicon, apple-touch-icon)', value: 'web' },\n\t\t\t{ title: 'Android (mipmap icons, Play Store)', value: 'android' },\n\t\t\t{ title: 'iOS (App icons, App Store)', value: 'ios' },\n\t\t],\n\t\t['web', 'android', 'ios'], // Default: all platforms\n\t);\n\n\tif (platforms.length === 0) {\n\t\terror('No platforms selected');\n\t\treturn false;\n\t}\n\n\tconst doWeb = platforms.includes('web');\n\tconst doAndroid = platforms.includes('android');\n\tconst doIos = platforms.includes('ios');\n\n\t// Create output directory\n\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\tmkdirSync(outputDir, { recursive: true });\n\tinfo(`Output directory: ${outputDir}`);\n\n\t// Prepare source: make square and scale to 1024px for best quality\n\tconsole.log('');\n\twip('Preparing source image...');\n\tconst tempSource = `${outputDir}/.source_1024.png`;\n\tconst tempSquare = `${outputDir}/.temp_square.png`;\n\n\t// First squarify\n\tif (!(await squarify(input, tempSquare))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\treturn false;\n\t}\n\n\t// Then scale to 1024 for high quality source\n\tif (!(await scaleToSize(tempSquare, tempSource, 1024))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\tcleanup(tempSquare);\n\t\treturn false;\n\t}\n\tcleanup(tempSquare);\n\twipDone(true, 'Prepared 1024x1024 source');\n\n\tlet totalFailed = 0;\n\n\t// Generate Web icons\n\tif (doWeb) {\n\t\tconsole.log('');\n\t\theader('Web Icons');\n\t\tconst webDir = `${outputDir}/web`;\n\t\tmkdirSync(webDir, { recursive: true });\n\n\t\tif (!(await generateFavicon(webDir, tempSource))) {\n\t\t\ttotalFailed++;\n\t\t}\n\n\t\ttotalFailed += await generateIcons(webDir, tempSource, WEB_ICONS);\n\t}\n\n\t// Generate Android icons\n\tif (doAndroid) {\n\t\tconsole.log('');\n\t\theader('Android Icons');\n\t\tconst androidDir = `${outputDir}/android`;\n\t\tmkdirSync(androidDir, { recursive: true });\n\n\t\ttotalFailed += await generateIcons(androidDir, tempSource, ANDROID_ICONS);\n\t}\n\n\t// Generate iOS icons\n\tif (doIos) {\n\t\tconsole.log('');\n\t\theader('iOS Icons');\n\t\tconst iosDir = `${outputDir}/ios`;\n\t\tmkdirSync(iosDir, { recursive: true });\n\n\t\ttotalFailed += await generateIcons(iosDir, tempSource, IOS_ICONS);\n\t}\n\n\t// Cleanup\n\tcleanup(tempSource);\n\n\t// Summary\n\tconsole.log('');\n\tseparator();\n\n\tif (totalFailed === 0) {\n\t\tsuccess('All icons generated successfully!');\n\t} else {\n\t\twarn(`${totalFailed} icon(s) failed to generate`);\n\t}\n\n\tconsole.log('');\n\tinfo(`Icons saved to: ${outputDir}`);\n\n\tif (doWeb) {\n\t\tstep('web/ - Favicon, PWA icons, Apple touch icon');\n\t}\n\tif (doAndroid) {\n\t\tstep('android/ - mipmap folders, Play Store icon');\n\t}\n\tif (doIos) {\n\t\tstep('ios/ - All iOS app icon sizes');\n\t}\n\n\treturn totalFailed === 0;\n}\n\n/**\n * Generate icon pack (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'iconpack.html',\n\t\ttitle: 'PicLet - Icon Pack',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tweb: true,\n\t\t\tandroid: true,\n\t\t\tios: true,\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst doWeb = (opts.web as boolean) ?? true;\n\t\t\tconst doAndroid = (opts.android as boolean) ?? true;\n\t\t\tconst doIos = (opts.ios as boolean) ?? true;\n\n\t\t\tif (!doWeb && !doAndroid && !doIos) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'No platforms selected',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'No platforms selected' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Create output directory\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\t\t\tlogs.push({ type: 'info', message: `Output: ${outputDir}` });\n\n\t\t\t// Prepare source: make square and scale to 1024px\n\t\t\tlogs.push({ type: 'info', message: 'Preparing source image...' });\n\t\t\tconst tempSource = `${outputDir}/.source_1024.png`;\n\t\t\tconst tempSquare = `${outputDir}/.temp_square.png`;\n\n\t\t\tif (!(await squarify(input, tempSquare))) {\n\t\t\t\treturn { success: false, error: 'Failed to prepare source', logs };\n\t\t\t}\n\n\t\t\tif (!(await scaleToSize(tempSquare, tempSource, 1024))) {\n\t\t\t\tcleanup(tempSquare);\n\t\t\t\treturn { success: false, error: 'Failed to prepare source', logs };\n\t\t\t}\n\t\t\tcleanup(tempSquare);\n\t\t\tlogs.push({ type: 'success', message: 'Prepared 1024x1024 source' });\n\n\t\t\tlet totalFailed = 0;\n\n\t\t\t// Generate Web icons\n\t\t\tif (doWeb) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating Web icons...' });\n\t\t\t\tconst webDir = `${outputDir}/web`;\n\t\t\t\tmkdirSync(webDir, { recursive: true });\n\n\t\t\t\tif (!(await generateFaviconSilent(webDir, tempSource))) {\n\t\t\t\t\ttotalFailed++;\n\t\t\t\t}\n\t\t\t\ttotalFailed += await generateIconsSilent(webDir, tempSource, WEB_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `Web: ${WEB_ICONS.length + 1} icons` });\n\t\t\t}\n\n\t\t\t// Generate Android icons\n\t\t\tif (doAndroid) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating Android icons...' });\n\t\t\t\tconst androidDir = `${outputDir}/android`;\n\t\t\t\tmkdirSync(androidDir, { recursive: true });\n\t\t\t\ttotalFailed += await generateIconsSilent(androidDir, tempSource, ANDROID_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `Android: ${ANDROID_ICONS.length} icons` });\n\t\t\t}\n\n\t\t\t// Generate iOS icons\n\t\t\tif (doIos) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating iOS icons...' });\n\t\t\t\tconst iosDir = `${outputDir}/ios`;\n\t\t\t\tmkdirSync(iosDir, { recursive: true });\n\t\t\t\ttotalFailed += await generateIconsSilent(iosDir, tempSource, IOS_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `iOS: ${IOS_ICONS.length} icons` });\n\t\t\t}\n\n\t\t\tcleanup(tempSource);\n\n\t\t\tif (totalFailed === 0) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `Icons saved to ${fileInfo.filename}_icons/`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `${totalFailed} icon(s) failed`,\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Silent version of generateIcons for GUI mode\n */\nasync function generateIconsSilent(\n\toutputDir: string,\n\tsourceImg: string,\n\ticons: IconDef[],\n\t_logs: Array<{ type: string; message: string }>,\n): Promise<number> {\n\tlet failed = 0;\n\n\tfor (const icon of icons) {\n\t\tconst outputPath = `${outputDir}/${icon.filename}`;\n\t\tconst subdir = dirname(outputPath);\n\t\tif (!existsSync(subdir)) {\n\t\t\tmkdirSync(subdir, { recursive: true });\n\t\t}\n\n\t\tif (!(await scaleToSize(sourceImg, outputPath, icon.size))) {\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Silent version of generateFavicon for GUI mode\n */\nasync function generateFaviconSilent(\n\toutputDir: string,\n\tsourceImg: string,\n): Promise<boolean> {\n\tconst temp16 = `${outputDir}/.temp_16.png`;\n\tconst temp32 = `${outputDir}/.temp_32.png`;\n\tconst temp48 = `${outputDir}/.temp_48.png`;\n\n\tawait scaleToSize(sourceImg, temp16, 16);\n\tawait scaleToSize(sourceImg, temp32, 32);\n\tawait scaleToSize(sourceImg, temp48, 48);\n\n\tconst result = await createIcoFromMultiple(\n\t\t[temp16, temp32, temp48],\n\t\t`${outputDir}/favicon.ico`,\n\t);\n\n\tcleanup(temp16, temp32, temp48);\n\treturn result;\n}\n\nexport const config = {\n\tid: 'iconpack',\n\tname: 'Icon Pack',\n\ticon: 'iconpack.ico',\n\textensions: ['.png', '.jpg', '.jpeg'],\n};\n","/**\n * GUI Server - Serves HTML interface and handles API calls\n */\nimport { spawn } from 'node:child_process';\nimport { createServer } from 'node:http';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport express from 'express';\nimport { deletePreset, savePreset, type Preset } from './presets.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Signal the loading HTA to close by creating a temp file\n */\nfunction signalReady(): void {\n\t// Write ready signal to Windows temp directory using PowerShell (no window flash)\n\tspawn('powershell.exe', ['-WindowStyle', 'Hidden', '-Command', 'New-Item -Path $env:TEMP\\\\piclet-ready.tmp -ItemType File -Force | Out-Null'], {\n\t\tstdio: 'ignore',\n\t\twindowsHide: true,\n\t});\n}\n\n/**\n * Open URL in Edge app mode (standalone window without browser UI)\n */\nfunction openAppWindow(url: string): void {\n\t// Use PowerShell with hidden window to launch Edge - prevents terminal flash\n\tspawn('powershell.exe', [\n\t\t'-WindowStyle', 'Hidden',\n\t\t'-Command',\n\t\t`Start-Process msedge -ArgumentList '--app=${url}'`\n\t], {\n\t\tdetached: true,\n\t\tstdio: 'ignore',\n\t\twindowsHide: true,\n\t}).unref();\n\n\t// Signal loading window to close after a brief delay for Edge to appear\n\tsetTimeout(signalReady, 500);\n}\n\nexport interface GuiServerOptions {\n\thtmlFile: string;\n\ttitle: string;\n\timageInfo: {\n\t\tfilePath: string;\n\t\tfileName: string;\n\t\twidth: number;\n\t\theight: number;\n\t\tborderColor: string | null;\n\t};\n\tdefaults: Record<string, unknown>;\n\tonPreview?: (options: Record<string, unknown>) => Promise<{\n\t\tsuccess: boolean;\n\t\timageData?: string; // Base64 data URL\n\t\twidth?: number;\n\t\theight?: number;\n\t\terror?: string;\n\t}>;\n\tonProcess: (options: Record<string, unknown>) => Promise<{\n\t\tsuccess: boolean;\n\t\toutput?: string;\n\t\terror?: string;\n\t\tlogs: Array<{ type: string; message: string }>;\n\t}>;\n\tonLoadImage?: (data: { fileName: string; data: string; mimeType: string }) => Promise<{\n\t\tsuccess: boolean;\n\t\tfilePath?: string;\n\t\tfileName?: string;\n\t\twidth?: number;\n\t\theight?: number;\n\t\tborderColor?: string | null;\n\t\terror?: string;\n\t}>;\n}\n\n/**\n * Start GUI server and open Edge app window\n * Returns a promise that resolves when the window is closed\n */\nexport function startGuiServer(options: GuiServerOptions): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst app = express();\n\t\tapp.use(express.json({ limit: '50mb' })); // Allow large base64 images\n\n\t\t// Handle JSON parse errors\n\t\tapp.use((err: Error, _req: express.Request, res: express.Response, next: express.NextFunction) => {\n\t\t\tif (err instanceof SyntaxError && 'body' in err) {\n\t\t\t\tres.status(400).json({ success: false, error: 'Invalid JSON: ' + err.message });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnext(err);\n\t\t});\n\n\t\tlet processResult: boolean | null = null;\n\t\tlet server: ReturnType<typeof createServer> | null = null;\n\n\t\t// Serve static files (CSS, JS, etc.)\n\t\tconst guiDir = join(__dirname, 'gui');\n\t\tconst iconsDir = join(__dirname, 'icons');\n\t\tapp.use(express.static(guiDir));\n\t\tapp.use('/icons', express.static(iconsDir));\n\n\t\t// Serve favicon from icons directory\n\t\tapp.get('/favicon.ico', (_req, res) => {\n\t\t\tres.sendFile(join(iconsDir, 'banana.ico'));\n\t\t});\n\n\t\t// API: Get image info and defaults\n\t\tapp.get('/api/info', (_req, res) => {\n\t\t\tres.json({\n\t\t\t\tfileName: options.imageInfo.fileName,\n\t\t\t\twidth: options.imageInfo.width,\n\t\t\t\theight: options.imageInfo.height,\n\t\t\t\tborderColor: options.imageInfo.borderColor,\n\t\t\t\tdefaults: options.defaults,\n\t\t\t});\n\t\t});\n\n\t\t// API: Preview image (if supported)\n\t\tapp.post('/api/preview', async (req, res) => {\n\t\t\tif (!options.onPreview) {\n\t\t\t\tres.json({ success: false, error: 'Preview not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await options.onPreview(req.body);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (err as Error).message,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// API: Process image\n\t\tapp.post('/api/process', async (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst result = await options.onProcess(req.body);\n\t\t\t\tprocessResult = result.success;\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tprocessResult = false;\n\t\t\t\tres.json({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (err as Error).message,\n\t\t\t\t\tlogs: [{ type: 'error', message: (err as Error).message }],\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// API: Load new image\n\t\tapp.post('/api/load', async (req, res) => {\n\t\t\tif (!options.onLoadImage) {\n\t\t\t\tres.json({ success: false, error: 'Load not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await options.onLoadImage(req.body);\n\t\t\t\tif (result.success) {\n\t\t\t\t\t// Update current image info\n\t\t\t\t\toptions.imageInfo.filePath = result.filePath!;\n\t\t\t\t\toptions.imageInfo.fileName = result.fileName!;\n\t\t\t\t\toptions.imageInfo.width = result.width!;\n\t\t\t\t\toptions.imageInfo.height = result.height!;\n\t\t\t\t\toptions.imageInfo.borderColor = result.borderColor ?? null;\n\t\t\t\t}\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Cancel/close\n\t\tapp.post('/api/cancel', (_req, res) => {\n\t\t\tprocessResult = false;\n\t\t\tres.json({ ok: true });\n\t\t\tshutdown();\n\t\t});\n\n\t\t// API: Close after completion\n\t\tapp.post('/api/close', (_req, res) => {\n\t\t\tres.json({ ok: true });\n\t\t\tshutdown();\n\t\t});\n\n\t\t// API: Save preset\n\t\tapp.post('/api/save-preset', (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst preset = req.body as Preset;\n\t\t\t\tif (!preset.id || !preset.name || !preset.icons?.length) {\n\t\t\t\t\tres.json({ success: false, error: 'Invalid preset data' });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsavePreset(preset);\n\t\t\t\tres.json({ success: true });\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Delete preset\n\t\tapp.post('/api/delete-preset', (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst { id } = req.body;\n\t\t\t\tif (!id) {\n\t\t\t\t\tres.json({ success: false, error: 'Missing preset ID' });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = deletePreset(id);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Open URL in default browser\n\t\tapp.post('/api/open-url', (req, res) => {\n\t\t\tconst { url } = req.body;\n\t\t\tif (!url || typeof url !== 'string') {\n\t\t\t\tres.json({ success: false, error: 'Missing URL' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Use PowerShell Start-Process which opens in default browser\n\t\t\tspawn('powershell.exe', ['-WindowStyle', 'Hidden', '-Command', `Start-Process '${url}'`], {\n\t\t\t\tdetached: true,\n\t\t\t\tstdio: 'ignore',\n\t\t\t\twindowsHide: true,\n\t\t\t}).unref();\n\t\t\tres.json({ success: true });\n\t\t});\n\n\t\tfunction shutdown() {\n\t\t\tsetTimeout(() => {\n\t\t\t\tserver?.close();\n\t\t\t\tresolve(processResult ?? false);\n\t\t\t}, 100);\n\t\t}\n\n\t\t// Find available port and start\n\t\tserver = createServer(app);\n\t\tserver.listen(0, '127.0.0.1', () => {\n\t\t\tconst addr = server!.address();\n\t\t\tif (typeof addr === 'object' && addr) {\n\t\t\t\tconst port = addr.port;\n\t\t\t\tconst url = `http://127.0.0.1:${port}/${options.htmlFile}`;\n\n\t\t\t\topenAppWindow(url);\n\n\t\t\t\t// Auto-close after 5 minutes of inactivity\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (processResult === null) {\n\t\t\t\t\t\tshutdown();\n\t\t\t\t\t}\n\t\t\t\t}, 5 * 60 * 1000);\n\t\t\t}\n\t\t});\n\n\t\tserver.on('error', (err) => {\n\t\t\tconsole.error('GUI server error:', err.message);\n\t\t\tresolve(false);\n\t\t});\n\t});\n}\n","/**\n * Presets configuration for store icon packs\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\n\n/** Single icon definition in a preset */\nexport interface PresetIcon {\n\tfilename: string;\n\twidth: number;\n\theight: number;\n}\n\n/** A complete preset definition */\nexport interface Preset {\n\tid: string;\n\tname: string;\n\tdescription: string;\n\ticons: PresetIcon[];\n}\n\n/** Presets file structure */\nexport interface PresetsConfig {\n\tversion: number;\n\tpresets: Preset[];\n}\n\n/** Built-in presets */\nconst BUILT_IN_PRESETS: Preset[] = [\n\t// ── Game Asset Stores ──\n\t{\n\t\tid: 'unity-asset',\n\t\tname: 'Unity Asset Store',\n\t\tdescription: 'Unity Asset Store package images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-160.png', width: 160, height: 160 },\n\t\t\t{ filename: 'card-420x280.png', width: 420, height: 280 },\n\t\t\t{ filename: 'cover-1200x630.png', width: 1200, height: 630 },\n\t\t\t{ filename: 'screenshot-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'unreal-fab',\n\t\tname: 'Unreal / Fab',\n\t\tdescription: 'Unreal Marketplace & Fab assets',\n\t\ticons: [\n\t\t\t{ filename: 'icon-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'thumbnail-284.png', width: 284, height: 284 },\n\t\t\t{ filename: 'featured-894x488.png', width: 894, height: 488 },\n\t\t\t{ filename: 'gallery-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'godot-asset',\n\t\tname: 'Godot Asset Library',\n\t\tdescription: 'Godot Asset Library images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-64.png', width: 64, height: 64 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'screenshot-1280x720.png', width: 1280, height: 720 },\n\t\t\t{ filename: 'screenshot-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'blender-market',\n\t\tname: 'Blender Market',\n\t\tdescription: 'Blender Market product images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'thumbnail-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'preview-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'steam',\n\t\tname: 'Steam',\n\t\tdescription: 'Steam store assets',\n\t\ticons: [\n\t\t\t{ filename: 'capsule-small-231x87.png', width: 231, height: 87 },\n\t\t\t{ filename: 'capsule-main-616x353.png', width: 616, height: 353 },\n\t\t\t{ filename: 'header-460x215.png', width: 460, height: 215 },\n\t\t\t{ filename: 'hero-1920x620.png', width: 1920, height: 620 },\n\t\t\t{ filename: 'library-capsule-600x900.png', width: 600, height: 900 },\n\t\t\t{ filename: 'library-hero-3840x1240.png', width: 3840, height: 1240 },\n\t\t],\n\t},\n\t{\n\t\tid: 'itch-io',\n\t\tname: 'itch.io',\n\t\tdescription: 'itch.io game page assets',\n\t\ticons: [\n\t\t\t{ filename: 'cover-630x500.png', width: 630, height: 500 },\n\t\t\t{ filename: 'thumbnail-315x250.png', width: 315, height: 250 },\n\t\t\t{ filename: 'banner-960x540.png', width: 960, height: 540 },\n\t\t],\n\t},\n\t// ── Extensions & Packages ──\n\t{\n\t\tid: 'chrome-extension',\n\t\tname: 'Chrome Extension',\n\t\tdescription: 'Chrome Web Store extension icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-16.png', width: 16, height: 16 },\n\t\t\t{ filename: 'icon-32.png', width: 32, height: 32 },\n\t\t\t{ filename: 'icon-48.png', width: 48, height: 48 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'promo-440x280.png', width: 440, height: 280 },\n\t\t\t{ filename: 'promo-1400x560.png', width: 1400, height: 560 },\n\t\t],\n\t},\n\t{\n\t\tid: 'firefox-addon',\n\t\tname: 'Firefox Add-on',\n\t\tdescription: 'Firefox Add-ons icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-48.png', width: 48, height: 48 },\n\t\t\t{ filename: 'icon-96.png', width: 96, height: 96 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t],\n\t},\n\t{\n\t\tid: 'vscode-extension',\n\t\tname: 'VS Code Extension',\n\t\tdescription: 'VS Code Marketplace icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'icon-256.png', width: 256, height: 256 },\n\t\t],\n\t},\n\t{\n\t\tid: 'npm-package',\n\t\tname: 'npm Package',\n\t\tdescription: 'npm package icons',\n\t\ticons: [\n\t\t\t{ filename: 'logo-64.png', width: 64, height: 64 },\n\t\t\t{ filename: 'logo-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'logo-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'banner-1200x600.png', width: 1200, height: 600 },\n\t\t],\n\t},\n\t{\n\t\tid: 'windows-store',\n\t\tname: 'Windows Store',\n\t\tdescription: 'Microsoft Store app icons',\n\t\ticons: [\n\t\t\t{ filename: 'Square44x44Logo.png', width: 44, height: 44 },\n\t\t\t{ filename: 'Square150x150Logo.png', width: 150, height: 150 },\n\t\t\t{ filename: 'Square310x310Logo.png', width: 310, height: 310 },\n\t\t\t{ filename: 'Wide310x150Logo.png', width: 310, height: 150 },\n\t\t\t{ filename: 'StoreLogo-50.png', width: 50, height: 50 },\n\t\t\t{ filename: 'SplashScreen-620x300.png', width: 620, height: 300 },\n\t\t],\n\t},\n];\n\n/** Get presets file path */\nexport function getPresetsPath(): string {\n\tconst picletDir = join(homedir(), '.piclet');\n\treturn join(picletDir, 'presets.json');\n}\n\n/** Ensure presets directory exists */\nfunction ensurePresetsDir(): void {\n\tconst presetsPath = getPresetsPath();\n\tconst dir = dirname(presetsPath);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n}\n\n/** Load presets (built-in + user-defined) */\nexport function loadPresets(): Preset[] {\n\tconst presetsPath = getPresetsPath();\n\tlet userPresets: Preset[] = [];\n\n\tif (existsSync(presetsPath)) {\n\t\ttry {\n\t\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\t\tuserPresets = config.presets || [];\n\t\t} catch {\n\t\t\t// Ignore parse errors, use built-in only\n\t\t}\n\t}\n\n\t// Merge: built-in first, then user presets (user can override built-in by ID)\n\tconst presetMap = new Map<string, Preset>();\n\tfor (const preset of BUILT_IN_PRESETS) {\n\t\tpresetMap.set(preset.id, preset);\n\t}\n\tfor (const preset of userPresets) {\n\t\tpresetMap.set(preset.id, preset);\n\t}\n\n\treturn Array.from(presetMap.values());\n}\n\n/** Get a single preset by ID */\nexport function getPreset(id: string): Preset | undefined {\n\tconst presets = loadPresets();\n\treturn presets.find((p) => p.id === id);\n}\n\n/** Save user presets */\nexport function savePresets(presets: Preset[]): void {\n\tensurePresetsDir();\n\tconst config: PresetsConfig = {\n\t\tversion: 1,\n\t\tpresets,\n\t};\n\twriteFileSync(getPresetsPath(), JSON.stringify(config, null, 2));\n}\n\n/** Add or update a preset */\nexport function savePreset(preset: Preset): void {\n\tconst presetsPath = getPresetsPath();\n\tlet userPresets: Preset[] = [];\n\n\tif (existsSync(presetsPath)) {\n\t\ttry {\n\t\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\t\tuserPresets = config.presets || [];\n\t\t} catch {\n\t\t\t// Start fresh\n\t\t}\n\t}\n\n\t// Update or add\n\tconst idx = userPresets.findIndex((p) => p.id === preset.id);\n\tif (idx >= 0) {\n\t\tuserPresets[idx] = preset;\n\t} else {\n\t\tuserPresets.push(preset);\n\t}\n\n\tsavePresets(userPresets);\n}\n\n/** Get built-in preset IDs (for UI distinction) */\nexport function getBuiltInPresetIds(): string[] {\n\treturn BUILT_IN_PRESETS.map((p) => p.id);\n}\n\n/** Delete a user-defined preset by ID */\nexport function deletePreset(id: string): { success: boolean; error?: string } {\n\t// Cannot delete built-in presets\n\tif (BUILT_IN_PRESETS.some((p) => p.id === id)) {\n\t\treturn { success: false, error: 'Cannot delete built-in presets' };\n\t}\n\n\tconst presetsPath = getPresetsPath();\n\tif (!existsSync(presetsPath)) {\n\t\treturn { success: false, error: 'Preset not found' };\n\t}\n\n\ttry {\n\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\tconst userPresets = config.presets || [];\n\n\t\tconst idx = userPresets.findIndex((p) => p.id === id);\n\t\tif (idx < 0) {\n\t\t\treturn { success: false, error: 'Preset not found' };\n\t\t}\n\n\t\tuserPresets.splice(idx, 1);\n\t\tsavePresets(userPresets);\n\t\treturn { success: true };\n\t} catch {\n\t\treturn { success: false, error: 'Failed to delete preset' };\n\t}\n}\n","/**\n * Colored console output utilities\n */\n\n// ANSI color codes\nconst RED = '\\x1b[31m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst BLUE = '\\x1b[34m';\nconst CYAN = '\\x1b[36m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\n\n// Status symbols\nconst CHECK = '✓';\nconst CROSS = '✗';\nconst ARROW = '→';\nconst BULLET = '•';\nconst SPINNER = '⠋';\n\n/** Print success message with checkmark */\nexport function success(message: string): void {\n\tconsole.log(`${GREEN}${CHECK}${RESET} ${message}`);\n}\n\n/** Print error message with X */\nexport function error(message: string): void {\n\tconsole.log(`${RED}${CROSS}${RESET} ${message}`);\n}\n\n/** Print warning message */\nexport function warn(message: string): void {\n\tconsole.log(`${YELLOW}${BULLET}${RESET} ${message}`);\n}\n\n/** Print info message */\nexport function info(message: string): void {\n\tconsole.log(`${BLUE}${ARROW}${RESET} ${message}`);\n}\n\n/** Print step message (for multi-step processes) */\nexport function step(message: string): void {\n\tconsole.log(`${CYAN}${BULLET}${RESET} ${message}`);\n}\n\n/** Print header with separator */\nexport function header(title: string): void {\n\tconsole.log('');\n\tconsole.log(`${BOLD}${title}${RESET}`);\n\tconsole.log(`${DIM}${'─'.repeat(40)}${RESET}`);\n}\n\n/** Print separator line */\nexport function separator(): void {\n\tconsole.log(`${DIM}${'─'.repeat(40)}${RESET}`);\n}\n\n/** Work-in-progress indicator (inline, no newline) */\nexport function wip(message: string): void {\n\tprocess.stdout.write(`${YELLOW}${SPINNER}${RESET} ${message}`);\n}\n\n/** Complete a WIP indicator with result */\nexport function wipDone(isSuccess: boolean, message: string): void {\n\t// Clear line and print result\n\tprocess.stdout.write('\\r\\x1b[K');\n\tif (isSuccess) {\n\t\tsuccess(message);\n\t} else {\n\t\terror(message);\n\t}\n}\n\n/** Clear current line */\nexport function clearLine(): void {\n\tprocess.stdout.write('\\r\\x1b[K');\n}\n\nexport { RESET, BOLD, DIM, GREEN, RED, YELLOW, BLUE, CYAN };\n","import { exec } from 'node:child_process';\nimport { copyFileSync, existsSync, mkdirSync, unlinkSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\n/**\n * Get input path with frame selector for multi-frame formats (ICO, GIF)\n * ICO files contain multiple resolutions - [0] selects the largest\n */\nfunction getInputSelector(imagePath: string): string {\n\tconst lowerPath = imagePath.toLowerCase();\n\tif (lowerPath.endsWith('.ico')) {\n\t\treturn `\"${imagePath}[0]\"`;\n\t}\n\treturn `\"${imagePath}\"`;\n}\n\n/**\n * Check if ImageMagick is installed\n */\nexport async function checkImageMagick(): Promise<boolean> {\n\ttry {\n\t\tawait execAsync('command -v convert');\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get image dimensions\n * Returns [width, height] or null on error\n */\nexport async function getDimensions(\n\timagePath: string,\n): Promise<[number, number] | null> {\n\ttry {\n\t\tconst input = getInputSelector(imagePath);\n\t\tconst { stdout } = await execAsync(\n\t\t\t`convert ${input} -ping -format \"%w %h\" info:`,\n\t\t);\n\t\tconst [w, h] = stdout.trim().split(' ').map(Number);\n\t\tif (Number.isNaN(w) || Number.isNaN(h)) return null;\n\t\treturn [w, h];\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Get border color (samples top-left pixel)\n */\nexport async function getBorderColor(\n\timagePath: string,\n): Promise<string | null> {\n\ttry {\n\t\tconst input = getInputSelector(imagePath);\n\t\tconst { stdout } = await execAsync(\n\t\t\t`convert ${input} -format \"%[pixel:u.p{0,0}]\" info:`,\n\t\t);\n\t\treturn stdout.trim();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Trim transparent/whitespace edges from image\n */\nexport async function trim(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst input = getInputSelector(inputPath);\n\t\tawait execAsync(`convert ${input} -trim +repage \"${outputPath}\"`);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Make image square by adding transparent padding\n */\nexport async function squarify(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\tconst dims = await getDimensions(inputPath);\n\tif (!dims) return false;\n\n\tconst [width, height] = dims;\n\n\t// Already square - just copy\n\tif (width === height) {\n\t\tif (inputPath !== outputPath) {\n\t\t\tcopyFileSync(inputPath, outputPath);\n\t\t}\n\t\treturn true;\n\t}\n\n\tconst size = Math.max(width, height);\n\tconst input = getInputSelector(inputPath);\n\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert ${input} -background none -gravity center -extent ${size}x${size} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to specific size with transparent padding\n */\nexport async function scaleToSize(\n\tinputPath: string,\n\toutputPath: string,\n\tsize: number,\n): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -resize ${size}x${size} -background none -gravity center -extent ${size}x${size} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image with custom dimensions and padding\n */\nexport async function scaleWithPadding(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -resize ${width}x${height} -background none -gravity center -extent ${width}x${height} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to exact dimensions (may distort)\n */\nexport async function resize(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -resize ${width}x${height}! \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to fill area and crop to exact size (cover mode)\n */\nexport async function scaleFillCrop(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -resize ${width}x${height}^ -background none -gravity center -extent ${width}x${height} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Remove background color from image\n */\nexport async function removeBackground(\n\tinputPath: string,\n\toutputPath: string,\n\tcolor: string,\n\tfuzz: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst input = getInputSelector(inputPath);\n\t\tawait execAsync(\n\t\t\t`convert ${input} -fuzz ${fuzz}% -transparent \"${color}\" \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Remove background using flood-fill from edges only\n */\nexport async function removeBackgroundBorderOnly(\n\tinputPath: string,\n\toutputPath: string,\n\tcolor: string,\n\tfuzz: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst input = getInputSelector(inputPath);\n\t\tawait execAsync(\n\t\t\t`convert ${input} -bordercolor \"${color}\" -border 1x1 -fill none -fuzz ${fuzz}% -draw \"matte 0,0 floodfill\" -shave 1x1 \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Create ICO file with multiple resolutions\n */\nexport async function createIco(\n\tinputPath: string,\n\toutputPath: string,\n\tsizes: number[] = [256, 128, 64, 48, 32, 16],\n): Promise<boolean> {\n\ttry {\n\t\tconst sizeStr = sizes.join(',');\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -define icon:auto-resize=${sizeStr} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Create ICO from multiple PNG files\n */\nexport async function createIcoFromMultiple(\n\tpngPaths: string[],\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst inputs = pngPaths.map((p) => `\"${p}\"`).join(' ');\n\t\tawait execAsync(`convert ${inputs} \"${outputPath}\"`);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Ensure output directory exists\n */\nexport function ensureDir(filePath: string): void {\n\tconst dir = dirname(filePath);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n}\n\n/**\n * Clean up temporary files\n */\nexport function cleanup(...files: string[]): void {\n\tfor (const file of files) {\n\t\ttry {\n\t\t\tif (existsSync(file)) {\n\t\t\t\tunlinkSync(file);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t}\n}\n","import { basename, dirname, extname, resolve } from 'node:path';\n\n/**\n * Convert Windows path to WSL path\n * C:\\Users\\... → /mnt/c/Users/...\n */\nexport function windowsToWsl(winPath: string): string {\n\t// Already a WSL path\n\tif (winPath.startsWith('/mnt/')) {\n\t\treturn winPath;\n\t}\n\n\t// Windows path pattern: C:\\... or C:/...\n\tconst match = winPath.match(/^([A-Za-z]):[/\\\\](.*)$/);\n\tif (match) {\n\t\tconst drive = match[1].toLowerCase();\n\t\tconst rest = match[2].replace(/\\\\/g, '/');\n\t\treturn `/mnt/${drive}/${rest}`;\n\t}\n\n\treturn winPath;\n}\n\n/**\n * Convert WSL path to Windows path\n * /mnt/c/Users/... → C:\\Users\\...\n */\nexport function wslToWindows(wslPath: string): string {\n\tconst match = wslPath.match(/^\\/mnt\\/([a-z])\\/(.*)$/i);\n\tif (match) {\n\t\tconst drive = match[1].toUpperCase();\n\t\tconst rest = match[2].replace(/\\//g, '\\\\');\n\t\treturn `${drive}:\\\\${rest}`;\n\t}\n\treturn wslPath;\n}\n\n/**\n * Normalize a path - convert Windows paths if needed, resolve relative paths\n */\nexport function normalizePath(inputPath: string): string {\n\tif (/^[A-Za-z]:[/\\\\]/.test(inputPath)) {\n\t\treturn windowsToWsl(inputPath);\n\t}\n\treturn resolve(inputPath);\n}\n\n/**\n * Get file info from a path\n */\nexport interface FileInfo {\n\tdirname: string;\n\tbasename: string;\n\tfilename: string;\n\textension: string;\n}\n\nexport function getFileInfo(filePath: string): FileInfo {\n\tconst dir = dirname(filePath);\n\tconst base = basename(filePath);\n\tconst ext = extname(filePath);\n\tconst name = base.slice(0, -ext.length);\n\n\treturn {\n\t\tdirname: dir,\n\t\tbasename: base,\n\t\tfilename: name,\n\t\textension: ext,\n\t};\n}\n\n/**\n * Generate output path with suffix\n */\nexport function getOutputPath(\n\tinputPath: string,\n\tsuffix: string,\n\tnewExtension?: string,\n): string {\n\tconst info = getFileInfo(inputPath);\n\tconst ext = newExtension ?? info.extension;\n\treturn `${info.dirname}/${info.filename}${suffix}${ext}`;\n}\n","import prompts from 'prompts';\n\n/** When true, all prompts return their default values without user interaction */\nlet useDefaults = false;\n\n/** Override values from CLI arguments - keyed by prompt message substring */\nconst overrides: Record<string, string | number | boolean | string[]> = {};\n\n/**\n * Enable or disable default mode (for --yes flag)\n */\nexport function setUseDefaults(value: boolean): void {\n\tuseDefaults = value;\n}\n\n/**\n * Check if defaults mode is enabled\n */\nexport function isUsingDefaults(): boolean {\n\treturn useDefaults;\n}\n\n/**\n * Set override values from CLI arguments\n */\nexport function setOverrides(values: Record<string, string | number | boolean | string[]>): void {\n\tObject.assign(overrides, values);\n}\n\n/**\n * Clear all overrides\n */\nexport function clearOverrides(): void {\n\tfor (const key of Object.keys(overrides)) {\n\t\tdelete overrides[key];\n\t}\n}\n\n/**\n * Get override value for a prompt message (matches substring)\n */\nfunction getOverride(message: string): string | number | boolean | string[] | undefined {\n\tconst msgLower = message.toLowerCase();\n\tfor (const [key, value] of Object.entries(overrides)) {\n\t\tif (msgLower.includes(key.toLowerCase())) {\n\t\t\treturn value;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Prompt for text input with optional default\n */\nexport async function text(\n\tmessage: string,\n\tdefaultValue?: string,\n): Promise<string> {\n\tif (useDefaults) return defaultValue ?? '';\n\n\tconst response = await prompts({\n\t\ttype: 'text',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t});\n\treturn response.value ?? defaultValue ?? '';\n}\n\n/**\n * Prompt for number input with optional default\n */\nexport async function number(\n\tmessage: string,\n\tdefaultValue?: number,\n\tmin?: number,\n\tmax?: number,\n): Promise<number> {\n\tconst override = getOverride(message);\n\tif (override !== undefined) return Number(override);\n\tif (useDefaults) return defaultValue ?? 0;\n\n\tconst response = await prompts({\n\t\ttype: 'number',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t\tmin,\n\t\tmax,\n\t});\n\treturn response.value ?? defaultValue ?? 0;\n}\n\n/**\n * Prompt for yes/no confirmation\n */\nexport async function confirm(\n\tmessage: string,\n\tdefaultValue = true,\n): Promise<boolean> {\n\tconst override = getOverride(message);\n\tif (override !== undefined) return Boolean(override);\n\tif (useDefaults) return defaultValue;\n\n\tconst response = await prompts({\n\t\ttype: 'confirm',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t});\n\treturn response.value ?? defaultValue;\n}\n\n/**\n * Single-select from options\n */\nexport interface SelectOption {\n\ttitle: string;\n\tvalue: string | number;\n\tdescription?: string;\n}\n\nexport async function select<T extends string | number>(\n\tmessage: string,\n\toptions: SelectOption[],\n\tdefaultValue?: T,\n): Promise<T | null> {\n\tif (useDefaults) return defaultValue ?? (options[0]?.value as T) ?? null;\n\n\tconst response = await prompts({\n\t\ttype: 'select',\n\t\tname: 'value',\n\t\tmessage,\n\t\tchoices: options.map((opt) => ({\n\t\t\ttitle: opt.title,\n\t\t\tvalue: opt.value,\n\t\t\tdescription: opt.description,\n\t\t})),\n\t});\n\treturn (response.value as T) ?? null;\n}\n\n/**\n * Multi-select from options\n */\nexport async function multiSelect<T extends string | number>(\n\tmessage: string,\n\toptions: SelectOption[],\n\tdefaultValues?: T[],\n): Promise<T[]> {\n\tif (useDefaults) return defaultValues ?? [];\n\n\tconst response = await prompts({\n\t\ttype: 'multiselect',\n\t\tname: 'value',\n\t\tmessage,\n\t\tchoices: options.map((opt) => ({\n\t\t\ttitle: opt.title,\n\t\t\tvalue: opt.value,\n\t\t\tdescription: opt.description,\n\t\t})),\n\t\tinstructions: false,\n\t\thint: '- Space to select, Enter to confirm',\n\t});\n\treturn (response.value as T[]) ?? [];\n}\n\n/**\n * Handle Ctrl+C gracefully\n */\nexport function onCancel(): void {\n\tprompts.override({ value: undefined });\n}\n\n// Set up cancel handler\nprompts.override({});\n\n/**\n * Pause and wait for user to press Enter (useful for errors in batch mode)\n * Only pauses when running with -y flag so user can see error messages\n */\nexport async function pauseOnError(message = 'Press Enter to close...'): Promise<void> {\n\tif (!useDefaults) return; // Interactive mode - no need to pause\n\n\tconsole.log();\n\tawait prompts({\n\t\ttype: 'text',\n\t\tname: 'value',\n\t\tmessage,\n\t});\n}\n","import { extname } from 'node:path';\nimport { dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport chalk from 'chalk';\nimport { setUseDefaults } from '../lib/prompts.js';\nimport { getTool } from './tools.js';\n\n/** Get dist directory (where cli.js lives after bundling) */\nexport function getDistDir(): string {\n\tconst currentFile = fileURLToPath(import.meta.url);\n\t// tsup bundles everything into dist/cli.js, so dirname gives dist/\n\treturn dirname(currentFile);\n}\n\n/** Get registry base path for PicLet menu on an extension */\nexport function getMenuBasePath(extension: string): string {\n\treturn `HKCU\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n}\n\n/** Validate files have correct extensions for the tool */\nexport function validateExtensions(\n\tfiles: string[],\n\tallowedExtensions: string[],\n): { valid: string[]; invalid: string[] } {\n\tconst valid: string[] = [];\n\tconst invalid: string[] = [];\n\n\tfor (const file of files) {\n\t\tconst ext = extname(file).toLowerCase();\n\t\tif (allowedExtensions.includes(ext)) {\n\t\t\tvalid.push(file);\n\t\t} else {\n\t\t\tinvalid.push(file);\n\t\t}\n\t}\n\n\treturn { valid, invalid };\n}\n\n/** Run tool on multiple files */\nexport async function runToolOnFiles(\n\ttoolId: string,\n\tfiles: string[],\n\tuseYes: boolean,\n): Promise<boolean> {\n\tconst tool = getTool(toolId);\n\tif (!tool) {\n\t\tconsole.error(chalk.red(`Tool not found: ${toolId}`));\n\t\treturn false;\n\t}\n\n\t// Validate extensions\n\tconst { valid, invalid } = validateExtensions(files, tool.config.extensions);\n\n\tif (invalid.length > 0) {\n\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\tfor (const file of invalid) {\n\t\t\tconsole.error(chalk.red(` ✗ ${file}`));\n\t\t}\n\t\tconsole.error(\n\t\t\tchalk.yellow(\n\t\t\t\t`\\nSupported extensions: ${tool.config.extensions.join(', ')}`,\n\t\t\t),\n\t\t);\n\t\tif (valid.length === 0) return false;\n\t\tconsole.log();\n\t}\n\n\t// Enable defaults mode if --yes flag or multiple files\n\tif (useYes || valid.length > 1) {\n\t\tsetUseDefaults(true);\n\t}\n\n\t// Process files\n\tlet allSuccess = true;\n\tfor (let i = 0; i < valid.length; i++) {\n\t\tconst file = valid[i];\n\t\tif (valid.length > 1) {\n\t\t\tconsole.log(chalk.cyan(`\\n[${i + 1}/${valid.length}] ${file}`));\n\t\t}\n\t\tconst success = await tool.run(file);\n\t\tif (!success) allSuccess = false;\n\t}\n\n\treturn allSuccess;\n}\n","import { existsSync, readFileSync } from 'node:fs';\r\nimport { tmpdir } from 'node:os';\r\nimport { basename, join } from 'node:path';\r\nimport { startGuiServer } from '../lib/gui-server.js';\r\nimport { error, header, success, wip, wipDone } from '../lib/logger.js';\r\nimport {\r\n\tcheckImageMagick,\r\n\tcleanup,\r\n\tcreateIco,\r\n\tgetDimensions,\r\n\tscaleToSize,\r\n\tsquarify,\r\n\ttrim,\r\n} from '../lib/magick.js';\r\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\r\nimport { pauseOnError } from '../lib/prompts.js';\r\n\r\n/** Processing options for makeicon */\r\ninterface ProcessOptions {\r\n\ttrim: boolean;\r\n\tmakeSquare: boolean;\r\n}\r\n\r\n/**\r\n * Convert PNG to ICO with multiple resolutions\r\n */\r\nexport async function run(inputRaw: string): Promise<boolean> {\r\n\t// Check dependencies\r\n\tif (!(await checkImageMagick())) {\r\n\t\terror('ImageMagick not found. Please install it:');\r\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\r\n\t\tawait pauseOnError();\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Normalize path\r\n\tconst input = normalizePath(inputRaw);\r\n\r\n\tif (!existsSync(input)) {\r\n\t\terror(`File not found: ${input}`);\r\n\t\tawait pauseOnError();\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Get file info\r\n\tconst fileInfo = getFileInfo(input);\r\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\r\n\tconst tempTrimmed = `${fileInfo.dirname}/${fileInfo.filename}_trimmed.png`;\r\n\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square.png`;\r\n\tconst tempScaled = `${fileInfo.dirname}/${fileInfo.filename}_scaled.png`;\r\n\r\n\theader('PicLet Make Icon');\r\n\r\n\t// Get original dimensions\r\n\twip('Analyzing image...');\r\n\tconst dims = await getDimensions(input);\r\n\tif (!dims) {\r\n\t\twipDone(false, 'Failed to read image');\r\n\t\treturn false;\r\n\t}\r\n\twipDone(true, `Original size: ${dims[0]}x${dims[1]}`);\r\n\r\n\t// Step 1: Trim transparent areas\r\n\twip('Trimming transparent areas...');\r\n\tif (!(await trim(input, tempTrimmed))) {\r\n\t\twipDone(false, 'Trim failed');\r\n\t\tcleanup(tempTrimmed);\r\n\t\treturn false;\r\n\t}\r\n\twipDone(true, 'Trimmed');\r\n\r\n\t// Step 2: Make square\r\n\twip('Making square...');\r\n\tif (!(await squarify(tempTrimmed, tempSquare))) {\r\n\t\twipDone(false, 'Square padding failed');\r\n\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempTrimmed);\r\n\twipDone(true, 'Made square');\r\n\r\n\t// Step 3: Scale to 512px for best quality source\r\n\twip('Scaling to 512px...');\r\n\tif (!(await scaleToSize(tempSquare, tempScaled, 512))) {\r\n\t\twipDone(false, 'Scaling failed');\r\n\t\tcleanup(tempSquare, tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempSquare);\r\n\twipDone(true, 'Scaled to 512x512');\r\n\r\n\t// Step 4: Create ICO with multiple resolutions\r\n\twip('Creating icon (256, 128, 64, 48, 32, 16)...');\r\n\tif (!(await createIco(tempScaled, output))) {\r\n\t\twipDone(false, 'Icon creation failed');\r\n\t\tcleanup(tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempScaled);\r\n\twipDone(true, 'Icon created');\r\n\r\n\tconsole.log('');\r\n\tsuccess(`Output: ${output}`);\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * Process image for icon creation (shared logic)\r\n */\r\nasync function processForIcon(\r\n\tinput: string,\r\n\toutput: string,\r\n\toptions: ProcessOptions,\r\n\tlogs?: Array<{ type: string; message: string }>,\r\n): Promise<boolean> {\r\n\tconst fileInfo = getFileInfo(input);\r\n\tconst tempTrimmed = `${fileInfo.dirname}/${fileInfo.filename}_trimmed.png`;\r\n\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square.png`;\r\n\tconst tempScaled = `${fileInfo.dirname}/${fileInfo.filename}_scaled.png`;\r\n\r\n\tlet currentInput = input;\r\n\r\n\t// Step 1: Trim (optional)\r\n\tif (options.trim) {\r\n\t\tlogs?.push({ type: 'info', message: 'Trimming transparent areas...' });\r\n\t\tif (!(await trim(currentInput, tempTrimmed))) {\r\n\t\t\tcleanup(tempTrimmed);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tcurrentInput = tempTrimmed;\r\n\t\tlogs?.push({ type: 'success', message: 'Trimmed' });\r\n\t}\r\n\r\n\t// Step 2: Squarify (optional)\r\n\tif (options.makeSquare) {\r\n\t\tlogs?.push({ type: 'info', message: 'Making square...' });\r\n\t\tif (!(await squarify(currentInput, tempSquare))) {\r\n\t\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tif (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\t\tcurrentInput = tempSquare;\r\n\t\tlogs?.push({ type: 'success', message: 'Made square' });\r\n\t}\r\n\r\n\t// Step 3: Scale to 512px\r\n\tlogs?.push({ type: 'info', message: 'Scaling to 512px...' });\r\n\tif (!(await scaleToSize(currentInput, tempScaled, 512))) {\r\n\t\tcleanup(tempTrimmed, tempSquare, tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tif (currentInput === tempSquare) cleanup(tempSquare);\r\n\telse if (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\tlogs?.push({ type: 'success', message: 'Scaled to 512x512' });\r\n\r\n\t// Step 4: Create ICO\r\n\tlogs?.push({ type: 'info', message: 'Creating icon (256, 128, 64, 48, 32, 16)...' });\r\n\tif (!(await createIco(tempScaled, output))) {\r\n\t\tcleanup(tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempScaled);\r\n\tlogs?.push({ type: 'success', message: 'Icon created' });\r\n\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * Generate preview image as base64 data URL\r\n */\r\nasync function generatePreview(\r\n\tinput: string,\r\n\toptions: ProcessOptions,\r\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\r\n\tconst tempDir = tmpdir();\r\n\tconst timestamp = Date.now();\r\n\tconst tempTrimmed = join(tempDir, `piclet-preview-trimmed-${timestamp}.png`);\r\n\tconst tempSquare = join(tempDir, `piclet-preview-square-${timestamp}.png`);\r\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\r\n\r\n\ttry {\r\n\t\tlet currentInput = input;\r\n\r\n\t\t// Trim if enabled\r\n\t\tif (options.trim) {\r\n\t\t\tif (!(await trim(currentInput, tempTrimmed))) {\r\n\t\t\t\tcleanup(tempTrimmed);\r\n\t\t\t\treturn { success: false, error: 'Trim failed' };\r\n\t\t\t}\r\n\t\t\tcurrentInput = tempTrimmed;\r\n\t\t}\r\n\r\n\t\t// Squarify if enabled\r\n\t\tif (options.makeSquare) {\r\n\t\t\tif (!(await squarify(currentInput, tempSquare))) {\r\n\t\t\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\t\t\treturn { success: false, error: 'Square failed' };\r\n\t\t\t}\r\n\t\t\tif (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\t\t\tcurrentInput = tempSquare;\r\n\t\t}\r\n\r\n\t\t// Scale to preview size (256px)\r\n\t\tif (!(await scaleToSize(currentInput, tempOutput, 256))) {\r\n\t\t\tcleanup(tempTrimmed, tempSquare, tempOutput);\r\n\t\t\treturn { success: false, error: 'Scale failed' };\r\n\t\t}\r\n\t\tif (currentInput === tempSquare) cleanup(tempSquare);\r\n\t\telse if (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\r\n\t\tconst buffer = readFileSync(tempOutput);\r\n\t\tconst base64 = buffer.toString('base64');\r\n\t\tconst imageData = `data:image/png;base64,${base64}`;\r\n\r\n\t\tconst dims = await getDimensions(tempOutput);\r\n\t\tcleanup(tempOutput);\r\n\r\n\t\treturn {\r\n\t\t\tsuccess: true,\r\n\t\t\timageData,\r\n\t\t\twidth: dims?.[0],\r\n\t\t\theight: dims?.[1],\r\n\t\t};\r\n\t} catch (err) {\r\n\t\tcleanup(tempTrimmed, tempSquare, tempOutput);\r\n\t\treturn { success: false, error: (err as Error).message };\r\n\t}\r\n}\r\n\r\n/**\r\n * Convert PNG to ICO (GUI mode)\r\n */\r\nexport async function runGUI(inputRaw: string): Promise<boolean> {\r\n\tconst input = normalizePath(inputRaw);\r\n\r\n\tif (!existsSync(input)) {\r\n\t\terror(`File not found: ${input}`);\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst dims = await getDimensions(input);\r\n\tif (!dims) {\r\n\t\terror('Failed to read image dimensions');\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst fileInfo = getFileInfo(input);\r\n\r\n\treturn startGuiServer({\r\n\t\thtmlFile: 'makeicon.html',\r\n\t\ttitle: 'PicLet - Make Icon',\r\n\t\timageInfo: {\r\n\t\t\tfilePath: input,\r\n\t\t\tfileName: basename(input),\r\n\t\t\twidth: dims[0],\r\n\t\t\theight: dims[1],\r\n\t\t\tborderColor: null,\r\n\t\t},\r\n\t\tdefaults: {\r\n\t\t\ttrim: true,\r\n\t\t\tmakeSquare: true,\r\n\t\t},\r\n\t\tonPreview: async (opts) => {\r\n\t\t\tconst options: ProcessOptions = {\r\n\t\t\t\ttrim: (opts.trim as boolean) ?? true,\r\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? true,\r\n\t\t\t};\r\n\t\t\treturn generatePreview(input, options);\r\n\t\t},\r\n\t\tonProcess: async (opts) => {\r\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\r\n\r\n\t\t\tif (!(await checkImageMagick())) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: false,\r\n\t\t\t\t\terror: 'ImageMagick not found',\r\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\tconst options: ProcessOptions = {\r\n\t\t\t\ttrim: (opts.trim as boolean) ?? true,\r\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? true,\r\n\t\t\t};\r\n\r\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\r\n\r\n\t\t\tconst success = await processForIcon(input, output, options, logs);\r\n\r\n\t\t\tif (success) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: true,\r\n\t\t\t\t\toutput: `${fileInfo.filename}.ico`,\r\n\t\t\t\t\tlogs,\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\treturn { success: false, error: 'Icon creation failed', logs };\r\n\t\t},\r\n\t});\r\n}\r\n\r\nexport const config = {\r\n\tid: 'makeicon',\r\n\tname: 'Make Icon',\r\n\ticon: 'makeicon.ico',\r\n\textensions: ['.png'],\r\n};\r\n","/**\n * Unified PicLet tool - combines all tools with chaining support\n */\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, dirname, extname, join } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport { error } from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tcreateIco,\n\tcreateIcoFromMultiple,\n\tgetBorderColor,\n\tgetDimensions,\n\tremoveBackground,\n\tremoveBackgroundBorderOnly,\n\tresize,\n\tscaleFillCrop,\n\tscaleToSize,\n\tscaleWithPadding,\n\tsquarify,\n\ttrim,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { loadPresets } from '../lib/presets.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface PreviewResult {\n\tsuccess: boolean;\n\timageData?: string;\n\twidth?: number;\n\theight?: number;\n\terror?: string;\n}\n\ninterface ProcessResult {\n\tsuccess: boolean;\n\toutput?: string;\n\terror?: string;\n\tlogs: Array<{ type: string; message: string }>;\n}\n\ninterface Dimension {\n\twidth: number;\n\theight: number;\n\tfilename?: string;\n}\n\ninterface ToolOptions {\n\ttools: string[];\n\toriginal?: boolean;\n\tremovebg?: { fuzz: number; trim: boolean; preserveInner: boolean };\n\tscale?: { width: number; height: number; makeSquare: boolean };\n\ticons?: {\n\t\ttrim: boolean;\n\t\tmakeSquare: boolean;\n\t\tico: boolean;\n\t\tweb: boolean;\n\t\tandroid: boolean;\n\t\tios: boolean;\n\t};\n\tstorepack?: { dimensions: Dimension[]; scaleMode: string; presetName?: string };\n}\n\n// Tool execution order (for chaining)\nconst TOOL_ORDER = ['removebg', 'scale', 'icons', 'storepack'];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Preview - Chains enabled tools\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function generateCombinedPreview(\n\tinput: string,\n\tborderColor: string | null,\n\topts: ToolOptions,\n): Promise<PreviewResult> {\n\tconst tempDir = tmpdir();\n\tconst ts = Date.now();\n\tconst temps: string[] = [];\n\n\tconst makeTempPath = (suffix: string) => {\n\t\tconst p = join(tempDir, `piclet-${ts}-${suffix}.png`);\n\t\ttemps.push(p);\n\t\treturn p;\n\t};\n\n\ttry {\n\t\tlet current = input;\n\n\t\t// If just showing original, scale it for preview and return\n\t\tif (opts.original || opts.tools.length === 0) {\n\t\t\tconst dims = await getDimensions(input);\n\t\t\tlet previewPath = input;\n\n\t\t\tif (dims && (dims[0] > 512 || dims[1] > 512)) {\n\t\t\t\tconst scaled = makeTempPath('orig-preview');\n\t\t\t\tconst targetSize = Math.min(512, Math.max(dims[0], dims[1]));\n\t\t\t\tif (await scaleToSize(input, scaled, targetSize)) {\n\t\t\t\t\tpreviewPath = scaled;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst buffer = readFileSync(previewPath);\n\t\t\tconst finalDims = await getDimensions(previewPath);\n\t\t\tcleanup(...temps);\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\t\twidth: finalDims?.[0] ?? dims?.[0],\n\t\t\t\theight: finalDims?.[1] ?? dims?.[1],\n\t\t\t};\n\t\t}\n\n\t\t// Get ordered list of active tools\n\t\tconst activeTools = TOOL_ORDER.filter(t => opts.tools.includes(t));\n\n\t\t// Process each tool in order\n\t\tfor (const tool of activeTools) {\n\t\t\tswitch (tool) {\n\t\t\t\tcase 'removebg': {\n\t\t\t\t\tconst rbOpts = opts.removebg!;\n\t\t\t\t\tconst out = makeTempPath('removebg');\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tif (rbOpts.preserveInner && borderColor) {\n\t\t\t\t\t\tsuccess = await removeBackgroundBorderOnly(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\t}\n\t\t\t\t\tif (!success && borderColor) {\n\t\t\t\t\t\tsuccess = await removeBackground(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\t}\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\t\treturn { success: false, error: 'Background removal failed' };\n\t\t\t\t\t}\n\n\t\t\t\t\t// Trim if enabled\n\t\t\t\t\tif (rbOpts.trim) {\n\t\t\t\t\t\tconst trimOut = makeTempPath('trim');\n\t\t\t\t\t\tif (await trim(out, trimOut)) {\n\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase 'scale': {\n\t\t\t\t\tconst scOpts = opts.scale!;\n\t\t\t\t\tconst out = makeTempPath('scale');\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tif (scOpts.makeSquare) {\n\t\t\t\t\t\tconst max = Math.max(scOpts.width, scOpts.height);\n\t\t\t\t\t\tsuccess = await scaleWithPadding(current, out, max, max);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsuccess = await resize(current, out, scOpts.width, scOpts.height);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\t\treturn { success: false, error: 'Scale failed' };\n\t\t\t\t\t}\n\t\t\t\t\tcurrent = out;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase 'icons': {\n\t\t\t\t\t// For preview, show what the icon source would look like after trim/squarify\n\t\t\t\t\tconst icOpts = opts.icons!;\n\n\t\t\t\t\tif (icOpts.trim && current === input) {\n\t\t\t\t\t\tconst trimOut = makeTempPath('ic-trim');\n\t\t\t\t\t\tif (await trim(current, trimOut)) {\n\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.makeSquare) {\n\t\t\t\t\t\tconst sqOut = makeTempPath('ic-sq');\n\t\t\t\t\t\tif (await squarify(current, sqOut)) {\n\t\t\t\t\t\t\tcurrent = sqOut;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// storepack doesn't affect preview\n\t\t\t}\n\t\t}\n\n\t\t// Scale down for preview display if needed\n\t\tconst dims = await getDimensions(current);\n\t\tlet previewPath = current;\n\n\t\tif (dims && (dims[0] > 512 || dims[1] > 512)) {\n\t\t\tconst scaled = makeTempPath('preview');\n\t\t\tconst targetSize = Math.min(512, Math.max(dims[0], dims[1]));\n\t\t\tif (await scaleToSize(current, scaled, targetSize)) {\n\t\t\t\tpreviewPath = scaled;\n\t\t\t}\n\t\t}\n\n\t\tconst buffer = readFileSync(previewPath);\n\t\tconst finalDims = await getDimensions(previewPath);\n\t\tcleanup(...temps);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\twidth: finalDims?.[0],\n\t\t\theight: finalDims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(...temps);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Process - Chains enabled tools and produces output\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function processCombined(\n\tinput: string,\n\tborderColor: string | null,\n\topts: ToolOptions,\n\tlogs: Array<{ type: string; message: string }>,\n): Promise<string[]> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputs: string[] = [];\n\tconst temps: string[] = [];\n\n\tconst makeTempPath = (suffix: string) => {\n\t\tconst p = `${fileInfo.dirname}/${fileInfo.filename}_${suffix}.png`;\n\t\ttemps.push(p);\n\t\treturn p;\n\t};\n\n\tlet current = input;\n\tconst activeTools = TOOL_ORDER.filter(t => opts.tools.includes(t));\n\n\tfor (const tool of activeTools) {\n\t\tswitch (tool) {\n\t\t\tcase 'removebg': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Removing background...' });\n\t\t\t\tconst rbOpts = opts.removebg!;\n\t\t\t\tconst out = makeTempPath('nobg');\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (rbOpts.preserveInner && borderColor) {\n\t\t\t\t\tsuccess = await removeBackgroundBorderOnly(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tlogs.push({ type: 'warn', message: 'Border-only failed, trying full removal' });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!success && borderColor) {\n\t\t\t\t\tsuccess = await removeBackground(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t}\n\t\t\t\tif (!success) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Background removal failed' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\tlogs.push({ type: 'success', message: 'Background removed' });\n\n\t\t\t\tif (rbOpts.trim) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Trimming edges...' });\n\t\t\t\t\tconst trimOut = makeTempPath('trimmed');\n\t\t\t\t\tif (await trim(out, trimOut)) {\n\t\t\t\t\t\tcleanup(out);\n\t\t\t\t\t\ttemps.splice(temps.indexOf(out), 1);\n\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcurrent = out;\n\t\t\t\t}\n\n\t\t\t\t// If this is the last tool, save output\n\t\t\t\tif (activeTools.indexOf(tool) === activeTools.length - 1) {\n\t\t\t\t\tconst finalOut = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;\n\t\t\t\t\trenameSync(current, finalOut);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t\toutputs.push(basename(finalOut));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'scale': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Scaling image...' });\n\t\t\t\tconst scOpts = opts.scale!;\n\t\t\t\tconst out = makeTempPath('scaled');\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (scOpts.makeSquare) {\n\t\t\t\t\tconst max = Math.max(scOpts.width, scOpts.height);\n\t\t\t\t\tsuccess = await scaleWithPadding(current, out, max, max);\n\t\t\t\t} else {\n\t\t\t\t\tsuccess = await resize(current, out, scOpts.width, scOpts.height);\n\t\t\t\t}\n\n\t\t\t\tif (!success) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Scale failed' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\tconst dims = await getDimensions(out);\n\t\t\t\tlogs.push({ type: 'success', message: `Scaled to ${dims?.[0]}×${dims?.[1]}` });\n\n\t\t\t\t// Clean up previous temp if it's not the input\n\t\t\t\tif (current !== input && temps.includes(current)) {\n\t\t\t\t\tcleanup(current);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t}\n\t\t\t\tcurrent = out;\n\n\t\t\t\t// If this is the last tool, save output\n\t\t\t\tif (activeTools.indexOf(tool) === activeTools.length - 1) {\n\t\t\t\t\tconst finalOut = `${fileInfo.dirname}/${fileInfo.filename}_scaled${fileInfo.extension}`;\n\t\t\t\t\trenameSync(current, finalOut);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t\toutputs.push(basename(finalOut));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'icons': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating icons...' });\n\t\t\t\tconst icOpts = opts.icons!;\n\n\t\t\t\t// Need at least one output format\n\t\t\t\tif (!icOpts.ico && !icOpts.web && !icOpts.android && !icOpts.ios) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'No output format selected' });\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\t// Prepare source - apply trim and squarify\n\t\t\t\tlet iconSource = current;\n\n\t\t\t\tif (icOpts.trim && current === input) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Trimming edges...' });\n\t\t\t\t\tconst trimOut = makeTempPath('ic-trim');\n\t\t\t\t\tif (await trim(current, trimOut)) {\n\t\t\t\t\t\ticonSource = trimOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (icOpts.makeSquare) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Making square...' });\n\t\t\t\t\tconst sqOut = makeTempPath('ic-sq');\n\t\t\t\t\tif (await squarify(iconSource, sqOut)) {\n\t\t\t\t\t\tif (iconSource !== current && iconSource !== input) cleanup(iconSource);\n\t\t\t\t\t\ticonSource = sqOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Made square' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Prepare high-res source (1024px for packs, 512px for ICO only)\n\t\t\t\tconst maxSize = icOpts.web || icOpts.android || icOpts.ios ? 1024 : 512;\n\t\t\t\tconst srcTemp = makeTempPath('ic-src');\n\t\t\t\tif (!(await scaleToSize(iconSource, srcTemp, maxSize))) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Failed to prepare icon source' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\tif (iconSource !== current && iconSource !== input) cleanup(iconSource);\n\n\t\t\t\tlet totalCount = 0;\n\n\t\t\t\t// Generate ICO file\n\t\t\t\tif (icOpts.ico) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Creating ICO file...' });\n\t\t\t\t\tconst icoOut = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\n\t\t\t\t\tif (await createIco(srcTemp, icoOut)) {\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'ICO: 6 sizes (256, 128, 64, 48, 32, 16)' });\n\t\t\t\t\t\toutputs.push(basename(icoOut));\n\t\t\t\t\t\ttotalCount += 6;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogs.push({ type: 'warn', message: 'ICO creation failed' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Generate icon packs (Web, Android, iOS)\n\t\t\t\tconst needsPacks = icOpts.web || icOpts.android || icOpts.ios;\n\t\t\t\tif (needsPacks) {\n\t\t\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\t\t\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\t\t\tif (icOpts.web) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating Web icons...' });\n\t\t\t\t\t\tconst webDir = `${outputDir}/web`;\n\t\t\t\t\t\tmkdirSync(webDir, { recursive: true });\n\n\t\t\t\t\t\t// Favicon.ico\n\t\t\t\t\t\tconst t16 = `${webDir}/.t16.png`, t32 = `${webDir}/.t32.png`, t48 = `${webDir}/.t48.png`;\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t16, 16);\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t32, 32);\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t48, 48);\n\t\t\t\t\t\tawait createIcoFromMultiple([t16, t32, t48], `${webDir}/favicon.ico`);\n\t\t\t\t\t\tcleanup(t16, t32, t48);\n\t\t\t\t\t\ttotalCount++;\n\n\t\t\t\t\t\tconst webIcons = [\n\t\t\t\t\t\t\t{ name: 'favicon-16x16.png', size: 16 }, { name: 'favicon-32x32.png', size: 32 },\n\t\t\t\t\t\t\t{ name: 'apple-touch-icon.png', size: 180 }, { name: 'android-chrome-192x192.png', size: 192 },\n\t\t\t\t\t\t\t{ name: 'android-chrome-512x512.png', size: 512 }, { name: 'mstile-150x150.png', size: 150 },\n\t\t\t\t\t\t];\n\t\t\t\t\t\tfor (const i of webIcons) {\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, `${webDir}/${i.name}`, i.size);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Web: 7 icons' });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.android) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating Android icons...' });\n\t\t\t\t\t\tconst androidDir = `${outputDir}/android`;\n\t\t\t\t\t\tconst androidIcons = [\n\t\t\t\t\t\t\t{ name: 'mipmap-mdpi/ic_launcher.png', size: 48 },\n\t\t\t\t\t\t\t{ name: 'mipmap-hdpi/ic_launcher.png', size: 72 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xhdpi/ic_launcher.png', size: 96 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xxhdpi/ic_launcher.png', size: 144 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xxxhdpi/ic_launcher.png', size: 192 },\n\t\t\t\t\t\t\t{ name: 'playstore-icon.png', size: 512 },\n\t\t\t\t\t\t];\n\t\t\t\t\t\tfor (const i of androidIcons) {\n\t\t\t\t\t\t\tconst p = `${androidDir}/${i.name}`;\n\t\t\t\t\t\t\tmkdirSync(dirname(p), { recursive: true });\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, p, i.size);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Android: 6 icons' });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.ios) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating iOS icons...' });\n\t\t\t\t\t\tconst iosDir = `${outputDir}/ios`;\n\t\t\t\t\t\tmkdirSync(iosDir, { recursive: true });\n\t\t\t\t\t\tconst iosSizes = [20, 29, 40, 58, 60, 76, 80, 87, 120, 152, 167, 180, 1024];\n\t\t\t\t\t\tfor (const s of iosSizes) {\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, `${iosDir}/AppIcon-${s}.png`, s);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: `iOS: ${iosSizes.length} icons` });\n\t\t\t\t\t}\n\n\t\t\t\t\toutputs.push(`${totalCount} icons → ${fileInfo.filename}_icons/`);\n\t\t\t\t}\n\n\t\t\t\tcleanup(srcTemp);\n\t\t\t\tlogs.push({ type: 'success', message: `Generated ${totalCount} total icons` });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'storepack': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating store assets...' });\n\t\t\t\tconst spOpts = opts.storepack!;\n\n\t\t\t\tif (!spOpts.dimensions || spOpts.dimensions.length === 0) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'No dimensions specified' });\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\tconst folderName = spOpts.presetName || 'assets';\n\t\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${folderName}`;\n\t\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\t\tlet count = 0;\n\t\t\t\tfor (const dim of spOpts.dimensions) {\n\t\t\t\t\tconst filename = dim.filename || `${dim.width}x${dim.height}.png`;\n\t\t\t\t\tconst out = join(outputDir, filename);\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tswitch (spOpts.scaleMode) {\n\t\t\t\t\t\tcase 'fill':\n\t\t\t\t\t\t\tsuccess = await scaleFillCrop(current, out, dim.width, dim.height);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'stretch':\n\t\t\t\t\t\t\tsuccess = await resize(current, out, dim.width, dim.height);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tsuccess = await scaleWithPadding(current, out, dim.width, dim.height);\n\t\t\t\t\t}\n\t\t\t\t\tif (success) count++;\n\t\t\t\t}\n\n\t\t\t\tlogs.push({ type: 'success', message: `Generated ${count}/${spOpts.dimensions.length} images` });\n\t\t\t\toutputs.push(`${count} images → ${fileInfo.filename}_${folderName}/`);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Cleanup any remaining temps\n\tcleanup(...temps);\n\treturn outputs;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Main GUI Entry Point\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tlet currentInput = normalizePath(inputRaw);\n\n\tif (!existsSync(currentInput)) {\n\t\terror(`File not found: ${currentInput}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(currentInput);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tlet currentBorderColor = await getBorderColor(currentInput);\n\tconst presets = loadPresets();\n\n\treturn startGuiServer({\n\t\thtmlFile: 'piclet.html',\n\t\ttitle: 'PicLet',\n\t\timageInfo: {\n\t\t\tfilePath: currentInput,\n\t\t\tfileName: basename(currentInput),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: currentBorderColor,\n\t\t},\n\t\tdefaults: {\n\t\t\t// Return full preset data for the UI\n\t\t\tpresets: presets.map(p => ({\n\t\t\t\tid: p.id,\n\t\t\t\tname: p.name,\n\t\t\t\tdescription: p.description,\n\t\t\t\ticons: p.icons,\n\t\t\t})),\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst toolOpts = opts as unknown as ToolOptions;\n\t\t\t// Allow empty tools array - will show original image\n\t\t\tif (!toolOpts.tools) {\n\t\t\t\ttoolOpts.tools = [];\n\t\t\t}\n\t\t\treturn generateCombinedPreview(currentInput, currentBorderColor, toolOpts);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\t\t\tconst toolOpts = opts as unknown as ToolOptions;\n\n\t\t\tif (!toolOpts.tools || toolOpts.tools.length === 0) {\n\t\t\t\treturn { success: false, error: 'No tools selected', logs };\n\t\t\t}\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst outputs = await processCombined(currentInput, currentBorderColor, toolOpts, logs);\n\n\t\t\tif (outputs.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: outputs.join('\\n'),\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn { success: false, error: 'Processing failed', logs };\n\t\t},\n\t\tonLoadImage: async (data) => {\n\t\t\ttry {\n\t\t\t\t// Save base64 data to temp file\n\t\t\t\tconst ext = extname(data.fileName) || '.png';\n\t\t\t\tconst tempPath = join(tmpdir(), `piclet-load-${Date.now()}${ext}`);\n\t\t\t\tconst buffer = Buffer.from(data.data, 'base64');\n\t\t\t\twriteFileSync(tempPath, buffer);\n\n\t\t\t\t// Get dimensions and border color\n\t\t\t\tconst newDims = await getDimensions(tempPath);\n\t\t\t\tif (!newDims) {\n\t\t\t\t\tcleanup(tempPath);\n\t\t\t\t\treturn { success: false, error: 'Failed to read image dimensions' };\n\t\t\t\t}\n\n\t\t\t\tconst newBorderColor = await getBorderColor(tempPath);\n\n\t\t\t\t// Update current image\n\t\t\t\tcurrentInput = tempPath;\n\t\t\t\tcurrentBorderColor = newBorderColor;\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tfilePath: tempPath,\n\t\t\t\t\tfileName: data.fileName,\n\t\t\t\t\twidth: newDims[0],\n\t\t\t\t\theight: newDims[1],\n\t\t\t\t\tborderColor: newBorderColor,\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\treturn { success: false, error: (err as Error).message };\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport const config = {\n\tid: 'piclet',\n\tname: 'PicLet',\n\ticon: 'banana.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico'],\n};\n","import { existsSync, readFileSync, renameSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, dirname, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tgetBorderColor,\n\tgetDimensions,\n\tremoveBackground,\n\tremoveBackgroundBorderOnly,\n\tsquarify,\n\ttrim,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tconfirm as promptConfirm,\n\tisUsingDefaults,\n\tnumber as promptNumber,\n\tpauseOnError,\n} from '../lib/prompts.js';\n\n/** Processing options for remove-bg */\ninterface ProcessOptions {\n\tfuzz: number;\n\tdoTrim: boolean;\n\tpreserveInner: boolean;\n\tmakeSquare: boolean;\n}\n\n/**\n * Core processing logic for background removal\n */\nasync function processImage(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;\n\tconst tempFile = `${fileInfo.dirname}/${fileInfo.filename}_temp.png`;\n\n\twip('Removing background...');\n\n\tlet bgRemoved = false;\n\tif (options.preserveInner && borderColor) {\n\t\tbgRemoved = await removeBackgroundBorderOnly(\n\t\t\tinput,\n\t\t\ttempFile,\n\t\t\tborderColor,\n\t\t\toptions.fuzz,\n\t\t);\n\t\tif (!bgRemoved) {\n\t\t\twarn('Border-only removal failed, using standard method');\n\t\t}\n\t}\n\n\tif (!bgRemoved && borderColor) {\n\t\tbgRemoved = await removeBackground(input, tempFile, borderColor, options.fuzz);\n\t}\n\n\tif (!bgRemoved) {\n\t\twipDone(false, 'Background removal failed');\n\t\tcleanup(tempFile);\n\t\treturn false;\n\t}\n\twipDone(true, 'Background removed');\n\n\t// Trim if requested\n\tif (options.doTrim) {\n\t\twip('Trimming transparent edges...');\n\t\tif (await trim(tempFile, output)) {\n\t\t\twipDone(true, 'Trimmed');\n\t\t\tcleanup(tempFile);\n\t\t} else {\n\t\t\twipDone(false, 'Trim failed, keeping untrimmed');\n\t\t\trenameSync(tempFile, output);\n\t\t}\n\t} else {\n\t\trenameSync(tempFile, output);\n\t}\n\n\t// Make square if requested\n\tif (options.makeSquare) {\n\t\twip('Making square...');\n\t\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square_temp.png`;\n\t\tif (await squarify(output, tempSquare)) {\n\t\t\trenameSync(tempSquare, output);\n\t\t\twipDone(true, 'Made square');\n\t\t} else {\n\t\t\twipDone(false, 'Square padding failed');\n\t\t\tcleanup(tempSquare);\n\t\t}\n\t}\n\n\t// Final dimensions\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tsuccess(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tsuccess(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Fuzz Value:${RESET} Controls color matching strictness`);\n\tconsole.log(` ${DIM}0-10% = Only exact or very similar colors${RESET}`);\n\tconsole.log(` ${DIM}10-30% = Somewhat similar colors${RESET}`);\n\tconsole.log(` ${DIM}30-70% = Aggressive removal${RESET}`);\n\tconsole.log(` ${DIM}70-100% = May affect non-background areas${RESET}`);\n\tconsole.log('');\n\n\tlet fuzz = await promptNumber('Fuzz value (0-100)', 10, 0, 100);\n\tif (fuzz < 0 || fuzz > 100) {\n\t\twarn('Invalid fuzz value, using 10');\n\t\tfuzz = 10;\n\t}\n\n\tconsole.log('');\n\tconst doTrim = await promptConfirm(\n\t\t'Trim transparent edges after removal?',\n\t\ttrue,\n\t);\n\n\tconsole.log('');\n\tconst preserveInner = await promptConfirm(\n\t\t'Preserve inner areas of same color? (border-only removal)',\n\t\tfalse,\n\t);\n\n\tconsole.log('');\n\tconst makeSquare = await promptConfirm(\n\t\t'Make output square with transparent padding?',\n\t\tfalse,\n\t);\n\n\treturn { fuzz, doTrim, preserveInner, makeSquare };\n}\n\n\n/**\n * Remove solid background from image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Remove Background');\n\n\t// Get original dimensions\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\n\t// Detect border color\n\tconst borderColor = await getBorderColor(input);\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\tif (borderColor) {\n\t\tinfo(`Detected border color: ${borderColor}`);\n\t}\n\n\t// Collect options via CLI or TUI\n\tconst options = await collectOptionsCLI();\n\n\tconsole.log('');\n\treturn processImage(input, borderColor, options);\n}\n\n/**\n * Remove solid background from image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\t// Get original dimensions\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\t// Detect border color\n\tconst borderColor = await getBorderColor(input);\n\n\t// Load config defaults\n\tconst config = loadConfig();\n\tconst defaults = config.removeBg;\n\n\t// Start GUI server\n\treturn startGuiServer({\n\t\thtmlFile: 'remove-bg.html',\n\t\ttitle: 'PicLet - Remove Background',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor,\n\t\t},\n\t\tdefaults: {\n\t\t\tfuzz: defaults.fuzz,\n\t\t\ttrim: defaults.trim,\n\t\t\tpreserveInner: defaults.preserveInner,\n\t\t\tmakeSquare: defaults.makeSquare,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\tfuzz: (opts.fuzz as number) ?? defaults.fuzz,\n\t\t\t\tdoTrim: (opts.trim as boolean) ?? defaults.trim,\n\t\t\t\tpreserveInner: (opts.preserveInner as boolean) ?? defaults.preserveInner,\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? defaults.makeSquare,\n\t\t\t};\n\t\t\treturn generatePreview(input, borderColor, options);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\t// Check dependencies\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\tfuzz: (opts.fuzz as number) ?? defaults.fuzz,\n\t\t\t\tdoTrim: (opts.trim as boolean) ?? defaults.trim,\n\t\t\t\tpreserveInner: (opts.preserveInner as boolean) ?? defaults.preserveInner,\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? defaults.makeSquare,\n\t\t\t};\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;\n\n\t\t\t// Process the image\n\t\t\tlogs.push({ type: 'info', message: 'Removing background...' });\n\n\t\t\tconst success = await processImageSilent(input, borderColor, options, logs);\n\n\t\t\tif (success) {\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Silent version of processImage for GUI mode (logs to array instead of console)\n */\nasync function processImageSilent(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n\tlogs: Array<{ type: string; message: string }>,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;\n\tconst tempFile = `${fileInfo.dirname}/${fileInfo.filename}_temp.png`;\n\n\tlet bgRemoved = false;\n\tif (options.preserveInner && borderColor) {\n\t\tbgRemoved = await removeBackgroundBorderOnly(\n\t\t\tinput,\n\t\t\ttempFile,\n\t\t\tborderColor,\n\t\t\toptions.fuzz,\n\t\t);\n\t\tif (!bgRemoved) {\n\t\t\tlogs.push({ type: 'warn', message: 'Border-only removal failed, using standard method' });\n\t\t}\n\t}\n\n\tif (!bgRemoved && borderColor) {\n\t\tbgRemoved = await removeBackground(input, tempFile, borderColor, options.fuzz);\n\t}\n\n\tif (!bgRemoved) {\n\t\tlogs.push({ type: 'error', message: 'Background removal failed' });\n\t\tcleanup(tempFile);\n\t\treturn false;\n\t}\n\tlogs.push({ type: 'success', message: 'Background removed' });\n\n\t// Trim if requested\n\tif (options.doTrim) {\n\t\tlogs.push({ type: 'info', message: 'Trimming transparent edges...' });\n\t\tif (await trim(tempFile, output)) {\n\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\tcleanup(tempFile);\n\t\t} else {\n\t\t\tlogs.push({ type: 'warn', message: 'Trim failed, keeping untrimmed' });\n\t\t\trenameSync(tempFile, output);\n\t\t}\n\t} else {\n\t\trenameSync(tempFile, output);\n\t}\n\n\t// Make square if requested\n\tif (options.makeSquare) {\n\t\tlogs.push({ type: 'info', message: 'Making square...' });\n\t\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square_temp.png`;\n\t\tif (await squarify(output, tempSquare)) {\n\t\t\trenameSync(tempSquare, output);\n\t\t\tlogs.push({ type: 'success', message: 'Made square' });\n\t\t} else {\n\t\t\tlogs.push({ type: 'warn', message: 'Square padding failed' });\n\t\t\tcleanup(tempSquare);\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempFile = join(tempDir, `piclet-preview-${timestamp}.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}-out.png`);\n\n\ttry {\n\t\t// Remove background\n\t\tlet bgRemoved = false;\n\t\tif (options.preserveInner && borderColor) {\n\t\t\tbgRemoved = await removeBackgroundBorderOnly(input, tempFile, borderColor, options.fuzz);\n\t\t}\n\t\tif (!bgRemoved && borderColor) {\n\t\t\tbgRemoved = await removeBackground(input, tempFile, borderColor, options.fuzz);\n\t\t}\n\t\tif (!bgRemoved) {\n\t\t\treturn { success: false, error: 'Background removal failed' };\n\t\t}\n\n\t\t// Trim if requested\n\t\tlet currentFile = tempFile;\n\t\tif (options.doTrim) {\n\t\t\tif (await trim(tempFile, tempOutput)) {\n\t\t\t\tcleanup(tempFile);\n\t\t\t\tcurrentFile = tempOutput;\n\t\t\t}\n\t\t}\n\n\t\t// Make square if requested\n\t\tif (options.makeSquare) {\n\t\t\tconst squareFile = join(tempDir, `piclet-preview-${timestamp}-sq.png`);\n\t\t\tif (await squarify(currentFile, squareFile)) {\n\t\t\t\tcleanup(currentFile);\n\t\t\t\tcurrentFile = squareFile;\n\t\t\t}\n\t\t}\n\n\t\t// Read as base64\n\t\tconst buffer = readFileSync(currentFile);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\t// Get dimensions\n\t\tconst dims = await getDimensions(currentFile);\n\n\t\t// Cleanup\n\t\tcleanup(currentFile, tempFile, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempFile, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'remove-bg',\n\tname: 'Remove Background',\n\ticon: 'removebg.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.ico'],\n};\n","import { existsSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tgetDimensions,\n\tresize,\n\tscaleWithPadding,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tconfirm as promptConfirm,\n\tnumber as promptNumber,\n\tpauseOnError,\n} from '../lib/prompts.js';\n\n/** Processing options for rescale */\ninterface ProcessOptions {\n\twidth: number;\n\theight: number;\n\tmakeSquare: boolean;\n}\n\n/**\n * Scale image with optional padding\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Get file info\n\tconst fileInfo = getFileInfo(input);\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_scaled${fileInfo.extension}`;\n\n\theader('PicLet Scale Image');\n\n\t// Get original dimensions\n\twip('Reading image dimensions...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\tconst [origW, origH] = dims;\n\twipDone(true, `Original size: ${origW}x${origH}`);\n\n\t// Check if image is square\n\tif (origW !== origH) {\n\t\twarn(`Image is not square (${origW}x${origH})`);\n\t}\n\n\tconsole.log('');\n\tconsole.log(`${BOLD}Scaling Options:${RESET}`);\n\tconsole.log(\n\t\t` ${DIM}Enter 0 for auto-calculate based on other dimension${RESET}`,\n\t);\n\tconsole.log(\n\t\t` ${DIM}Enter single number for both to make square output${RESET}`,\n\t);\n\tconsole.log('');\n\n\t// Get target dimensions\n\tlet targetW = await promptNumber('Width (0 for auto)', 0, 0);\n\tlet targetH = await promptNumber('Height (0 for auto)', 0, 0);\n\n\t// Determine scaling mode\n\tlet makeSquare = false;\n\n\tif (targetW === 0 && targetH === 0) {\n\t\t// Default: scale to 50%\n\t\ttargetW = Math.floor(origW / 2);\n\t\ttargetH = Math.floor(origH / 2);\n\t\tinfo(`Using default: 50% scale (${targetW}x${targetH})`);\n\t} else if (targetW > 0 && targetH === 0) {\n\t\t// Width specified, calculate height\n\t\ttargetH = Math.floor((targetW * origH) / origW);\n\t\tinfo(`Calculated height: ${targetH}`);\n\t} else if (targetW === 0 && targetH > 0) {\n\t\t// Height specified, calculate width\n\t\ttargetW = Math.floor((targetH * origW) / origH);\n\t\tinfo(`Calculated width: ${targetW}`);\n\t}\n\n\t// Ask about square padding\n\tconsole.log('');\n\tmakeSquare = await promptConfirm(\n\t\t'Make output square with transparent padding?',\n\t\tfalse,\n\t);\n\n\tif (makeSquare) {\n\t\tconst maxDim = Math.max(targetW, targetH);\n\t\ttargetW = maxDim;\n\t\ttargetH = maxDim;\n\t\tinfo(`Output will be ${targetW}x${targetH} (square with padding)`);\n\t}\n\n\tconsole.log('');\n\twip('Scaling image...');\n\n\tlet scaled = false;\n\tif (makeSquare) {\n\t\t// Scale and add transparent padding for square output\n\t\tscaled = await scaleWithPadding(input, output, targetW, targetH);\n\t} else {\n\t\t// Standard resize\n\t\tscaled = await resize(input, output, targetW, targetH);\n\t}\n\n\tif (!scaled || !existsSync(output)) {\n\t\twipDone(false, 'Scaling failed');\n\t\treturn false;\n\t}\n\n\t// Get final dimensions\n\tconst finalDims = await getDimensions(output);\n\tif (finalDims) {\n\t\twipDone(true, `Scaled to ${finalDims[0]}x${finalDims[1]}`);\n\t} else {\n\t\twipDone(true, 'Scaled');\n\t}\n\n\tconsole.log('');\n\tsuccess(`Output: ${output}`);\n\treturn true;\n}\n\n/**\n * Scale image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'rescale.html',\n\t\ttitle: 'PicLet - Scale Image',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tmakeSquare: false,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\twidth: (opts.width as number) ?? Math.round(dims[0] / 2),\n\t\t\t\theight: (opts.height as number) ?? Math.round(dims[1] / 2),\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? false,\n\t\t\t};\n\t\t\treturn generatePreview(input, options);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\twidth: (opts.width as number) ?? Math.round(dims[0] / 2),\n\t\t\t\theight: (opts.height as number) ?? Math.round(dims[1] / 2),\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? false,\n\t\t\t};\n\n\t\t\tlogs.push({ type: 'info', message: `Scaling to ${options.width}x${options.height}...` });\n\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_scaled${fileInfo.extension}`;\n\t\t\tlet scaled = false;\n\n\t\t\tif (options.makeSquare) {\n\t\t\t\tconst maxDim = Math.max(options.width, options.height);\n\t\t\t\tscaled = await scaleWithPadding(input, output, maxDim, maxDim);\n\t\t\t} else {\n\t\t\t\tscaled = await resize(input, output, options.width, options.height);\n\t\t\t}\n\n\t\t\tif (scaled && existsSync(output)) {\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\tlogs.push({ type: 'success', message: 'Scaled successfully' });\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Scaling failed' });\n\t\t\treturn { success: false, error: 'Scaling failed', logs };\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\tlet scaled = false;\n\t\tlet targetW = options.width;\n\t\tlet targetH = options.height;\n\n\t\tif (options.makeSquare) {\n\t\t\tconst maxDim = Math.max(targetW, targetH);\n\t\t\ttargetW = maxDim;\n\t\t\ttargetH = maxDim;\n\t\t\tscaled = await scaleWithPadding(input, tempOutput, targetW, targetH);\n\t\t} else {\n\t\t\tscaled = await resize(input, tempOutput, targetW, targetH);\n\t\t}\n\n\t\tif (!scaled || !existsSync(tempOutput)) {\n\t\t\treturn { success: false, error: 'Scaling failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\t\tcleanup(tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'rescale',\n\tname: 'Scale Image',\n\ticon: 'rescale.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],\n};\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { basename, join } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport { error, header, info, success, wip, wipDone } from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tgetDimensions,\n\tresize,\n\tscaleFillCrop,\n\tscaleWithPadding,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { loadPresets, type Preset } from '../lib/presets.js';\nimport { pauseOnError, select as promptSelect } from '../lib/prompts.js';\n\ntype ScaleMode = 'fit' | 'fill' | 'stretch';\n\n/**\n * Scale image using the specified mode\n */\nasync function scaleImage(\n\tinput: string,\n\toutput: string,\n\twidth: number,\n\theight: number,\n\tmode: ScaleMode,\n): Promise<boolean> {\n\tswitch (mode) {\n\t\tcase 'fill':\n\t\t\treturn scaleFillCrop(input, output, width, height);\n\t\tcase 'stretch':\n\t\t\treturn resize(input, output, width, height);\n\t\tcase 'fit':\n\t\tdefault:\n\t\t\treturn scaleWithPadding(input, output, width, height);\n\t}\n}\n\n/**\n * Generate images for a preset\n */\nasync function generatePresetImages(\n\tsourceImg: string,\n\toutputDir: string,\n\tpreset: Preset,\n\tscaleMode: ScaleMode = 'fit',\n\tlogs?: Array<{ type: string; message: string }>,\n): Promise<number> {\n\tlet failed = 0;\n\tconst total = preset.icons.length;\n\n\tfor (let i = 0; i < total; i++) {\n\t\tconst icon = preset.icons[i];\n\t\tconst outputPath = join(outputDir, icon.filename);\n\n\t\tif (logs) {\n\t\t\tlogs.push({ type: 'info', message: `[${i + 1}/${total}] ${icon.filename}` });\n\t\t} else {\n\t\t\twip(`[${i + 1}/${total}] Generating ${icon.filename}...`);\n\t\t}\n\n\t\tconst scaled = await scaleImage(\n\t\t\tsourceImg,\n\t\t\toutputPath,\n\t\t\ticon.width,\n\t\t\ticon.height,\n\t\t\tscaleMode,\n\t\t);\n\n\t\tif (scaled) {\n\t\t\tif (!logs) {\n\t\t\t\twipDone(true, `[${i + 1}/${total}] ${icon.filename} (${icon.width}x${icon.height})`);\n\t\t\t}\n\t\t} else {\n\t\t\tif (logs) {\n\t\t\t\tlogs.push({ type: 'error', message: `Failed: ${icon.filename}` });\n\t\t\t} else {\n\t\t\t\twipDone(false, `[${i + 1}/${total}] Failed: ${icon.filename}`);\n\t\t\t}\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Generate store assets (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\theader('PicLet Store Pack');\n\n\t// Analyze source image\n\twip('Analyzing source image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\twipDone(true, `Source: ${dims[0]}x${dims[1]}`);\n\n\t// Load presets\n\tconst presets = loadPresets();\n\tconst choices = presets.map((p) => ({\n\t\ttitle: p.name,\n\t\tvalue: p.id,\n\t\tdescription: p.description,\n\t}));\n\n\t// Select preset\n\tconsole.log('');\n\tconst selectedId = await promptSelect('Select target store:', choices, presets[0].id);\n\tconst preset = presets.find((p) => p.id === selectedId);\n\n\tif (!preset) {\n\t\terror('Preset not found');\n\t\treturn false;\n\t}\n\n\t// Create output directory\n\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${preset.id}`;\n\tmkdirSync(outputDir, { recursive: true });\n\tinfo(`Output: ${outputDir}`);\n\n\t// Prepare source (make square for consistent scaling)\n\tconsole.log('');\n\twip('Preparing source...');\n\tconst tempSource = join(outputDir, '.source.png');\n\n\tif (!(await squarify(input, tempSource))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\treturn false;\n\t}\n\twipDone(true, 'Source prepared');\n\n\t// Generate images\n\tconsole.log('');\n\theader(`Generating ${preset.name} Images`);\n\n\tconst failed = await generatePresetImages(tempSource, outputDir, preset);\n\tcleanup(tempSource);\n\n\tconsole.log('');\n\tif (failed === 0) {\n\t\tsuccess(`All ${preset.icons.length} images generated!`);\n\t} else {\n\t\terror(`${failed}/${preset.icons.length} images failed`);\n\t}\n\n\tinfo(`Output: ${outputDir}`);\n\treturn failed === 0;\n}\n\n/**\n * Generate store assets (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\tconst presets = loadPresets();\n\n\treturn startGuiServer({\n\t\thtmlFile: 'storepack.html',\n\t\ttitle: 'PicLet - Store Pack',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tpresets: presets.map((p) => ({\n\t\t\t\tid: p.id,\n\t\t\t\tname: p.name,\n\t\t\t\tdescription: p.description,\n\t\t\t\ticons: p.icons,\n\t\t\t})),\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst presetId = opts.preset as string;\n\t\t\tconst scaleMode = (opts.scaleMode as ScaleMode) || 'fit';\n\t\t\tconst preset = presets.find((p) => p.id === presetId);\n\n\t\t\tif (!preset) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'Preset not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'No preset selected' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Create output directory\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${preset.id}`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\t\t\tlogs.push({ type: 'info', message: `Output: ${outputDir}` });\n\t\t\tlogs.push({ type: 'info', message: `Scale mode: ${scaleMode}` });\n\n\t\t\t// Generate images directly from source\n\t\t\tlogs.push({ type: 'info', message: `Generating ${preset.icons.length} images...` });\n\t\t\tconst failed = await generatePresetImages(input, outputDir, preset, scaleMode, logs);\n\n\t\t\tif (failed === 0) {\n\t\t\t\tlogs.push({ type: 'success', message: `All ${preset.icons.length} images generated` });\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${preset.icons.length} images saved to ${fileInfo.filename}_${preset.id}/`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `${failed} image(s) failed`,\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\nexport const config = {\n\tid: 'storepack',\n\tname: 'Store Pack',\n\ticon: 'storepack.ico',\n\textensions: ['.png', '.jpg', '.jpeg'],\n};\n","import * as iconpack from '../tools/iconpack.js';\nimport * as makeicon from '../tools/makeicon.js';\nimport * as picletMain from '../tools/piclet-main.js';\nimport * as removeBg from '../tools/remove-bg.js';\nimport * as rescale from '../tools/rescale.js';\nimport * as storepack from '../tools/storepack.js';\n\n/** Tool configuration */\nexport interface ToolConfig {\n\tid: string;\n\tname: string;\n\ticon: string;\n\textensions: string[];\n}\n\n/** Tool with config and run function */\nexport interface Tool {\n\tconfig: ToolConfig;\n\trun: (file: string) => Promise<boolean>;\n\trunGUI?: (file: string) => Promise<boolean>;\n}\n\n/** Unified tool (GUI only) */\nexport interface UnifiedTool {\n\tconfig: ToolConfig;\n\trunGUI: (file: string) => Promise<boolean>;\n}\n\n/** All available tools (individual) */\nexport const tools: Tool[] = [\n\t{ config: makeicon.config, run: makeicon.run, runGUI: makeicon.runGUI },\n\t{ config: removeBg.config, run: removeBg.run, runGUI: removeBg.runGUI },\n\t{ config: rescale.config, run: rescale.run, runGUI: rescale.runGUI },\n\t{ config: iconpack.config, run: iconpack.run, runGUI: iconpack.runGUI },\n\t{ config: storepack.config, run: storepack.run, runGUI: storepack.runGUI },\n];\n\n/** Unified PicLet tool (all-in-one) */\nexport const picletTool: UnifiedTool = {\n\tconfig: picletMain.config,\n\trunGUI: picletMain.runGUI,\n};\n\n/** Tools that use TUI (terminal GUI) mode */\nexport const tuiTools = ['makeicon', 'remove-bg', 'rescale', 'iconpack', 'storepack'];\n\n/** Get tool by ID */\nexport function getTool(id: string): Tool | undefined {\n\treturn tools.find((t) => t.config.id === id);\n}\n\n/** Get all unique extensions from tools */\nexport function getAllExtensions(): string[] {\n\tconst extensions = new Set<string>();\n\tfor (const { config } of tools) {\n\t\tfor (const ext of config.extensions) {\n\t\t\textensions.add(ext);\n\t\t}\n\t}\n\treturn Array.from(extensions);\n}\n\n/** Get tools that support a given extension */\nexport function getToolsForExtension(extension: string): Tool[] {\n\treturn tools.filter((t) => t.config.extensions.includes(extension));\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { showBanner } from '../../lib/banner.js';\nimport { wslToWindows } from '../../lib/paths.js';\nimport { isWSL, isWSLInteropEnabled } from '../../lib/registry.js';\nimport { generateRegFile, registerAllTools, unregisterAllTools } from '../registry.js';\nimport { tools } from '../tools.js';\n\nexport function registerInstallCommand(program: Command): void {\n\tprogram\n\t\t.command('install')\n\t\t.description('Install Windows shell context menu integration')\n\t\t.action(async () => {\n\t\t\tshowBanner();\n\t\t\tconsole.log(chalk.bold('Installing...\\n'));\n\n\t\t\tif (!isWSL()) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow('! Not running in WSL. Registry integration skipped.'),\n\t\t\t\t);\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow('! Run \"piclet install\" from WSL to add context menu.'),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isWSLInteropEnabled()) {\n\t\t\t\tconsole.log(chalk.yellow('WSL Interop not available. Generating registry file...\\n'));\n\n\t\t\t\tconst regPath = await generateRegFile();\n\t\t\t\tconst winPath = wslToWindows(regPath);\n\n\t\t\t\tconsole.log(chalk.green('✓ Generated registry file:'));\n\t\t\t\tconsole.log(chalk.cyan(` ${winPath}\\n`));\n\t\t\t\tconsole.log(chalk.bold('To install, either:'));\n\t\t\t\tconsole.log(chalk.dim(' 1. Double-click the .reg file in Windows Explorer'));\n\t\t\t\tconsole.log(chalk.dim(` 2. Run in elevated PowerShell: reg import \"${winPath}\"`));\n\t\t\t\tconsole.log();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Clean up existing entries first\n\t\t\tconsole.log(chalk.dim('Removing old entries...'));\n\t\t\tawait unregisterAllTools();\n\t\t\tconsole.log();\n\n\t\t\tconst results = await registerAllTools();\n\t\t\tconst allSuccess = results.every((r) => r.success);\n\n\t\t\t// Display each tool with its supported extensions\n\t\t\tfor (const { config } of tools) {\n\t\t\t\tconst extList = config.extensions.join(', ');\n\t\t\t\tconsole.log(`${chalk.green('✓')} ${config.name} ${chalk.dim(`[${extList}]`)}`);\n\t\t\t}\n\n\t\t\tconsole.log();\n\t\t\tif (allSuccess) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.green(`✓ Registered ${tools.length} tools for context menu.`),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst successCount = results.filter((r) => r.success).length;\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow(`! Registered ${successCount}/${results.length} entries.`),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconsole.log(chalk.bold('\\nUsage:'));\n\t\t\tconsole.log(' Right-click any supported image in Windows Explorer.');\n\t\t\tconsole.log(' Multi-select supported for batch processing.');\n\t\t\tconsole.log();\n\t\t});\n}\n","import { exec } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\n/**\n * Check if running inside WSL\n */\nexport function isWSL(): boolean {\n\treturn (\n\t\tprocess.platform === 'linux' &&\n\t\t(process.env.WSL_DISTRO_NAME !== undefined ||\n\t\t\tprocess.env.WSLENV !== undefined)\n\t);\n}\n\n/**\n * Check if WSL interop is enabled (can run Windows executables)\n */\nexport function isWSLInteropEnabled(): boolean {\n\treturn existsSync('/proc/sys/fs/binfmt_misc/WSLInterop');\n}\n\n/**\n * Convert WSL path to Windows path\n */\nexport function wslToWindows(wslPath: string): string {\n\tconst match = wslPath.match(/^\\/mnt\\/([a-z])\\/(.*)$/i);\n\tif (match) {\n\t\tconst drive = match[1].toUpperCase();\n\t\tconst rest = match[2].replace(/\\//g, '\\\\');\n\t\treturn `${drive}:\\\\${rest}`;\n\t}\n\treturn wslPath;\n}\n\n/**\n * Convert Windows path to WSL path\n */\nexport function windowsToWsl(winPath: string): string {\n\tconst match = winPath.match(/^([A-Za-z]):\\\\(.*)$/);\n\tif (match) {\n\t\tconst drive = match[1].toLowerCase();\n\t\tconst rest = match[2].replace(/\\\\/g, '/');\n\t\treturn `/mnt/${drive}/${rest}`;\n\t}\n\treturn winPath;\n}\n\n/**\n * Get the directory where this module is located\n */\nexport function getModuleDir(): string {\n\tconst currentFile = fileURLToPath(import.meta.url);\n\treturn dirname(currentFile);\n}\n\n/**\n * Add a registry key with value\n */\nexport async function addRegistryKey(\n\tkeyPath: string,\n\tvalueName: string,\n\tvalue: string,\n\ttype = 'REG_SZ',\n): Promise<boolean> {\n\tconst valueArg = valueName ? `/v \"${valueName}\"` : '/ve';\n\t// Escape inner quotes for Windows command line\n\tconst escapedValue = value.replace(/\"/g, '\\\\\"');\n\tconst cmd = `reg.exe add \"${keyPath}\" ${valueArg} /t ${type} /d \"${escapedValue}\" /f`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch (error) {\n\t\tconst message = (error as Error).message;\n\t\t// Silently ignore WSL interop errors (can't run reg.exe)\n\t\tconst ignoredErrors = ['Exec format error', 'not found'];\n\t\tconst shouldIgnore = ignoredErrors.some((e) =>\n\t\t\tmessage.toLowerCase().includes(e.toLowerCase()),\n\t\t);\n\t\tif (!shouldIgnore) {\n\t\t\tconsole.error(`Failed to add registry key: ${keyPath}`);\n\t\t\tconsole.error(message);\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Delete a registry key\n */\nexport async function deleteRegistryKey(keyPath: string): Promise<boolean> {\n\tconst cmd = `reg.exe delete \"${keyPath}\" /f`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch (error) {\n\t\tconst message = (error as Error).message;\n\t\t// Silently ignore expected errors:\n\t\t// - \"unable to find\" = key doesn't exist\n\t\t// - \"Exec format error\" = WSL can't run reg.exe (interop disabled)\n\t\t// - \"not found\" = reg.exe not in PATH\n\t\tconst ignoredErrors = ['unable to find', 'Exec format error', 'not found'];\n\t\tconst shouldIgnore = ignoredErrors.some((e) =>\n\t\t\tmessage.toLowerCase().includes(e.toLowerCase()),\n\t\t);\n\t\tif (!shouldIgnore) {\n\t\t\tconsole.error(`Failed to delete registry key: ${keyPath}`);\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if a registry key exists\n */\nexport async function registryKeyExists(keyPath: string): Promise<boolean> {\n\tconst cmd = `reg.exe query \"${keyPath}\" 2>/dev/null`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","import { writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { wslToWindows } from '../lib/paths.js';\nimport { addRegistryKey, deleteRegistryKey } from '../lib/registry.js';\nimport { getAllExtensions, getToolsForExtension, picletTool, tuiTools } from './tools.js';\nimport { getDistDir, getMenuBasePath } from './utils.js';\n\n/** Tool registration result */\nexport interface RegistrationResult {\n\textension: string;\n\ttoolName: string;\n\tsuccess: boolean;\n}\n\n/** Register unified PicLet menu item directly on context menu (no submenu) */\nasync function registerUnifiedMenu(\n\textension: string,\n\ticonsDir: string,\n\tlauncherPath: string,\n): Promise<RegistrationResult> {\n\tconst basePath = `HKCU\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\n\t// Create direct PicLet menu item (not a submenu)\n\tconst menuSuccess = await addRegistryKey(basePath, 'MUIVerb', 'PicLet');\n\tconst iconSuccess = await addRegistryKey(basePath, 'Icon', `${iconsDirWin}\\\\banana.ico`);\n\n\t// Enable multi-select\n\tawait addRegistryKey(basePath, 'MultiSelectModel', 'Player');\n\n\t// Command - opens unified GUI\n\tconst commandValue = `wscript.exe //B \"${launcherWin}\" piclet \"%1\" -g`;\n\tconst cmdSuccess = await addRegistryKey(`${basePath}\\\\command`, '', commandValue);\n\n\treturn {\n\t\textension,\n\t\ttoolName: 'PicLet',\n\t\tsuccess: menuSuccess && iconSuccess && cmdSuccess,\n\t};\n}\n\n/** Register PicLet submenu for a single extension (legacy - individual tools) */\nasync function registerMenuForExtension(\n\textension: string,\n\ticonsDir: string,\n\tlauncherPath: string,\n): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\tconst basePath = getMenuBasePath(extension);\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\tconst extensionTools = getToolsForExtension(extension);\n\n\t// Create parent PicLet menu\n\tawait addRegistryKey(basePath, 'MUIVerb', 'PicLet');\n\tawait addRegistryKey(basePath, 'Icon', `${iconsDirWin}\\\\banana.ico`);\n\tawait addRegistryKey(basePath, 'SubCommands', '');\n\n\t// Create submenu for each tool\n\tfor (const { config } of extensionTools) {\n\t\tconst toolPath = `${basePath}\\\\shell\\\\${config.id}`;\n\n\t\tconst menuSuccess = await addRegistryKey(toolPath, 'MUIVerb', config.name);\n\t\tconst iconSuccess = await addRegistryKey(\n\t\t\ttoolPath,\n\t\t\t'Icon',\n\t\t\t`${iconsDirWin}\\\\${config.icon}`,\n\t\t);\n\n\t\t// Enable multi-select\n\t\tawait addRegistryKey(toolPath, 'MultiSelectModel', 'Player');\n\n\t\t// Command - use VBScript launcher for hidden cmd.exe window\n\t\tlet commandValue: string;\n\t\tif (tuiTools.includes(config.id)) {\n\t\t\t// GUI mode - opens Edge app window\n\t\t\tcommandValue = `wscript.exe //B \"${launcherWin}\" ${config.id} \"%1\" -g`;\n\t\t} else {\n\t\t\t// Run headless with defaults\n\t\t\tcommandValue = `wscript.exe //B \"${launcherWin}\" ${config.id} \"%1\" -y`;\n\t\t}\n\t\tconst cmdSuccess = await addRegistryKey(\n\t\t\t`${toolPath}\\\\command`,\n\t\t\t'',\n\t\t\tcommandValue,\n\t\t);\n\n\t\tresults.push({\n\t\t\textension,\n\t\t\ttoolName: config.name,\n\t\t\tsuccess: menuSuccess && iconSuccess && cmdSuccess,\n\t\t});\n\t}\n\n\treturn results;\n}\n\n/** Unregister PicLet menu for a single extension */\nasync function unregisterMenuForExtension(\n\textension: string,\n): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\tconst basePath = getMenuBasePath(extension);\n\tconst extensionTools = getToolsForExtension(extension);\n\n\t// Delete each tool's submenu\n\tfor (const { config } of extensionTools) {\n\t\tconst toolPath = `${basePath}\\\\shell\\\\${config.id}`;\n\t\tawait deleteRegistryKey(`${toolPath}\\\\command`);\n\t\tconst success = await deleteRegistryKey(toolPath);\n\n\t\tresults.push({\n\t\t\textension,\n\t\t\ttoolName: config.name,\n\t\t\tsuccess,\n\t\t});\n\t}\n\n\t// Delete the shell container\n\tawait deleteRegistryKey(`${basePath}\\\\shell`);\n\n\t// Delete parent PicLet menu\n\tawait deleteRegistryKey(basePath);\n\n\treturn results;\n}\n\n/** Register all tools - unified mode (single PicLet menu item) */\nexport async function registerAllTools(): Promise<RegistrationResult[]> {\n\tconst distDir = getDistDir();\n\tconst iconsDir = join(distDir, 'icons');\n\tconst launcherPath = join(distDir, 'launcher.vbs');\n\tconst results: RegistrationResult[] = [];\n\n\t// Register unified PicLet menu for each supported extension\n\tfor (const extension of picletTool.config.extensions) {\n\t\tconst result = await registerUnifiedMenu(extension, iconsDir, launcherPath);\n\t\tresults.push(result);\n\t}\n\n\treturn results;\n}\n\n/** Unregister all tools */\nexport async function unregisterAllTools(): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\n\t// Unregister from all extensions (both unified and legacy)\n\tconst allExts = new Set([...getAllExtensions(), ...picletTool.config.extensions]);\n\tfor (const extension of allExts) {\n\t\tconst basePath = getMenuBasePath(extension);\n\n\t\t// Try to delete any submenus (legacy)\n\t\tconst extResults = await unregisterMenuForExtension(extension);\n\t\tresults.push(...extResults);\n\n\t\t// Also delete the unified command if it exists\n\t\tawait deleteRegistryKey(`${basePath}\\\\command`);\n\t\tawait deleteRegistryKey(basePath);\n\t}\n\n\treturn results;\n}\n\n/**\n * Escape a string value for .reg file format\n */\nfunction escapeRegValue(value: string): string {\n\treturn value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Generate registry content for unified PicLet menu\n */\nfunction generateRegContent(): string {\n\tconst distDir = getDistDir();\n\tconst iconsDir = join(distDir, 'icons');\n\tconst launcherPath = join(distDir, 'launcher.vbs');\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\n\tconst lines: string[] = ['Windows Registry Editor Version 5.00', ''];\n\n\t// Register unified PicLet menu for each supported extension\n\tfor (const extension of picletTool.config.extensions) {\n\t\tconst basePath = `HKEY_CURRENT_USER\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n\n\t\tlines.push(`[${basePath}]`);\n\t\tlines.push(`\"MUIVerb\"=\"${escapeRegValue('PicLet')}\"`);\n\t\tlines.push(`\"Icon\"=\"${escapeRegValue(`${iconsDirWin}\\\\banana.ico`)}\"`);\n\t\tlines.push('\"MultiSelectModel\"=\"Player\"');\n\t\tlines.push('');\n\n\t\t// Command - opens unified GUI\n\t\tconst commandValue = `wscript.exe //B \"${launcherWin}\" piclet \"%1\" -g`;\n\t\tlines.push(`[${basePath}\\\\command]`);\n\t\tlines.push(`@=\"${escapeRegValue(commandValue)}\"`);\n\t\tlines.push('');\n\t}\n\n\treturn lines.join('\\r\\n');\n}\n\n/**\n * Generate uninstall registry content (deletion entries)\n */\nfunction generateUninstallRegContent(): string {\n\tconst lines: string[] = ['Windows Registry Editor Version 5.00', ''];\n\n\t// Delete from all extensions (both unified and legacy)\n\tconst allExts = new Set([...getAllExtensions(), ...picletTool.config.extensions]);\n\tfor (const extension of allExts) {\n\t\tconst basePath = `HKEY_CURRENT_USER\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n\n\t\t// Delete the entire PicLet key (minus sign deletes)\n\t\tlines.push(`[-${basePath}]`);\n\t\tlines.push('');\n\t}\n\n\treturn lines.join('\\r\\n');\n}\n\n/**\n * Generate a .reg file for installation\n * @returns Path to the generated .reg file\n */\nexport async function generateRegFile(): Promise<string> {\n\tconst distDir = getDistDir();\n\tconst regPath = join(distDir, 'piclet-install.reg');\n\tconst content = generateRegContent();\n\tawait writeFile(regPath, content, 'utf-8');\n\treturn regPath;\n}\n\n/**\n * Generate a .reg file for uninstallation\n * @returns Path to the generated .reg file\n */\nexport async function generateUninstallRegFile(): Promise<string> {\n\tconst distDir = getDistDir();\n\tconst regPath = join(distDir, 'piclet-uninstall.reg');\n\tconst content = generateUninstallRegContent();\n\tawait writeFile(regPath, content, 'utf-8');\n\treturn regPath;\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as makeicon from '../../tools/makeicon.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerMakeiconCommand(program: Command): void {\n\tprogram\n\t\t.command('makeicon <files...>')\n\t\t.description('Convert PNG to multi-resolution ICO file')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for confirmation')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, makeicon.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await makeicon.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'makeicon',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { picletTool } from '../tools.js';\nimport { validateExtensions } from '../utils.js';\n\nexport function registerPicletCommand(program: Command): void {\n\tprogram\n\t\t.command('piclet <file>')\n\t\t.description('Open unified PicLet window with all tools')\n\t\t.option('-g, --gui', 'Use GUI (default)')\n\t\t.action(async (file: string) => {\n\t\t\tconst { valid, invalid } = validateExtensions([file], picletTool.config.extensions);\n\t\t\tif (invalid.length > 0) {\n\t\t\t\tconsole.error(chalk.red(`Invalid file type: ${file}`));\n\t\t\t\tconsole.error(chalk.yellow(`Supported: ${picletTool.config.extensions.join(', ')}`));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tconst result = await picletTool.runGUI(valid[0]);\n\t\t\tprocess.exit(result ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { clearOverrides, setOverrides } from '../../lib/prompts.js';\nimport * as removeBg from '../../tools/remove-bg.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerRemoveBgCommand(program: Command): void {\n\tprogram\n\t\t.command('remove-bg <files...>')\n\t\t.alias('removebg')\n\t\t.description('Remove solid background from image')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use TUI (terminal GUI) for options')\n\t\t.option('-f, --fuzz <percent>', 'Fuzz tolerance 0-100 (default: 10)')\n\t\t.option('-t, --trim', 'Trim transparent edges (default: true)')\n\t\t.option('--no-trim', 'Do not trim transparent edges')\n\t\t.option('-p, --preserve-inner', 'Preserve inner areas of same color')\n\t\t.option('-s, --square', 'Make output square with padding')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean; fuzz?: string; trim?: boolean; preserveInner?: boolean; square?: boolean }) => {\n\t\t\t// GUI mode - open HTML interface in browser\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, removeBg.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\t// Only process first file in GUI mode\n\t\t\t\tconst result = await removeBg.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\t// Set overrides from CLI args\n\t\t\tif (options.fuzz !== undefined) {\n\t\t\t\tsetOverrides({ 'fuzz': Number(options.fuzz) });\n\t\t\t}\n\t\t\tif (options.trim !== undefined) {\n\t\t\t\tsetOverrides({ 'trim': options.trim });\n\t\t\t}\n\t\t\tif (options.preserveInner) {\n\t\t\t\tsetOverrides({ 'preserve inner': true });\n\t\t\t}\n\t\t\tif (options.square) {\n\t\t\t\tsetOverrides({ 'square': true });\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'remove-bg',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tclearOverrides();\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as rescale from '../../tools/rescale.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerScaleCommand(program: Command): void {\n\tprogram\n\t\t.command('scale <files...>')\n\t\t.alias('rescale')\n\t\t.description('Resize image with optional padding')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, rescale.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await rescale.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'rescale',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as storepack from '../../tools/storepack.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerStorepackCommand(program: Command): void {\n\tprogram\n\t\t.command('storepack <files...>')\n\t\t.description('Generate assets for app stores (Windows, Unity, Steam, etc.)')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, storepack.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await storepack.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'storepack',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { showBanner } from '../../lib/banner.js';\nimport { wslToWindows } from '../../lib/paths.js';\nimport { isWSL, isWSLInteropEnabled } from '../../lib/registry.js';\nimport { generateUninstallRegFile, unregisterAllTools } from '../registry.js';\n\nexport function registerUninstallCommand(program: Command): void {\n\tprogram\n\t\t.command('uninstall')\n\t\t.description('Remove Windows shell context menu integration')\n\t\t.action(async () => {\n\t\t\tshowBanner();\n\t\t\tconsole.log(chalk.bold('Uninstalling...\\n'));\n\n\t\t\tif (!isWSL()) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow('! Not running in WSL. Registry cleanup skipped.'),\n\t\t\t\t);\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t'! Run \"piclet uninstall\" from WSL to remove context menu.',\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isWSLInteropEnabled()) {\n\t\t\t\tconsole.log(chalk.yellow('WSL Interop not available. Generating registry file...\\n'));\n\n\t\t\t\tconst regPath = await generateUninstallRegFile();\n\t\t\t\tconst winPath = wslToWindows(regPath);\n\n\t\t\t\tconsole.log(chalk.green('✓ Generated uninstall registry file:'));\n\t\t\t\tconsole.log(chalk.cyan(` ${winPath}\\n`));\n\t\t\t\tconsole.log(chalk.bold('To uninstall, either:'));\n\t\t\t\tconsole.log(chalk.dim(' 1. Double-click the .reg file in Windows Explorer'));\n\t\t\t\tconsole.log(chalk.dim(` 2. Run in elevated PowerShell: reg import \"${winPath}\"`));\n\t\t\t\tconsole.log();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst results = await unregisterAllTools();\n\t\t\tconst removedCount = results.filter((r) => r.success).length;\n\n\t\t\tfor (const result of results) {\n\t\t\t\tif (result.success) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`${chalk.green('✓')} Removed: ${result.extension} → ${result.toolName}`,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`${chalk.gray('-')} Skipped: ${result.extension} → ${result.toolName}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log();\n\t\t\tconsole.log(\n\t\t\t\tchalk.green(\n\t\t\t\t\t`✓ Cleanup complete. Removed ${removedCount}/${results.length} entries.`,\n\t\t\t\t),\n\t\t\t);\n\t\t\tconsole.log(chalk.dim('\\nThanks for using PicLet!\\n'));\n\t\t});\n}\n"],"mappings":"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","names":["chalk","chalk","program","config","program","chalk","existsSync","mkdirSync","basename","dirname","dirname","join","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","homedir","config","config","writeFileSync","existsSync","readFileSync","existsSync","readFileSync","config","__dirname","dirname","resolve","join","existsSync","mkdirSync","dirname","squarify","existsSync","dirname","dirname","existsSync","mkdirSync","squarify","basename","extname","dirname","fileURLToPath","chalk","existsSync","readFileSync","basename","join","run","existsSync","squarify","join","readFileSync","runGUI","basename","success","config","existsSync","mkdirSync","readFileSync","writeFileSync","tmpdir","basename","dirname","extname","join","tmpdir","join","dims","previewPath","buffer","readFileSync","finalDims","success","squarify","basename","mkdirSync","dirname","runGUI","existsSync","extname","writeFileSync","config","existsSync","readFileSync","renameSync","tmpdir","basename","join","renameSync","squarify","run","existsSync","runGUI","config","basename","generatePreview","success","tmpdir","join","readFileSync","existsSync","readFileSync","tmpdir","basename","join","run","existsSync","runGUI","basename","generatePreview","tmpdir","join","readFileSync","config","existsSync","mkdirSync","basename","join","join","run","existsSync","mkdirSync","runGUI","basename","config","config","run","runGUI","config","fileURLToPath","dirname","extname","chalk","success","program","chalk","success","chalk","exec","existsSync","dirname","fileURLToPath","promisify","execAsync","execAsync","error","join","config","success","join","program","chalk","config","chalk","program","config","chalk","runGUI","success","chalk","program","chalk","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","chalk","program","chalk","chalk","program","error","chalk"]}
|