@spark-apps/piclet 1.0.4 → 1.0.6

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/dist/cli.js CHANGED
@@ -1,19 +1,14 @@
1
1
  #!/usr/bin/env node
2
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
- }) : x)(function(x) {
5
- if (typeof require !== "undefined") return require.apply(this, arguments);
6
- throw Error('Dynamic require of "' + x + '" is not supported');
7
- });
8
2
 
9
3
  // src/cli.ts
10
- import chalk17 from "chalk";
4
+ import chalk18 from "chalk";
11
5
 
12
6
  // src/cli/index.ts
13
- import chalk16 from "chalk";
7
+ import chalk17 from "chalk";
14
8
  import { Command } from "commander";
15
9
 
16
10
  // src/lib/banner.ts
11
+ import chalk from "chalk";
17
12
  import figlet from "figlet";
18
13
  import gradient from "gradient-string";
19
14
  var GRADIENT_COLORS = ["#22c55e", "#84cc16", "#eab308", "#fcd34d"];
@@ -24,36 +19,37 @@ function renderLogo() {
24
19
  });
25
20
  return gradient(GRADIENT_COLORS)(ascii);
26
21
  }
22
+ var SUBTITLE_COLOR = "#eab308";
27
23
  function showBanner(subtitle = "Image manipulation utility toolkit with Windows shell integration") {
28
24
  try {
29
25
  console.log(`
30
26
  ${renderLogo()}`);
31
27
  if (subtitle) {
32
- const subtleGradient = gradient(["#a8a8a8", "#d4d4d4"]);
33
- console.log(subtleGradient(` ${subtitle}
28
+ console.log(chalk.hex(SUBTITLE_COLOR)(`${subtitle}
34
29
  `));
35
30
  }
36
31
  } catch {
37
32
  console.log("\n\x1B[1mPicLet\x1B[0m");
38
33
  if (subtitle) {
39
- console.log(`\x1B[2m ${subtitle}\x1B[0m
34
+ console.log(`\x1B[38;2;234;179;8m${subtitle}\x1B[0m
40
35
  `);
41
36
  }
42
37
  }
43
38
  }
44
39
 
45
40
  // src/cli/commands/border.ts
46
- import chalk2 from "chalk";
41
+ import chalk3 from "chalk";
47
42
 
48
43
  // src/tools/border.ts
49
- import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
44
+ import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
50
45
  import { tmpdir } from "os";
51
- import { basename as basename2, join as join3 } from "path";
46
+ import { basename as basename2, join as join4 } from "path";
52
47
 
53
48
  // src/lib/gui-server.ts
54
49
  import { spawn } from "child_process";
50
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
55
51
  import { createServer } from "http";
56
- import { dirname as dirname2, join as join2 } from "path";
52
+ import { dirname as dirname2, extname, join as join2 } from "path";
57
53
  import { fileURLToPath } from "url";
58
54
  import express from "express";
59
55
 
@@ -506,14 +502,12 @@ function startGuiServer(options) {
506
502
  return;
507
503
  }
508
504
  try {
509
- const fs = __require("fs");
510
- const path = __require("path");
511
- if (!fs.existsSync(outputPath)) {
505
+ if (!existsSync2(outputPath)) {
512
506
  res.json({ success: false, error: "Output file not found" });
513
507
  return;
514
508
  }
515
- const buffer = fs.readFileSync(outputPath);
516
- const ext = path.extname(outputPath).toLowerCase();
509
+ const buffer = readFileSync2(outputPath);
510
+ const ext = extname(outputPath).toLowerCase();
517
511
  const mimeTypes = {
518
512
  ".png": "image/png",
519
513
  ".jpg": "image/jpeg",
@@ -632,7 +626,7 @@ function clearLine() {
632
626
 
633
627
  // src/lib/magick.ts
634
628
  import { exec } from "child_process";
635
- import { copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, unlinkSync } from "fs";
629
+ import { copyFileSync, existsSync as existsSync3, mkdirSync as mkdirSync2, unlinkSync } from "fs";
636
630
  import { dirname as dirname3 } from "path";
637
631
  import { promisify } from "util";
638
632
  var execAsync = promisify(exec);
@@ -822,14 +816,14 @@ async function createIcoFromMultiple(pngPaths, outputPath) {
822
816
  }
823
817
  function ensureDir(filePath) {
824
818
  const dir = dirname3(filePath);
825
- if (!existsSync2(dir)) {
819
+ if (!existsSync3(dir)) {
826
820
  mkdirSync2(dir, { recursive: true });
827
821
  }
828
822
  }
829
823
  function cleanup(...files) {
830
824
  for (const file of files) {
831
825
  try {
832
- if (existsSync2(file)) {
826
+ if (existsSync3(file)) {
833
827
  unlinkSync(file);
834
828
  }
835
829
  } catch {
@@ -1100,7 +1094,8 @@ async function simplifyGif(inputPath, outputPath, skipFactor) {
1100
1094
  }
1101
1095
 
1102
1096
  // src/lib/paths.ts
1103
- import { basename, dirname as dirname4, extname, resolve } from "path";
1097
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
1098
+ import { basename, dirname as dirname4, extname as extname2, join as join3, resolve } from "path";
1104
1099
  function windowsToWsl(winPath) {
1105
1100
  if (winPath.startsWith("/mnt/")) {
1106
1101
  return winPath;
@@ -1131,7 +1126,7 @@ function normalizePath(inputPath) {
1131
1126
  function getFileInfo(filePath) {
1132
1127
  const dir = dirname4(filePath);
1133
1128
  const base = basename(filePath);
1134
- const ext = extname(filePath);
1129
+ const ext = extname2(filePath);
1135
1130
  const name = base.slice(0, -ext.length);
1136
1131
  return {
1137
1132
  dirname: dir,
@@ -1140,6 +1135,20 @@ function getFileInfo(filePath) {
1140
1135
  extension: ext
1141
1136
  };
1142
1137
  }
1138
+ function getOutputDir(inputPath) {
1139
+ const dir = dirname4(inputPath);
1140
+ if (basename(dir) === "PicLet") {
1141
+ return dir;
1142
+ }
1143
+ return join3(dir, "PicLet");
1144
+ }
1145
+ function ensureOutputDir(inputPath) {
1146
+ const outDir = getOutputDir(inputPath);
1147
+ if (!existsSync4(outDir)) {
1148
+ mkdirSync3(outDir, { recursive: true });
1149
+ }
1150
+ return outDir;
1151
+ }
1143
1152
 
1144
1153
  // src/lib/prompts.ts
1145
1154
  import prompts from "prompts";
@@ -1288,7 +1297,7 @@ async function run(inputRaw) {
1288
1297
  return false;
1289
1298
  }
1290
1299
  const input = normalizePath(inputRaw);
1291
- if (!existsSync3(input)) {
1300
+ if (!existsSync5(input)) {
1292
1301
  error(`File not found: ${input}`);
1293
1302
  await pauseOnError();
1294
1303
  return false;
@@ -1307,7 +1316,7 @@ async function run(inputRaw) {
1307
1316
  }
1308
1317
  async function runGUI(inputRaw) {
1309
1318
  const input = normalizePath(inputRaw);
1310
- if (!existsSync3(input)) {
1319
+ if (!existsSync5(input)) {
1311
1320
  error(`File not found: ${input}`);
1312
1321
  return false;
1313
1322
  }
@@ -1375,8 +1384,8 @@ async function runGUI(inputRaw) {
1375
1384
  async function generatePreview(input, options) {
1376
1385
  const tempDir = tmpdir();
1377
1386
  const timestamp = Date.now();
1378
- const tempSource = join3(tempDir, `piclet-preview-${timestamp}-src.png`);
1379
- const tempOutput = join3(tempDir, `piclet-preview-${timestamp}.png`);
1387
+ const tempSource = join4(tempDir, `piclet-preview-${timestamp}-src.png`);
1388
+ const tempOutput = join4(tempDir, `piclet-preview-${timestamp}.png`);
1380
1389
  try {
1381
1390
  let previewInput = input;
1382
1391
  if (isMultiFrame(input)) {
@@ -1390,7 +1399,7 @@ async function generatePreview(input, options) {
1390
1399
  cleanup(tempSource, tempOutput);
1391
1400
  return { success: false, error: "Border failed" };
1392
1401
  }
1393
- const buffer = readFileSync2(tempOutput);
1402
+ const buffer = readFileSync3(tempOutput);
1394
1403
  const base64 = buffer.toString("base64");
1395
1404
  const imageData = `data:image/png;base64,${base64}`;
1396
1405
  const dims = await getDimensions(tempOutput);
@@ -1413,16 +1422,10 @@ var config = {
1413
1422
  extensions: [".png", ".jpg", ".jpeg", ".gif", ".bmp"]
1414
1423
  };
1415
1424
 
1416
- // src/cli/utils.ts
1417
- import { extname as extname3 } from "path";
1418
- import { dirname as dirname9 } from "path";
1419
- import { fileURLToPath as fileURLToPath2 } from "url";
1420
- import chalk from "chalk";
1421
-
1422
1425
  // src/tools/extract-frames.ts
1423
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3 } from "fs";
1426
+ import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync4 } from "fs";
1424
1427
  import { tmpdir as tmpdir2 } from "os";
1425
- import { basename as basename3, join as join4 } from "path";
1428
+ import { basename as basename3, join as join5 } from "path";
1426
1429
  async function run2(inputRaw) {
1427
1430
  if (!await checkImageMagick()) {
1428
1431
  error("ImageMagick not found. Please install it:");
@@ -1431,7 +1434,7 @@ async function run2(inputRaw) {
1431
1434
  return false;
1432
1435
  }
1433
1436
  const input = normalizePath(inputRaw);
1434
- if (!existsSync4(input)) {
1437
+ if (!existsSync6(input)) {
1435
1438
  error(`File not found: ${input}`);
1436
1439
  await pauseOnError();
1437
1440
  return false;
@@ -1462,7 +1465,7 @@ async function run2(inputRaw) {
1462
1465
  const outputDir = `${fileInfo.dirname}/${fileInfo.filename}_frames`;
1463
1466
  console.log("");
1464
1467
  wip("Extracting frames...");
1465
- mkdirSync3(outputDir, { recursive: true });
1468
+ mkdirSync4(outputDir, { recursive: true });
1466
1469
  const frames = await extractAllFrames(input, outputDir, "frame");
1467
1470
  if (frames.length === 0) {
1468
1471
  wipDone(false, "Extraction failed");
@@ -1475,7 +1478,7 @@ async function run2(inputRaw) {
1475
1478
  }
1476
1479
  async function runGUI2(inputRaw) {
1477
1480
  const input = normalizePath(inputRaw);
1478
- if (!existsSync4(input)) {
1481
+ if (!existsSync6(input)) {
1479
1482
  error(`File not found: ${input}`);
1480
1483
  return false;
1481
1484
  }
@@ -1514,7 +1517,7 @@ async function runGUI2(inputRaw) {
1514
1517
  }
1515
1518
  logs.push({ type: "info", message: `Extracting ${frameCount} frames...` });
1516
1519
  const outputDir = `${fileInfo.dirname}/${fileInfo.filename}_frames`;
1517
- mkdirSync3(outputDir, { recursive: true });
1520
+ mkdirSync4(outputDir, { recursive: true });
1518
1521
  const frames = await extractAllFrames(input, outputDir, "frame");
1519
1522
  if (frames.length > 0) {
1520
1523
  logs.push({ type: "success", message: `Extracted ${frames.length} frames` });
@@ -1532,12 +1535,12 @@ async function runGUI2(inputRaw) {
1532
1535
  async function generateFramePreview(input, frameIndex) {
1533
1536
  const tempDir = tmpdir2();
1534
1537
  const timestamp = Date.now();
1535
- const tempOutput = join4(tempDir, `piclet-frame-${timestamp}.png`);
1538
+ const tempOutput = join5(tempDir, `piclet-frame-${timestamp}.png`);
1536
1539
  try {
1537
1540
  if (!await extractFirstFrame(input, tempOutput, frameIndex)) {
1538
1541
  return { success: false, error: "Failed to extract frame" };
1539
1542
  }
1540
- const buffer = readFileSync3(tempOutput);
1543
+ const buffer = readFileSync4(tempOutput);
1541
1544
  const base64 = buffer.toString("base64");
1542
1545
  const imageData = `data:image/png;base64,${base64}`;
1543
1546
  const dims = await getDimensions(tempOutput);
@@ -1561,9 +1564,9 @@ var config2 = {
1561
1564
  };
1562
1565
 
1563
1566
  // src/tools/filter.ts
1564
- import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
1567
+ import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
1565
1568
  import { tmpdir as tmpdir3 } from "os";
1566
- import { basename as basename4, join as join5 } from "path";
1569
+ import { basename as basename4, join as join6 } from "path";
1567
1570
  var FILTER_LABELS = {
1568
1571
  "grayscale": "Grayscale",
1569
1572
  "sepia": "Sepia",
@@ -1637,7 +1640,7 @@ async function run3(inputRaw) {
1637
1640
  return false;
1638
1641
  }
1639
1642
  const input = normalizePath(inputRaw);
1640
- if (!existsSync5(input)) {
1643
+ if (!existsSync7(input)) {
1641
1644
  error(`File not found: ${input}`);
1642
1645
  await pauseOnError();
1643
1646
  return false;
@@ -1656,7 +1659,7 @@ async function run3(inputRaw) {
1656
1659
  }
1657
1660
  async function runGUI3(inputRaw) {
1658
1661
  const input = normalizePath(inputRaw);
1659
- if (!existsSync5(input)) {
1662
+ if (!existsSync7(input)) {
1660
1663
  error(`File not found: ${input}`);
1661
1664
  return false;
1662
1665
  }
@@ -1721,8 +1724,8 @@ async function runGUI3(inputRaw) {
1721
1724
  async function generatePreview2(input, options) {
1722
1725
  const tempDir = tmpdir3();
1723
1726
  const timestamp = Date.now();
1724
- const tempSource = join5(tempDir, `piclet-preview-${timestamp}-src.png`);
1725
- const tempOutput = join5(tempDir, `piclet-preview-${timestamp}.png`);
1727
+ const tempSource = join6(tempDir, `piclet-preview-${timestamp}-src.png`);
1728
+ const tempOutput = join6(tempDir, `piclet-preview-${timestamp}.png`);
1726
1729
  try {
1727
1730
  let previewInput = input;
1728
1731
  if (isMultiFrame(input)) {
@@ -1736,7 +1739,7 @@ async function generatePreview2(input, options) {
1736
1739
  cleanup(tempSource, tempOutput);
1737
1740
  return { success: false, error: "Filter failed" };
1738
1741
  }
1739
- const buffer = readFileSync4(tempOutput);
1742
+ const buffer = readFileSync5(tempOutput);
1740
1743
  const base64 = buffer.toString("base64");
1741
1744
  const imageData = `data:image/png;base64,${base64}`;
1742
1745
  const dims = await getDimensions(tempOutput);
@@ -1760,7 +1763,7 @@ var config3 = {
1760
1763
  };
1761
1764
 
1762
1765
  // src/tools/iconpack.ts
1763
- import { existsSync as existsSync6, mkdirSync as mkdirSync4 } from "fs";
1766
+ import { existsSync as existsSync8, mkdirSync as mkdirSync5 } from "fs";
1764
1767
  import { basename as basename5, dirname as dirname5 } from "path";
1765
1768
  var WEB_ICONS = [
1766
1769
  { filename: "favicon-16x16.png", size: 16 },
@@ -1811,8 +1814,8 @@ async function generateIcons(outputDir, sourceImg, icons) {
1811
1814
  current++;
1812
1815
  const outputPath = `${outputDir}/${icon.filename}`;
1813
1816
  const subdir = dirname5(outputPath);
1814
- if (!existsSync6(subdir)) {
1815
- mkdirSync4(subdir, { recursive: true });
1817
+ if (!existsSync8(subdir)) {
1818
+ mkdirSync5(subdir, { recursive: true });
1816
1819
  }
1817
1820
  clearLine();
1818
1821
  wip(`[${current}/${total}] Generating ${icon.filename}...`);
@@ -1857,7 +1860,7 @@ async function run4(inputRaw) {
1857
1860
  return false;
1858
1861
  }
1859
1862
  const input = normalizePath(inputRaw);
1860
- if (!existsSync6(input)) {
1863
+ if (!existsSync8(input)) {
1861
1864
  error(`File not found: ${input}`);
1862
1865
  await pauseOnError();
1863
1866
  return false;
@@ -1899,7 +1902,7 @@ async function run4(inputRaw) {
1899
1902
  const doAndroid = platforms.includes("android");
1900
1903
  const doIos = platforms.includes("ios");
1901
1904
  const outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;
1902
- mkdirSync4(outputDir, { recursive: true });
1905
+ mkdirSync5(outputDir, { recursive: true });
1903
1906
  info(`Output directory: ${outputDir}`);
1904
1907
  console.log("");
1905
1908
  wip("Preparing source image...");
@@ -1921,7 +1924,7 @@ async function run4(inputRaw) {
1921
1924
  console.log("");
1922
1925
  header("Web Icons");
1923
1926
  const webDir = `${outputDir}/web`;
1924
- mkdirSync4(webDir, { recursive: true });
1927
+ mkdirSync5(webDir, { recursive: true });
1925
1928
  if (!await generateFavicon(webDir, tempSource)) {
1926
1929
  totalFailed++;
1927
1930
  }
@@ -1931,14 +1934,14 @@ async function run4(inputRaw) {
1931
1934
  console.log("");
1932
1935
  header("Android Icons");
1933
1936
  const androidDir = `${outputDir}/android`;
1934
- mkdirSync4(androidDir, { recursive: true });
1937
+ mkdirSync5(androidDir, { recursive: true });
1935
1938
  totalFailed += await generateIcons(androidDir, tempSource, ANDROID_ICONS);
1936
1939
  }
1937
1940
  if (doIos) {
1938
1941
  console.log("");
1939
1942
  header("iOS Icons");
1940
1943
  const iosDir = `${outputDir}/ios`;
1941
- mkdirSync4(iosDir, { recursive: true });
1944
+ mkdirSync5(iosDir, { recursive: true });
1942
1945
  totalFailed += await generateIcons(iosDir, tempSource, IOS_ICONS);
1943
1946
  }
1944
1947
  cleanup(tempSource);
@@ -1964,7 +1967,7 @@ async function run4(inputRaw) {
1964
1967
  }
1965
1968
  async function runGUI4(inputRaw) {
1966
1969
  const input = normalizePath(inputRaw);
1967
- if (!existsSync6(input)) {
1970
+ if (!existsSync8(input)) {
1968
1971
  error(`File not found: ${input}`);
1969
1972
  return false;
1970
1973
  }
@@ -2009,7 +2012,7 @@ async function runGUI4(inputRaw) {
2009
2012
  };
2010
2013
  }
2011
2014
  const outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;
2012
- mkdirSync4(outputDir, { recursive: true });
2015
+ mkdirSync5(outputDir, { recursive: true });
2013
2016
  logs.push({ type: "info", message: `Output: ${outputDir}` });
2014
2017
  logs.push({ type: "info", message: "Preparing source image..." });
2015
2018
  const tempSource = `${outputDir}/.source_1024.png`;
@@ -2027,7 +2030,7 @@ async function runGUI4(inputRaw) {
2027
2030
  if (doWeb) {
2028
2031
  logs.push({ type: "info", message: "Generating Web icons..." });
2029
2032
  const webDir = `${outputDir}/web`;
2030
- mkdirSync4(webDir, { recursive: true });
2033
+ mkdirSync5(webDir, { recursive: true });
2031
2034
  if (!await generateFaviconSilent(webDir, tempSource)) {
2032
2035
  totalFailed++;
2033
2036
  }
@@ -2037,14 +2040,14 @@ async function runGUI4(inputRaw) {
2037
2040
  if (doAndroid) {
2038
2041
  logs.push({ type: "info", message: "Generating Android icons..." });
2039
2042
  const androidDir = `${outputDir}/android`;
2040
- mkdirSync4(androidDir, { recursive: true });
2043
+ mkdirSync5(androidDir, { recursive: true });
2041
2044
  totalFailed += await generateIconsSilent(androidDir, tempSource, ANDROID_ICONS, logs);
2042
2045
  logs.push({ type: "success", message: `Android: ${ANDROID_ICONS.length} icons` });
2043
2046
  }
2044
2047
  if (doIos) {
2045
2048
  logs.push({ type: "info", message: "Generating iOS icons..." });
2046
2049
  const iosDir = `${outputDir}/ios`;
2047
- mkdirSync4(iosDir, { recursive: true });
2050
+ mkdirSync5(iosDir, { recursive: true });
2048
2051
  totalFailed += await generateIconsSilent(iosDir, tempSource, IOS_ICONS, logs);
2049
2052
  logs.push({ type: "success", message: `iOS: ${IOS_ICONS.length} icons` });
2050
2053
  }
@@ -2069,8 +2072,8 @@ async function generateIconsSilent(outputDir, sourceImg, icons, _logs) {
2069
2072
  for (const icon of icons) {
2070
2073
  const outputPath = `${outputDir}/${icon.filename}`;
2071
2074
  const subdir = dirname5(outputPath);
2072
- if (!existsSync6(subdir)) {
2073
- mkdirSync4(subdir, { recursive: true });
2075
+ if (!existsSync8(subdir)) {
2076
+ mkdirSync5(subdir, { recursive: true });
2074
2077
  }
2075
2078
  if (!await scaleToSize(sourceImg, outputPath, icon.size)) {
2076
2079
  failed++;
@@ -2100,9 +2103,9 @@ var config4 = {
2100
2103
  };
2101
2104
 
2102
2105
  // src/tools/makeicon.ts
2103
- import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
2106
+ import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
2104
2107
  import { tmpdir as tmpdir4 } from "os";
2105
- import { basename as basename6, join as join6 } from "path";
2108
+ import { basename as basename6, join as join7 } from "path";
2106
2109
  async function run5(inputRaw) {
2107
2110
  if (!await checkImageMagick()) {
2108
2111
  error("ImageMagick not found. Please install it:");
@@ -2111,7 +2114,7 @@ async function run5(inputRaw) {
2111
2114
  return false;
2112
2115
  }
2113
2116
  const input = normalizePath(inputRaw);
2114
- if (!existsSync7(input)) {
2117
+ if (!existsSync9(input)) {
2115
2118
  error(`File not found: ${input}`);
2116
2119
  await pauseOnError();
2117
2120
  return false;
@@ -2209,9 +2212,9 @@ async function processForIcon(input, output, options, logs) {
2209
2212
  async function generatePreview3(input, options) {
2210
2213
  const tempDir = tmpdir4();
2211
2214
  const timestamp = Date.now();
2212
- const tempTrimmed = join6(tempDir, `piclet-preview-trimmed-${timestamp}.png`);
2213
- const tempSquare = join6(tempDir, `piclet-preview-square-${timestamp}.png`);
2214
- const tempOutput = join6(tempDir, `piclet-preview-${timestamp}.png`);
2215
+ const tempTrimmed = join7(tempDir, `piclet-preview-trimmed-${timestamp}.png`);
2216
+ const tempSquare = join7(tempDir, `piclet-preview-square-${timestamp}.png`);
2217
+ const tempOutput = join7(tempDir, `piclet-preview-${timestamp}.png`);
2215
2218
  try {
2216
2219
  let currentInput = input;
2217
2220
  if (options.trim) {
@@ -2235,7 +2238,7 @@ async function generatePreview3(input, options) {
2235
2238
  }
2236
2239
  if (currentInput === tempSquare) cleanup(tempSquare);
2237
2240
  else if (currentInput === tempTrimmed) cleanup(tempTrimmed);
2238
- const buffer = readFileSync5(tempOutput);
2241
+ const buffer = readFileSync6(tempOutput);
2239
2242
  const base64 = buffer.toString("base64");
2240
2243
  const imageData = `data:image/png;base64,${base64}`;
2241
2244
  const dims = await getDimensions(tempOutput);
@@ -2253,7 +2256,7 @@ async function generatePreview3(input, options) {
2253
2256
  }
2254
2257
  async function runGUI5(inputRaw) {
2255
2258
  const input = normalizePath(inputRaw);
2256
- if (!existsSync7(input)) {
2259
+ if (!existsSync9(input)) {
2257
2260
  error(`File not found: ${input}`);
2258
2261
  return false;
2259
2262
  }
@@ -2318,16 +2321,16 @@ var config5 = {
2318
2321
  };
2319
2322
 
2320
2323
  // src/tools/piclet-main.ts
2321
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync, writeFileSync as writeFileSync2 } from "fs";
2324
+ import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync, writeFileSync as writeFileSync2 } from "fs";
2322
2325
  import { tmpdir as tmpdir5 } from "os";
2323
- import { basename as basename7, dirname as dirname6, extname as extname2, join as join7 } from "path";
2326
+ import { basename as basename7, dirname as dirname6, extname as extname3, join as join8 } from "path";
2324
2327
  var TOOL_ORDER = ["removebg", "scale", "icons", "storepack"];
2325
2328
  async function generateCombinedPreview(input, borderColor, opts) {
2326
2329
  const tempDir = tmpdir5();
2327
2330
  const ts = Date.now();
2328
2331
  const temps = [];
2329
2332
  const makeTempPath = (suffix) => {
2330
- const p = join7(tempDir, `piclet-${ts}-${suffix}.png`);
2333
+ const p = join8(tempDir, `piclet-${ts}-${suffix}.png`);
2331
2334
  temps.push(p);
2332
2335
  return p;
2333
2336
  };
@@ -2349,7 +2352,7 @@ async function generateCombinedPreview(input, borderColor, opts) {
2349
2352
  previewPath2 = scaled;
2350
2353
  }
2351
2354
  }
2352
- const buffer2 = readFileSync6(previewPath2);
2355
+ const buffer2 = readFileSync7(previewPath2);
2353
2356
  const finalDims2 = await getDimensions(previewPath2);
2354
2357
  cleanup(...temps);
2355
2358
  return {
@@ -2434,7 +2437,7 @@ async function generateCombinedPreview(input, borderColor, opts) {
2434
2437
  previewPath = scaled;
2435
2438
  }
2436
2439
  }
2437
- const buffer = readFileSync6(previewPath);
2440
+ const buffer = readFileSync7(previewPath);
2438
2441
  const finalDims = await getDimensions(previewPath);
2439
2442
  cleanup(...temps);
2440
2443
  return {
@@ -2504,7 +2507,8 @@ async function processCombined(input, borderColor, opts, logs) {
2504
2507
  current = out;
2505
2508
  }
2506
2509
  if (activeTools.indexOf(tool) === activeTools.length - 1) {
2507
- const finalOut = `${fileInfo.dirname}/${fileInfo.filename}_nobg${outputExt}`;
2510
+ const outDir = ensureOutputDir(input);
2511
+ const finalOut = join8(outDir, `${fileInfo.filename}_nobg${outputExt}`);
2508
2512
  renameSync(current, finalOut);
2509
2513
  temps.splice(temps.indexOf(current), 1);
2510
2514
  outputs.push(basename7(finalOut));
@@ -2536,7 +2540,8 @@ async function processCombined(input, borderColor, opts, logs) {
2536
2540
  }
2537
2541
  current = out;
2538
2542
  if (activeTools.indexOf(tool) === activeTools.length - 1) {
2539
- const finalOut = `${fileInfo.dirname}/${fileInfo.filename}_scaled${outputExt}`;
2543
+ const outDir = ensureOutputDir(input);
2544
+ const finalOut = join8(outDir, `${fileInfo.filename}_scaled${outputExt}`);
2540
2545
  renameSync(current, finalOut);
2541
2546
  temps.splice(temps.indexOf(current), 1);
2542
2547
  outputs.push(basename7(finalOut));
@@ -2580,7 +2585,8 @@ async function processCombined(input, borderColor, opts, logs) {
2580
2585
  let totalCount = 0;
2581
2586
  if (icOpts.ico) {
2582
2587
  logs.push({ type: "info", message: "Creating ICO file..." });
2583
- const icoOut = `${fileInfo.dirname}/${fileInfo.filename}.ico`;
2588
+ const outDir = ensureOutputDir(input);
2589
+ const icoOut = join8(outDir, `${fileInfo.filename}.ico`);
2584
2590
  if (await createIco(srcTemp, icoOut)) {
2585
2591
  logs.push({ type: "success", message: "ICO: 6 sizes (256, 128, 64, 48, 32, 16)" });
2586
2592
  outputs.push(basename7(icoOut));
@@ -2591,12 +2597,13 @@ async function processCombined(input, borderColor, opts, logs) {
2591
2597
  }
2592
2598
  const needsPacks = icOpts.web || icOpts.android || icOpts.ios;
2593
2599
  if (needsPacks) {
2594
- const outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;
2595
- mkdirSync5(outputDir, { recursive: true });
2600
+ const outDir = ensureOutputDir(input);
2601
+ const outputDir = join8(outDir, `${fileInfo.filename}_icons`);
2602
+ mkdirSync6(outputDir, { recursive: true });
2596
2603
  if (icOpts.web) {
2597
2604
  logs.push({ type: "info", message: "Generating Web icons..." });
2598
2605
  const webDir = `${outputDir}/web`;
2599
- mkdirSync5(webDir, { recursive: true });
2606
+ mkdirSync6(webDir, { recursive: true });
2600
2607
  const t16 = `${webDir}/.t16.png`, t32 = `${webDir}/.t32.png`, t48 = `${webDir}/.t48.png`;
2601
2608
  await scaleToSize(srcTemp, t16, 16);
2602
2609
  await scaleToSize(srcTemp, t32, 32);
@@ -2631,7 +2638,7 @@ async function processCombined(input, borderColor, opts, logs) {
2631
2638
  ];
2632
2639
  for (const i of androidIcons) {
2633
2640
  const p = `${androidDir}/${i.name}`;
2634
- mkdirSync5(dirname6(p), { recursive: true });
2641
+ mkdirSync6(dirname6(p), { recursive: true });
2635
2642
  await scaleToSize(srcTemp, p, i.size);
2636
2643
  totalCount++;
2637
2644
  }
@@ -2640,7 +2647,7 @@ async function processCombined(input, borderColor, opts, logs) {
2640
2647
  if (icOpts.ios) {
2641
2648
  logs.push({ type: "info", message: "Generating iOS icons..." });
2642
2649
  const iosDir = `${outputDir}/ios`;
2643
- mkdirSync5(iosDir, { recursive: true });
2650
+ mkdirSync6(iosDir, { recursive: true });
2644
2651
  const iosSizes = [20, 29, 40, 58, 60, 76, 80, 87, 120, 152, 167, 180, 1024];
2645
2652
  for (const s of iosSizes) {
2646
2653
  await scaleToSize(srcTemp, `${iosDir}/AppIcon-${s}.png`, s);
@@ -2662,12 +2669,13 @@ async function processCombined(input, borderColor, opts, logs) {
2662
2669
  return { outputs: [] };
2663
2670
  }
2664
2671
  const folderName = spOpts.presetName || "assets";
2665
- const outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${folderName}`;
2666
- mkdirSync5(outputDir, { recursive: true });
2672
+ const outDir = ensureOutputDir(input);
2673
+ const outputDir = join8(outDir, `${fileInfo.filename}_${folderName}`);
2674
+ mkdirSync6(outputDir, { recursive: true });
2667
2675
  let count = 0;
2668
2676
  for (const dim of spOpts.dimensions) {
2669
2677
  const filename = dim.filename || `${dim.width}x${dim.height}.png`;
2670
- const out = join7(outputDir, filename);
2678
+ const out = join8(outputDir, filename);
2671
2679
  let success2 = false;
2672
2680
  switch (spOpts.scaleMode) {
2673
2681
  case "fill":
@@ -2692,7 +2700,7 @@ async function processCombined(input, borderColor, opts, logs) {
2692
2700
  }
2693
2701
  async function runGUI6(inputRaw) {
2694
2702
  let currentInput = normalizePath(inputRaw);
2695
- if (!existsSync8(currentInput)) {
2703
+ if (!existsSync10(currentInput)) {
2696
2704
  error(`File not found: ${currentInput}`);
2697
2705
  return false;
2698
2706
  }
@@ -2706,14 +2714,14 @@ async function runGUI6(inputRaw) {
2706
2714
  const presets = loadPresets();
2707
2715
  async function generateFrameThumbnail(frameIndex) {
2708
2716
  const tempDir = tmpdir5();
2709
- const tempOutput = join7(tempDir, `piclet-frame-${Date.now()}-${frameIndex}.png`);
2717
+ const tempOutput = join8(tempDir, `piclet-frame-${Date.now()}-${frameIndex}.png`);
2710
2718
  try {
2711
2719
  if (!await extractFirstFrame(currentInput, tempOutput, frameIndex)) {
2712
2720
  return { success: false, error: "Failed to extract frame" };
2713
2721
  }
2714
- const thumbOutput = join7(tempDir, `piclet-thumb-${Date.now()}-${frameIndex}.png`);
2722
+ const thumbOutput = join8(tempDir, `piclet-thumb-${Date.now()}-${frameIndex}.png`);
2715
2723
  await scaleToSize(tempOutput, thumbOutput, 96);
2716
- const buffer = readFileSync6(thumbOutput);
2724
+ const buffer = readFileSync7(thumbOutput);
2717
2725
  cleanup(tempOutput, thumbOutput);
2718
2726
  return {
2719
2727
  success: true,
@@ -2727,7 +2735,7 @@ async function runGUI6(inputRaw) {
2727
2735
  async function generateFramePreview2(frameIndex, opts) {
2728
2736
  const tempDir = tmpdir5();
2729
2737
  const ts = Date.now();
2730
- const frameFile = join7(tempDir, `piclet-fp-${ts}-${frameIndex}.png`);
2738
+ const frameFile = join8(tempDir, `piclet-fp-${ts}-${frameIndex}.png`);
2731
2739
  const temps = [frameFile];
2732
2740
  try {
2733
2741
  if (!await extractFirstFrame(currentInput, frameFile, frameIndex)) {
@@ -2736,7 +2744,7 @@ async function runGUI6(inputRaw) {
2736
2744
  let current = frameFile;
2737
2745
  const activeTools = ["removebg", "scale", "icons"].filter((t) => opts.tools.includes(t));
2738
2746
  for (const tool of activeTools) {
2739
- const tempOut = join7(tempDir, `piclet-fp-${ts}-${frameIndex}-${tool}.png`);
2747
+ const tempOut = join8(tempDir, `piclet-fp-${ts}-${frameIndex}-${tool}.png`);
2740
2748
  temps.push(tempOut);
2741
2749
  switch (tool) {
2742
2750
  case "removebg": {
@@ -2750,7 +2758,7 @@ async function runGUI6(inputRaw) {
2750
2758
  }
2751
2759
  if (success2) {
2752
2760
  if (rbOpts.trim) {
2753
- const trimOut = join7(tempDir, `piclet-fp-${ts}-${frameIndex}-trim.png`);
2761
+ const trimOut = join8(tempDir, `piclet-fp-${ts}-${frameIndex}-trim.png`);
2754
2762
  temps.push(trimOut);
2755
2763
  if (await trim(tempOut, trimOut)) {
2756
2764
  current = trimOut;
@@ -2780,7 +2788,7 @@ async function runGUI6(inputRaw) {
2780
2788
  case "icons": {
2781
2789
  const icOpts = opts.icons;
2782
2790
  if (icOpts.trim) {
2783
- const trimOut = join7(tempDir, `piclet-fp-${ts}-${frameIndex}-ictrim.png`);
2791
+ const trimOut = join8(tempDir, `piclet-fp-${ts}-${frameIndex}-ictrim.png`);
2784
2792
  temps.push(trimOut);
2785
2793
  if (await trim(current, trimOut)) {
2786
2794
  current = trimOut;
@@ -2795,10 +2803,10 @@ async function runGUI6(inputRaw) {
2795
2803
  }
2796
2804
  }
2797
2805
  }
2798
- const thumbOut = join7(tempDir, `piclet-fp-${ts}-${frameIndex}-thumb.png`);
2806
+ const thumbOut = join8(tempDir, `piclet-fp-${ts}-${frameIndex}-thumb.png`);
2799
2807
  temps.push(thumbOut);
2800
2808
  await scaleToSize(current, thumbOut, 96);
2801
- const buffer = readFileSync6(thumbOut);
2809
+ const buffer = readFileSync7(thumbOut);
2802
2810
  cleanup(...temps);
2803
2811
  return {
2804
2812
  success: true,
@@ -2837,7 +2845,7 @@ async function runGUI6(inputRaw) {
2837
2845
  if (isMultiFrame(currentInput) && typeof toolOpts.frameIndex === "number") {
2838
2846
  const tempDir = tmpdir5();
2839
2847
  const ts = Date.now();
2840
- const frameFile = join7(tempDir, `piclet-prev-${ts}.png`);
2848
+ const frameFile = join8(tempDir, `piclet-prev-${ts}.png`);
2841
2849
  if (!await extractFirstFrame(currentInput, frameFile, toolOpts.frameIndex)) {
2842
2850
  return { success: false, error: "Failed to extract frame" };
2843
2851
  }
@@ -2876,8 +2884,8 @@ async function runGUI6(inputRaw) {
2876
2884
  },
2877
2885
  onLoadImage: async (data) => {
2878
2886
  try {
2879
- const ext = extname2(data.fileName) || ".png";
2880
- const tempPath = join7(tmpdir5(), `piclet-load-${Date.now()}${ext}`);
2887
+ const ext = extname3(data.fileName) || ".png";
2888
+ const tempPath = join8(tmpdir5(), `piclet-load-${Date.now()}${ext}`);
2881
2889
  const buffer = Buffer.from(data.data, "base64");
2882
2890
  writeFileSync2(tempPath, buffer);
2883
2891
  const newDims = await getDimensions(tempPath);
@@ -2911,7 +2919,7 @@ async function runGUI6(inputRaw) {
2911
2919
  },
2912
2920
  onSimplifyGif: async (skipFactor) => {
2913
2921
  try {
2914
- const tempPath = join7(tmpdir5(), `piclet-simplified-${Date.now()}.gif`);
2922
+ const tempPath = join8(tmpdir5(), `piclet-simplified-${Date.now()}.gif`);
2915
2923
  const result = await simplifyGif(currentInput, tempPath, skipFactor);
2916
2924
  if (!result.success) {
2917
2925
  return { success: false, error: "Failed to simplify GIF" };
@@ -2937,7 +2945,7 @@ async function runGUI6(inputRaw) {
2937
2945
  },
2938
2946
  onDeleteFrame: async (frameIndex) => {
2939
2947
  try {
2940
- const tempPath = join7(tmpdir5(), `piclet-edited-${Date.now()}.gif`);
2948
+ const tempPath = join8(tmpdir5(), `piclet-edited-${Date.now()}.gif`);
2941
2949
  const result = await deleteGifFrame(currentInput, tempPath, frameIndex);
2942
2950
  if (!result.success) {
2943
2951
  return { success: false, error: "Failed to delete frame" };
@@ -2952,9 +2960,9 @@ async function runGUI6(inputRaw) {
2952
2960
  onReplaceFrame: async (frameIndex, imageData) => {
2953
2961
  try {
2954
2962
  const buffer = Buffer.from(imageData, "base64");
2955
- const tempImagePath = join7(tmpdir5(), `piclet-replace-${Date.now()}.png`);
2963
+ const tempImagePath = join8(tmpdir5(), `piclet-replace-${Date.now()}.png`);
2956
2964
  writeFileSync2(tempImagePath, buffer);
2957
- const tempPath = join7(tmpdir5(), `piclet-edited-${Date.now()}.gif`);
2965
+ const tempPath = join8(tmpdir5(), `piclet-edited-${Date.now()}.gif`);
2958
2966
  const result = await replaceGifFrame(currentInput, tempPath, frameIndex, tempImagePath);
2959
2967
  cleanup(tempImagePath);
2960
2968
  if (!result.success) {
@@ -2984,7 +2992,7 @@ async function processGifExport(input, borderColor, opts, logs) {
2984
2992
  case "frame": {
2985
2993
  const frameIndex = opts.frameIndex ?? 0;
2986
2994
  logs.push({ type: "info", message: `Exporting frame ${frameIndex + 1}...` });
2987
- const frameFile = join7(tempDir, `piclet-export-${ts}.png`);
2995
+ const frameFile = join8(tempDir, `piclet-export-${ts}.png`);
2988
2996
  if (!await extractFirstFrame(input, frameFile, frameIndex)) {
2989
2997
  logs.push({ type: "error", message: "Failed to extract frame" });
2990
2998
  return { success: false, error: "Failed to extract frame", logs };
@@ -2999,7 +3007,8 @@ async function processGifExport(input, borderColor, opts, logs) {
2999
3007
  return { success: false, error: "Processing failed", logs };
3000
3008
  }
3001
3009
  }
3002
- const finalOutput = `${fileInfo.dirname}/${fileInfo.filename}_frame${frameIndex + 1}.png`;
3010
+ const frameOutDir = ensureOutputDir(input);
3011
+ const finalOutput = join8(frameOutDir, `${fileInfo.filename}_frame${frameIndex + 1}.png`);
3003
3012
  if (outputFile === frameFile) {
3004
3013
  renameSync(frameFile, finalOutput);
3005
3014
  }
@@ -3008,8 +3017,9 @@ async function processGifExport(input, borderColor, opts, logs) {
3008
3017
  }
3009
3018
  case "all-frames": {
3010
3019
  logs.push({ type: "info", message: "Extracting all frames..." });
3011
- const outputDir = `${fileInfo.dirname}/${fileInfo.filename}_frames`;
3012
- mkdirSync5(outputDir, { recursive: true });
3020
+ const framesOutDir = ensureOutputDir(input);
3021
+ const outputDir = join8(framesOutDir, `${fileInfo.filename}_frames`);
3022
+ mkdirSync6(outputDir, { recursive: true });
3013
3023
  const frames = await extractAllFrames(input, outputDir, "frame");
3014
3024
  if (frames.length === 0) {
3015
3025
  logs.push({ type: "error", message: "Failed to extract frames" });
@@ -3046,9 +3056,9 @@ var config6 = {
3046
3056
  };
3047
3057
 
3048
3058
  // src/tools/recolor.ts
3049
- import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
3059
+ import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
3050
3060
  import { tmpdir as tmpdir6 } from "os";
3051
- import { basename as basename8, join as join8 } from "path";
3061
+ import { basename as basename8, join as join9 } from "path";
3052
3062
  async function processImage3(input, options) {
3053
3063
  const fileInfo = getFileInfo(input);
3054
3064
  const outputExt = fileInfo.extension.toLowerCase() === ".gif" ? ".gif" : ".png";
@@ -3111,7 +3121,7 @@ async function run6(inputRaw) {
3111
3121
  return false;
3112
3122
  }
3113
3123
  const input = normalizePath(inputRaw);
3114
- if (!existsSync9(input)) {
3124
+ if (!existsSync11(input)) {
3115
3125
  error(`File not found: ${input}`);
3116
3126
  await pauseOnError();
3117
3127
  return false;
@@ -3134,7 +3144,7 @@ async function run6(inputRaw) {
3134
3144
  }
3135
3145
  async function runGUI7(inputRaw) {
3136
3146
  const input = normalizePath(inputRaw);
3137
- if (!existsSync9(input)) {
3147
+ if (!existsSync11(input)) {
3138
3148
  error(`File not found: ${input}`);
3139
3149
  return false;
3140
3150
  }
@@ -3206,8 +3216,8 @@ async function runGUI7(inputRaw) {
3206
3216
  async function generatePreview4(input, options) {
3207
3217
  const tempDir = tmpdir6();
3208
3218
  const timestamp = Date.now();
3209
- const tempSource = join8(tempDir, `piclet-preview-${timestamp}-src.png`);
3210
- const tempOutput = join8(tempDir, `piclet-preview-${timestamp}.png`);
3219
+ const tempSource = join9(tempDir, `piclet-preview-${timestamp}-src.png`);
3220
+ const tempOutput = join9(tempDir, `piclet-preview-${timestamp}.png`);
3211
3221
  try {
3212
3222
  let previewInput = input;
3213
3223
  if (isMultiFrame(input)) {
@@ -3227,7 +3237,7 @@ async function generatePreview4(input, options) {
3227
3237
  cleanup(tempSource, tempOutput);
3228
3238
  return { success: false, error: "Color replacement failed" };
3229
3239
  }
3230
- const buffer = readFileSync7(tempOutput);
3240
+ const buffer = readFileSync8(tempOutput);
3231
3241
  const base64 = buffer.toString("base64");
3232
3242
  const imageData = `data:image/png;base64,${base64}`;
3233
3243
  const dims = await getDimensions(tempOutput);
@@ -3251,13 +3261,13 @@ var config7 = {
3251
3261
  };
3252
3262
 
3253
3263
  // src/tools/remove-bg.ts
3254
- import { existsSync as existsSync11, readFileSync as readFileSync9, renameSync as renameSync2 } from "fs";
3264
+ import { existsSync as existsSync13, readFileSync as readFileSync10, renameSync as renameSync2 } from "fs";
3255
3265
  import { tmpdir as tmpdir7 } from "os";
3256
- import { basename as basename9, join as join10 } from "path";
3266
+ import { basename as basename9, join as join11 } from "path";
3257
3267
 
3258
3268
  // src/lib/config.ts
3259
- import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "fs";
3260
- import { dirname as dirname7, join as join9 } from "path";
3269
+ import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync3 } from "fs";
3270
+ import { dirname as dirname7, join as join10 } from "path";
3261
3271
  import { homedir as homedir2 } from "os";
3262
3272
  var DEFAULT_CONFIG = {
3263
3273
  removeBg: {
@@ -3275,18 +3285,18 @@ var DEFAULT_CONFIG = {
3275
3285
  }
3276
3286
  };
3277
3287
  function getConfigDir() {
3278
- return join9(homedir2(), ".config", "piclet");
3288
+ return join10(homedir2(), ".config", "piclet");
3279
3289
  }
3280
3290
  function getConfigPath() {
3281
- return join9(getConfigDir(), "config.json");
3291
+ return join10(getConfigDir(), "config.json");
3282
3292
  }
3283
3293
  function loadConfig() {
3284
3294
  const configPath = getConfigPath();
3285
- if (!existsSync10(configPath)) {
3295
+ if (!existsSync12(configPath)) {
3286
3296
  return { ...DEFAULT_CONFIG };
3287
3297
  }
3288
3298
  try {
3289
- const content = readFileSync8(configPath, "utf-8");
3299
+ const content = readFileSync9(configPath, "utf-8");
3290
3300
  const loaded = JSON.parse(content);
3291
3301
  return {
3292
3302
  removeBg: { ...DEFAULT_CONFIG.removeBg, ...loaded.removeBg },
@@ -3300,8 +3310,8 @@ function loadConfig() {
3300
3310
  function resetConfig() {
3301
3311
  const configPath = getConfigPath();
3302
3312
  const configDir = dirname7(configPath);
3303
- if (!existsSync10(configDir)) {
3304
- mkdirSync6(configDir, { recursive: true });
3313
+ if (!existsSync12(configDir)) {
3314
+ mkdirSync7(configDir, { recursive: true });
3305
3315
  }
3306
3316
  writeFileSync3(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2));
3307
3317
  }
@@ -3404,7 +3414,7 @@ async function run7(inputRaw) {
3404
3414
  return false;
3405
3415
  }
3406
3416
  const input = normalizePath(inputRaw);
3407
- if (!existsSync11(input)) {
3417
+ if (!existsSync13(input)) {
3408
3418
  error(`File not found: ${input}`);
3409
3419
  await pauseOnError();
3410
3420
  return false;
@@ -3427,7 +3437,7 @@ async function run7(inputRaw) {
3427
3437
  }
3428
3438
  async function runGUI8(inputRaw) {
3429
3439
  const input = normalizePath(inputRaw);
3430
- if (!existsSync11(input)) {
3440
+ if (!existsSync13(input)) {
3431
3441
  error(`File not found: ${input}`);
3432
3442
  return false;
3433
3443
  }
@@ -3465,15 +3475,12 @@ async function runGUI8(inputRaw) {
3465
3475
  return generatePreview5(input, borderColor, options);
3466
3476
  },
3467
3477
  onProcess: async (opts) => {
3468
- const logs = [];
3469
3478
  if (!await checkImageMagick()) {
3470
3479
  return {
3471
3480
  success: false,
3472
- error: "ImageMagick not found",
3473
- logs: [{ type: "error", message: "ImageMagick not found. Install with: sudo apt install imagemagick" }]
3481
+ error: "ImageMagick not found"
3474
3482
  };
3475
3483
  }
3476
- logs.push({ type: "info", message: `Processing ${basename9(input)}...` });
3477
3484
  const options = {
3478
3485
  fuzz: opts.fuzz ?? defaults.fuzz,
3479
3486
  doTrim: opts.trim ?? defaults.trim,
@@ -3481,22 +3488,25 @@ async function runGUI8(inputRaw) {
3481
3488
  makeSquare: opts.makeSquare ?? defaults.makeSquare
3482
3489
  };
3483
3490
  const fileInfo = getFileInfo(input);
3484
- const output = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;
3485
- logs.push({ type: "info", message: "Removing background..." });
3491
+ const outputExt = fileInfo.extension.toLowerCase() === ".gif" ? ".gif" : ".png";
3492
+ const output = `${fileInfo.dirname}/${fileInfo.filename}_nobg${outputExt}`;
3493
+ const logs = [];
3486
3494
  const success2 = await processImageSilent(input, borderColor, options, logs);
3487
- if (success2) {
3495
+ if (success2 && existsSync13(output)) {
3488
3496
  const finalDims = await getDimensions(output);
3489
3497
  const sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : "";
3498
+ const buffer = readFileSync10(output);
3499
+ const mimeType = outputExt === ".gif" ? "image/gif" : "image/png";
3500
+ const imageData = `data:${mimeType};base64,${buffer.toString("base64")}`;
3490
3501
  return {
3491
3502
  success: true,
3492
3503
  output: `${basename9(output)}${sizeStr}`,
3493
- logs
3504
+ imageData
3494
3505
  };
3495
3506
  }
3496
3507
  return {
3497
3508
  success: false,
3498
- error: "Processing failed",
3499
- logs
3509
+ error: "Processing failed"
3500
3510
  };
3501
3511
  }
3502
3512
  });
@@ -3555,9 +3565,9 @@ async function processImageSilent(input, borderColor, options, logs) {
3555
3565
  async function generatePreview5(input, borderColor, options) {
3556
3566
  const tempDir = tmpdir7();
3557
3567
  const timestamp = Date.now();
3558
- const tempSource = join10(tempDir, `piclet-preview-${timestamp}-src.png`);
3559
- const tempFile = join10(tempDir, `piclet-preview-${timestamp}.png`);
3560
- const tempOutput = join10(tempDir, `piclet-preview-${timestamp}-out.png`);
3568
+ const tempSource = join11(tempDir, `piclet-preview-${timestamp}-src.png`);
3569
+ const tempFile = join11(tempDir, `piclet-preview-${timestamp}.png`);
3570
+ const tempOutput = join11(tempDir, `piclet-preview-${timestamp}-out.png`);
3561
3571
  try {
3562
3572
  let previewInput = input;
3563
3573
  if (isMultiFrame(input)) {
@@ -3585,13 +3595,13 @@ async function generatePreview5(input, borderColor, options) {
3585
3595
  }
3586
3596
  }
3587
3597
  if (options.makeSquare) {
3588
- const squareFile = join10(tempDir, `piclet-preview-${timestamp}-sq.png`);
3598
+ const squareFile = join11(tempDir, `piclet-preview-${timestamp}-sq.png`);
3589
3599
  if (await squarify(currentFile, squareFile)) {
3590
3600
  cleanup(currentFile);
3591
3601
  currentFile = squareFile;
3592
3602
  }
3593
3603
  }
3594
- const buffer = readFileSync9(currentFile);
3604
+ const buffer = readFileSync10(currentFile);
3595
3605
  const base64 = buffer.toString("base64");
3596
3606
  const imageData = `data:image/png;base64,${base64}`;
3597
3607
  const dims = await getDimensions(currentFile);
@@ -3615,9 +3625,9 @@ var config8 = {
3615
3625
  };
3616
3626
 
3617
3627
  // src/tools/rescale.ts
3618
- import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
3628
+ import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
3619
3629
  import { tmpdir as tmpdir8 } from "os";
3620
- import { basename as basename10, join as join11 } from "path";
3630
+ import { basename as basename10, join as join12 } from "path";
3621
3631
  async function run8(inputRaw) {
3622
3632
  if (!await checkImageMagick()) {
3623
3633
  error("ImageMagick not found. Please install it:");
@@ -3626,7 +3636,7 @@ async function run8(inputRaw) {
3626
3636
  return false;
3627
3637
  }
3628
3638
  const input = normalizePath(inputRaw);
3629
- if (!existsSync12(input)) {
3639
+ if (!existsSync14(input)) {
3630
3640
  error(`File not found: ${input}`);
3631
3641
  await pauseOnError();
3632
3642
  return false;
@@ -3687,7 +3697,7 @@ async function run8(inputRaw) {
3687
3697
  } else {
3688
3698
  scaled = await resize(input, output, targetW, targetH);
3689
3699
  }
3690
- if (!scaled || !existsSync12(output)) {
3700
+ if (!scaled || !existsSync14(output)) {
3691
3701
  wipDone(false, "Scaling failed");
3692
3702
  return false;
3693
3703
  }
@@ -3703,7 +3713,7 @@ async function run8(inputRaw) {
3703
3713
  }
3704
3714
  async function runGUI9(inputRaw) {
3705
3715
  const input = normalizePath(inputRaw);
3706
- if (!existsSync12(input)) {
3716
+ if (!existsSync14(input)) {
3707
3717
  error(`File not found: ${input}`);
3708
3718
  return false;
3709
3719
  }
@@ -3757,7 +3767,7 @@ async function runGUI9(inputRaw) {
3757
3767
  } else {
3758
3768
  scaled = await resize(input, output, options.width, options.height);
3759
3769
  }
3760
- if (scaled && existsSync12(output)) {
3770
+ if (scaled && existsSync14(output)) {
3761
3771
  const finalDims = await getDimensions(output);
3762
3772
  const sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : "";
3763
3773
  logs.push({ type: "success", message: "Scaled successfully" });
@@ -3775,8 +3785,8 @@ async function runGUI9(inputRaw) {
3775
3785
  async function generatePreview6(input, options) {
3776
3786
  const tempDir = tmpdir8();
3777
3787
  const timestamp = Date.now();
3778
- const tempSource = join11(tempDir, `piclet-preview-${timestamp}-src.png`);
3779
- const tempOutput = join11(tempDir, `piclet-preview-${timestamp}.png`);
3788
+ const tempSource = join12(tempDir, `piclet-preview-${timestamp}-src.png`);
3789
+ const tempOutput = join12(tempDir, `piclet-preview-${timestamp}.png`);
3780
3790
  try {
3781
3791
  let previewInput = input;
3782
3792
  if (isMultiFrame(input)) {
@@ -3796,11 +3806,11 @@ async function generatePreview6(input, options) {
3796
3806
  } else {
3797
3807
  scaled = await resize(previewInput, tempOutput, targetW, targetH);
3798
3808
  }
3799
- if (!scaled || !existsSync12(tempOutput)) {
3809
+ if (!scaled || !existsSync14(tempOutput)) {
3800
3810
  cleanup(tempSource);
3801
3811
  return { success: false, error: "Scaling failed" };
3802
3812
  }
3803
- const buffer = readFileSync10(tempOutput);
3813
+ const buffer = readFileSync11(tempOutput);
3804
3814
  const base64 = buffer.toString("base64");
3805
3815
  const imageData = `data:image/png;base64,${base64}`;
3806
3816
  const dims = await getDimensions(tempOutput);
@@ -3824,8 +3834,8 @@ var config9 = {
3824
3834
  };
3825
3835
 
3826
3836
  // src/tools/storepack.ts
3827
- import { existsSync as existsSync13, mkdirSync as mkdirSync7 } from "fs";
3828
- import { basename as basename11, join as join12 } from "path";
3837
+ import { existsSync as existsSync15, mkdirSync as mkdirSync8 } from "fs";
3838
+ import { basename as basename11, join as join13 } from "path";
3829
3839
  async function scaleImage(input, output, width, height, mode) {
3830
3840
  switch (mode) {
3831
3841
  case "fill":
@@ -3842,7 +3852,7 @@ async function generatePresetImages(sourceImg, outputDir, preset, scaleMode = "f
3842
3852
  const total = preset.icons.length;
3843
3853
  for (let i = 0; i < total; i++) {
3844
3854
  const icon = preset.icons[i];
3845
- const outputPath = join12(outputDir, icon.filename);
3855
+ const outputPath = join13(outputDir, icon.filename);
3846
3856
  if (logs) {
3847
3857
  logs.push({ type: "info", message: `[${i + 1}/${total}] ${icon.filename}` });
3848
3858
  } else {
@@ -3878,7 +3888,7 @@ async function run9(inputRaw) {
3878
3888
  return false;
3879
3889
  }
3880
3890
  const input = normalizePath(inputRaw);
3881
- if (!existsSync13(input)) {
3891
+ if (!existsSync15(input)) {
3882
3892
  error(`File not found: ${input}`);
3883
3893
  await pauseOnError();
3884
3894
  return false;
@@ -3906,11 +3916,11 @@ async function run9(inputRaw) {
3906
3916
  return false;
3907
3917
  }
3908
3918
  const outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${preset.id}`;
3909
- mkdirSync7(outputDir, { recursive: true });
3919
+ mkdirSync8(outputDir, { recursive: true });
3910
3920
  info(`Output: ${outputDir}`);
3911
3921
  console.log("");
3912
3922
  wip("Preparing source...");
3913
- const tempSource = join12(outputDir, ".source.png");
3923
+ const tempSource = join13(outputDir, ".source.png");
3914
3924
  if (!await squarify(input, tempSource)) {
3915
3925
  wipDone(false, "Failed to prepare source");
3916
3926
  return false;
@@ -3931,7 +3941,7 @@ async function run9(inputRaw) {
3931
3941
  }
3932
3942
  async function runGUI10(inputRaw) {
3933
3943
  const input = normalizePath(inputRaw);
3934
- if (!existsSync13(input)) {
3944
+ if (!existsSync15(input)) {
3935
3945
  error(`File not found: ${input}`);
3936
3946
  return false;
3937
3947
  }
@@ -3980,7 +3990,7 @@ async function runGUI10(inputRaw) {
3980
3990
  };
3981
3991
  }
3982
3992
  const outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${preset.id}`;
3983
- mkdirSync7(outputDir, { recursive: true });
3993
+ mkdirSync8(outputDir, { recursive: true });
3984
3994
  logs.push({ type: "info", message: `Output: ${outputDir}` });
3985
3995
  logs.push({ type: "info", message: `Scale mode: ${scaleMode}` });
3986
3996
  logs.push({ type: "info", message: `Generating ${preset.icons.length} images...` });
@@ -4009,9 +4019,9 @@ var config10 = {
4009
4019
  };
4010
4020
 
4011
4021
  // src/tools/transform.ts
4012
- import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
4022
+ import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
4013
4023
  import { tmpdir as tmpdir9 } from "os";
4014
- import { basename as basename12, join as join13 } from "path";
4024
+ import { basename as basename12, join as join14 } from "path";
4015
4025
  var TRANSFORM_LABELS = {
4016
4026
  "flip-h": "Flip Horizontal",
4017
4027
  "flip-v": "Flip Vertical",
@@ -4087,7 +4097,7 @@ async function run10(inputRaw) {
4087
4097
  return false;
4088
4098
  }
4089
4099
  const input = normalizePath(inputRaw);
4090
- if (!existsSync14(input)) {
4100
+ if (!existsSync16(input)) {
4091
4101
  error(`File not found: ${input}`);
4092
4102
  await pauseOnError();
4093
4103
  return false;
@@ -4106,7 +4116,7 @@ async function run10(inputRaw) {
4106
4116
  }
4107
4117
  async function runGUI11(inputRaw) {
4108
4118
  const input = normalizePath(inputRaw);
4109
- if (!existsSync14(input)) {
4119
+ if (!existsSync16(input)) {
4110
4120
  error(`File not found: ${input}`);
4111
4121
  return false;
4112
4122
  }
@@ -4189,8 +4199,8 @@ async function runGUI11(inputRaw) {
4189
4199
  async function generatePreview7(input, options) {
4190
4200
  const tempDir = tmpdir9();
4191
4201
  const timestamp = Date.now();
4192
- const tempSource = join13(tempDir, `piclet-preview-${timestamp}-src.png`);
4193
- const tempOutput = join13(tempDir, `piclet-preview-${timestamp}.png`);
4202
+ const tempSource = join14(tempDir, `piclet-preview-${timestamp}-src.png`);
4203
+ const tempOutput = join14(tempDir, `piclet-preview-${timestamp}.png`);
4194
4204
  try {
4195
4205
  let previewInput = input;
4196
4206
  if (isMultiFrame(input)) {
@@ -4221,7 +4231,7 @@ async function generatePreview7(input, options) {
4221
4231
  cleanup(tempSource, tempOutput);
4222
4232
  return { success: false, error: "Transform failed" };
4223
4233
  }
4224
- const buffer = readFileSync11(tempOutput);
4234
+ const buffer = readFileSync12(tempOutput);
4225
4235
  const base64 = buffer.toString("base64");
4226
4236
  const imageData = `data:image/png;base64,${base64}`;
4227
4237
  const dims = await getDimensions(tempOutput);
@@ -4278,6 +4288,10 @@ function getToolsForExtension(extension) {
4278
4288
  }
4279
4289
 
4280
4290
  // src/cli/utils.ts
4291
+ import { extname as extname4 } from "path";
4292
+ import { dirname as dirname9 } from "path";
4293
+ import { fileURLToPath as fileURLToPath2 } from "url";
4294
+ import chalk2 from "chalk";
4281
4295
  function getDistDir() {
4282
4296
  const currentFile = fileURLToPath2(import.meta.url);
4283
4297
  return dirname9(currentFile);
@@ -4289,7 +4303,7 @@ function validateExtensions(files, allowedExtensions) {
4289
4303
  const valid = [];
4290
4304
  const invalid = [];
4291
4305
  for (const file of files) {
4292
- const ext = extname3(file).toLowerCase();
4306
+ const ext = extname4(file).toLowerCase();
4293
4307
  if (allowedExtensions.includes(ext)) {
4294
4308
  valid.push(file);
4295
4309
  } else {
@@ -4301,17 +4315,17 @@ function validateExtensions(files, allowedExtensions) {
4301
4315
  async function runToolOnFiles(toolId, files, useYes) {
4302
4316
  const tool = getTool(toolId);
4303
4317
  if (!tool) {
4304
- console.error(chalk.red(`Tool not found: ${toolId}`));
4318
+ console.error(chalk2.red(`Tool not found: ${toolId}`));
4305
4319
  return false;
4306
4320
  }
4307
4321
  const { valid, invalid } = validateExtensions(files, tool.config.extensions);
4308
4322
  if (invalid.length > 0) {
4309
- console.error(chalk.red("Invalid file types:"));
4323
+ console.error(chalk2.red("Invalid file types:"));
4310
4324
  for (const file of invalid) {
4311
- console.error(chalk.red(` \u2717 ${file}`));
4325
+ console.error(chalk2.red(` \u2717 ${file}`));
4312
4326
  }
4313
4327
  console.error(
4314
- chalk.yellow(
4328
+ chalk2.yellow(
4315
4329
  `
4316
4330
  Supported extensions: ${tool.config.extensions.join(", ")}`
4317
4331
  )
@@ -4326,7 +4340,7 @@ Supported extensions: ${tool.config.extensions.join(", ")}`
4326
4340
  for (let i = 0; i < valid.length; i++) {
4327
4341
  const file = valid[i];
4328
4342
  if (valid.length > 1) {
4329
- console.log(chalk.cyan(`
4343
+ console.log(chalk2.cyan(`
4330
4344
  [${i + 1}/${valid.length}] ${file}`));
4331
4345
  }
4332
4346
  const success2 = await tool.run(file);
@@ -4341,15 +4355,15 @@ function registerBorderCommand(program2) {
4341
4355
  if (options.gui) {
4342
4356
  const { valid, invalid } = validateExtensions(files, config.extensions);
4343
4357
  if (invalid.length > 0) {
4344
- console.error(chalk2.red("Invalid file types:"));
4358
+ console.error(chalk3.red("Invalid file types:"));
4345
4359
  for (const file of invalid) {
4346
- console.error(chalk2.red(` - ${file}`));
4360
+ console.error(chalk3.red(` - ${file}`));
4347
4361
  }
4348
4362
  }
4349
4363
  if (valid.length === 0) {
4350
4364
  process.exit(1);
4351
4365
  }
4352
- const result = await runGUI(valid[0]);
4366
+ const result = await picletTool.runGUI(valid[0]);
4353
4367
  process.exit(result ? 0 : 1);
4354
4368
  }
4355
4369
  const success2 = await runToolOnFiles(
@@ -4362,38 +4376,38 @@ function registerBorderCommand(program2) {
4362
4376
  }
4363
4377
 
4364
4378
  // src/cli/commands/config.ts
4365
- import chalk3 from "chalk";
4379
+ import chalk4 from "chalk";
4366
4380
  function registerConfigCommand(program2) {
4367
4381
  const configCmd = program2.command("config").description("Display current settings").action(() => {
4368
4382
  const config12 = loadConfig();
4369
- console.log(chalk3.white.bold("\n PicLet Configuration"));
4370
- console.log(chalk3.gray(` ${getConfigPath()}
4383
+ console.log(chalk4.white.bold("\n PicLet Configuration"));
4384
+ console.log(chalk4.gray(` ${getConfigPath()}
4371
4385
  `));
4372
4386
  console.log(JSON.stringify(config12, null, 2));
4373
4387
  console.log();
4374
4388
  });
4375
4389
  configCmd.command("reset").description("Restore defaults").action(() => {
4376
4390
  resetConfig();
4377
- console.log(chalk3.green("Configuration reset to defaults."));
4391
+ console.log(chalk4.green("Configuration reset to defaults."));
4378
4392
  });
4379
4393
  }
4380
4394
 
4381
4395
  // src/cli/commands/extract-frames.ts
4382
- import chalk4 from "chalk";
4396
+ import chalk5 from "chalk";
4383
4397
  function registerExtractFramesCommand(program2) {
4384
- program2.command("extract-frames <files...>").alias("frames").description("Extract frames from animated GIF").option("-y, --yes", "Use defaults, skip prompts").option("-g, --gui", "Use GUI for options").action(async (files, options) => {
4398
+ program2.command("extract-frames <files...>").alias("frames").alias("gif").description("Extract frames from animated GIF").option("-y, --yes", "Use defaults, skip prompts").option("-g, --gui", "Use GUI for options").action(async (files, options) => {
4385
4399
  if (options.gui) {
4386
4400
  const { valid, invalid } = validateExtensions(files, config2.extensions);
4387
4401
  if (invalid.length > 0) {
4388
- console.error(chalk4.red("Invalid file types:"));
4402
+ console.error(chalk5.red("Invalid file types:"));
4389
4403
  for (const file of invalid) {
4390
- console.error(chalk4.red(` - ${file}`));
4404
+ console.error(chalk5.red(` - ${file}`));
4391
4405
  }
4392
4406
  }
4393
4407
  if (valid.length === 0) {
4394
4408
  process.exit(1);
4395
4409
  }
4396
- const result = await runGUI2(valid[0]);
4410
+ const result = await picletTool.runGUI(valid[0]);
4397
4411
  process.exit(result ? 0 : 1);
4398
4412
  }
4399
4413
  const success2 = await runToolOnFiles(
@@ -4406,21 +4420,21 @@ function registerExtractFramesCommand(program2) {
4406
4420
  }
4407
4421
 
4408
4422
  // src/cli/commands/filter.ts
4409
- import chalk5 from "chalk";
4423
+ import chalk6 from "chalk";
4410
4424
  function registerFilterCommand(program2) {
4411
4425
  program2.command("filter <files...>").description("Apply color filters (grayscale, sepia, etc.)").option("-y, --yes", "Use defaults, skip prompts").option("-g, --gui", "Use GUI for options").action(async (files, options) => {
4412
4426
  if (options.gui) {
4413
4427
  const { valid, invalid } = validateExtensions(files, config3.extensions);
4414
4428
  if (invalid.length > 0) {
4415
- console.error(chalk5.red("Invalid file types:"));
4429
+ console.error(chalk6.red("Invalid file types:"));
4416
4430
  for (const file of invalid) {
4417
- console.error(chalk5.red(` - ${file}`));
4431
+ console.error(chalk6.red(` - ${file}`));
4418
4432
  }
4419
4433
  }
4420
4434
  if (valid.length === 0) {
4421
4435
  process.exit(1);
4422
4436
  }
4423
- const result = await runGUI3(valid[0]);
4437
+ const result = await picletTool.runGUI(valid[0]);
4424
4438
  process.exit(result ? 0 : 1);
4425
4439
  }
4426
4440
  const success2 = await runToolOnFiles(
@@ -4440,21 +4454,21 @@ function registerHelpCommand(program2) {
4440
4454
  }
4441
4455
 
4442
4456
  // src/cli/commands/iconpack.ts
4443
- import chalk6 from "chalk";
4457
+ import chalk7 from "chalk";
4444
4458
  function registerIconpackCommand(program2) {
4445
4459
  program2.command("iconpack <files...>").description("Generate icon sets for Web, Android, iOS").option("-y, --yes", "Use defaults, skip prompts").option("-g, --gui", "Use GUI for options").action(async (files, options) => {
4446
4460
  if (options.gui) {
4447
4461
  const { valid, invalid } = validateExtensions(files, config4.extensions);
4448
4462
  if (invalid.length > 0) {
4449
- console.error(chalk6.red("Invalid file types:"));
4463
+ console.error(chalk7.red("Invalid file types:"));
4450
4464
  for (const file of invalid) {
4451
- console.error(chalk6.red(` - ${file}`));
4465
+ console.error(chalk7.red(` - ${file}`));
4452
4466
  }
4453
4467
  }
4454
4468
  if (valid.length === 0) {
4455
4469
  process.exit(1);
4456
4470
  }
4457
- const result = await runGUI4(valid[0]);
4471
+ const result = await picletTool.runGUI(valid[0]);
4458
4472
  process.exit(result ? 0 : 1);
4459
4473
  }
4460
4474
  const success2 = await runToolOnFiles(
@@ -4467,11 +4481,11 @@ function registerIconpackCommand(program2) {
4467
4481
  }
4468
4482
 
4469
4483
  // src/cli/commands/install.ts
4470
- import chalk7 from "chalk";
4484
+ import chalk8 from "chalk";
4471
4485
 
4472
4486
  // src/lib/registry.ts
4473
4487
  import { exec as exec2 } from "child_process";
4474
- import { existsSync as existsSync15 } from "fs";
4488
+ import { existsSync as existsSync17 } from "fs";
4475
4489
  import { dirname as dirname10 } from "path";
4476
4490
  import { fileURLToPath as fileURLToPath3 } from "url";
4477
4491
  import { promisify as promisify2 } from "util";
@@ -4480,7 +4494,7 @@ function isWSL() {
4480
4494
  return process.platform === "linux" && (process.env.WSL_DISTRO_NAME !== void 0 || process.env.WSLENV !== void 0);
4481
4495
  }
4482
4496
  function isWSLInteropEnabled() {
4483
- return existsSync15("/proc/sys/fs/binfmt_misc/WSLInterop");
4497
+ return existsSync17("/proc/sys/fs/binfmt_misc/WSLInterop");
4484
4498
  }
4485
4499
  async function addRegistryKey(keyPath, valueName, value, type = "REG_SZ") {
4486
4500
  const valueArg = valueName ? `/v "${valueName}"` : "/ve";
@@ -4522,7 +4536,7 @@ async function deleteRegistryKey(keyPath) {
4522
4536
 
4523
4537
  // src/cli/registry.ts
4524
4538
  import { writeFile } from "fs/promises";
4525
- import { join as join14 } from "path";
4539
+ import { join as join15 } from "path";
4526
4540
  async function registerUnifiedMenu(extension, iconsDir, launcherPath) {
4527
4541
  const basePath = `HKCU\\Software\\Classes\\SystemFileAssociations\\${extension}\\shell\\PicLet`;
4528
4542
  const iconsDirWin = wslToWindows(iconsDir);
@@ -4558,8 +4572,8 @@ async function unregisterMenuForExtension(extension) {
4558
4572
  }
4559
4573
  async function registerAllTools() {
4560
4574
  const distDir = getDistDir();
4561
- const iconsDir = join14(distDir, "icons");
4562
- const launcherPath = join14(distDir, "launcher.vbs");
4575
+ const iconsDir = join15(distDir, "icons");
4576
+ const launcherPath = join15(distDir, "launcher.vbs");
4563
4577
  const results = [];
4564
4578
  for (const extension of picletTool.config.extensions) {
4565
4579
  const result = await registerUnifiedMenu(extension, iconsDir, launcherPath);
@@ -4635,8 +4649,8 @@ function escapeRegValue(value) {
4635
4649
  }
4636
4650
  function generateRegContent() {
4637
4651
  const distDir = getDistDir();
4638
- const iconsDir = join14(distDir, "icons");
4639
- const launcherPath = join14(distDir, "launcher.vbs");
4652
+ const iconsDir = join15(distDir, "icons");
4653
+ const launcherPath = join15(distDir, "launcher.vbs");
4640
4654
  const iconsDirWin = wslToWindows(iconsDir);
4641
4655
  const launcherWin = wslToWindows(launcherPath);
4642
4656
  const lines = ["Windows Registry Editor Version 5.00", ""];
@@ -4673,14 +4687,14 @@ function generateUninstallRegContent() {
4673
4687
  }
4674
4688
  async function generateRegFile() {
4675
4689
  const distDir = getDistDir();
4676
- const regPath = join14(distDir, "piclet-install.reg");
4690
+ const regPath = join15(distDir, "piclet-install.reg");
4677
4691
  const content = generateRegContent();
4678
4692
  await writeFile(regPath, content, "utf-8");
4679
4693
  return regPath;
4680
4694
  }
4681
4695
  async function generateUninstallRegFile() {
4682
4696
  const distDir = getDistDir();
4683
- const regPath = join14(distDir, "piclet-uninstall.reg");
4697
+ const regPath = join15(distDir, "piclet-uninstall.reg");
4684
4698
  const content = generateUninstallRegContent();
4685
4699
  await writeFile(regPath, content, "utf-8");
4686
4700
  return regPath;
@@ -4689,86 +4703,95 @@ async function generateUninstallRegFile() {
4689
4703
  // src/cli/commands/install.ts
4690
4704
  function registerInstallCommand(program2) {
4691
4705
  program2.command("install").description("Install Windows shell context menu integration").action(async () => {
4706
+ console.log(chalk8.bold("Installing...\n"));
4692
4707
  showBanner();
4693
- console.log(chalk7.bold("Installing...\n"));
4694
4708
  if (!isWSL()) {
4695
4709
  console.log(
4696
- chalk7.yellow("! Not running in WSL. Registry integration skipped.")
4710
+ chalk8.yellow("! Not running in WSL. Registry integration skipped.")
4697
4711
  );
4698
4712
  console.log(
4699
- chalk7.yellow('! Run "piclet install" from WSL to add context menu.')
4713
+ chalk8.yellow('! Run "piclet install" from WSL to add context menu.')
4700
4714
  );
4701
4715
  return;
4702
4716
  }
4703
4717
  if (!isWSLInteropEnabled()) {
4704
- console.log(chalk7.yellow("WSL Interop not available. Generating registry file...\n"));
4718
+ console.log(chalk8.yellow("WSL Interop not available. Generating registry file...\n"));
4705
4719
  const regPath = await generateRegFile();
4706
4720
  const winPath = wslToWindows(regPath);
4707
- console.log(chalk7.green("\u2713 Generated registry file:"));
4708
- console.log(chalk7.cyan(` ${winPath}
4721
+ console.log(chalk8.green("\u2713 Generated registry file:"));
4722
+ console.log(chalk8.cyan(` ${winPath}
4709
4723
  `));
4710
- console.log(chalk7.bold("To install, either:"));
4711
- console.log(chalk7.dim(" 1. Double-click the .reg file in Windows Explorer"));
4712
- console.log(chalk7.dim(` 2. Run in elevated PowerShell: reg import "${winPath}"`));
4713
- console.log();
4724
+ console.log(chalk8.bold("To install, either:"));
4725
+ console.log(chalk8.dim(" 1. Double-click the .reg file in Windows Explorer"));
4726
+ console.log(chalk8.dim(` 2. Run in elevated PowerShell: reg import "${winPath}"`));
4714
4727
  return;
4715
4728
  }
4716
- console.log(chalk7.dim("Removing old entries..."));
4717
4729
  await unregisterAllTools();
4718
- console.log();
4719
- const results = await registerAllTools();
4720
- const allSuccess = results.every((r) => r.success);
4721
- for (const { config: config12 } of tools) {
4722
- const extList = config12.extensions.join(", ");
4723
- console.log(`${chalk7.green("\u2713")} ${config12.name} ${chalk7.dim(`[${extList}]`)}`);
4724
- }
4725
- console.log();
4726
- if (allSuccess) {
4727
- console.log(
4728
- chalk7.green(`\u2713 Registered ${tools.length} tools for context menu.`)
4729
- );
4730
- } else {
4731
- const successCount = results.filter((r) => r.success).length;
4732
- console.log(
4733
- chalk7.yellow(`! Registered ${successCount}/${results.length} entries.`)
4734
- );
4735
- }
4736
- console.log(chalk7.bold("\nContext Menu Usage:"));
4730
+ await registerAllTools();
4731
+ const dim = chalk8.gray;
4732
+ const cmd = chalk8.cyan;
4733
+ const arg = chalk8.hex("#cc8800");
4734
+ const opt = chalk8.green;
4735
+ const head = chalk8.white.bold;
4736
+ console.log(chalk8.bold("\nContext Menu Usage:"));
4737
4737
  console.log(" Right-click any supported image in Windows Explorer.");
4738
4738
  console.log(" Multi-select supported for batch processing.");
4739
- console.log(chalk7.bold("\nCLI Usage:"));
4740
- console.log(chalk7.cyan(" piclet <image>") + chalk7.dim(" Open GUI editor"));
4741
- console.log(chalk7.cyan(" piclet makeicon <img>") + chalk7.dim(" Convert to .ico"));
4742
- console.log(chalk7.cyan(" piclet remove-bg <img>") + chalk7.dim(" Remove background"));
4743
- console.log(chalk7.cyan(" piclet scale <img>") + chalk7.dim(" Resize image"));
4744
- console.log(chalk7.cyan(" piclet iconpack <img>") + chalk7.dim(" Generate icon pack"));
4745
- console.log(chalk7.cyan(" piclet storepack <img>") + chalk7.dim(" Generate store assets"));
4746
- console.log(chalk7.cyan(" piclet transform <img>") + chalk7.dim(" Rotate/flip image"));
4747
- console.log(chalk7.cyan(" piclet filter <img>") + chalk7.dim(" Apply filters"));
4748
- console.log(chalk7.cyan(" piclet border <img>") + chalk7.dim(" Add border"));
4749
- console.log(chalk7.cyan(" piclet recolor <img>") + chalk7.dim(" Replace colors"));
4750
- console.log(chalk7.cyan(" piclet extract-frames <gif>") + chalk7.dim(" Extract GIF frames"));
4751
- console.log(chalk7.dim('\n Run "piclet --help" for full documentation.'));
4739
+ console.log(arg(" Supported image types: [.png, .jpg, .jpeg, .gif, .bmp, .ico]"));
4740
+ console.log(head("\nCLI Usage:"));
4741
+ console.log(
4742
+ ` ${head("Usage:")} piclet ${cmd("<command>")} ${arg("<file>")} ${opt("[options]")}`
4743
+ );
4744
+ console.log();
4745
+ console.log(head(" GUI"));
4746
+ console.log(
4747
+ ` ${cmd("piclet")} ${arg("<file>")} Opens PicLet GUI window with all tools`
4748
+ );
4749
+ console.log();
4750
+ console.log(head(" Setup"));
4751
+ console.log(` ${cmd("install")} Add Windows right-click menu`);
4752
+ console.log(` ${cmd("uninstall")} Remove right-click menu`);
4753
+ console.log();
4754
+ console.log(head(" Config"));
4755
+ console.log(` ${cmd("config")} Display current settings`);
4756
+ console.log(` ${cmd("config reset")} Restore defaults`);
4757
+ console.log();
4758
+ console.log(head(" Prerequisites"));
4759
+ console.log(" - WSL (Windows Subsystem for Linux)");
4760
+ console.log(" - ImageMagick: sudo apt install imagemagick");
4761
+ console.log();
4762
+ console.log(head(" Examples"));
4763
+ console.log(` ${dim("$")} piclet ${cmd("piclet")} ${arg("image.png")} ${dim("# All tools in one window")}`);
4764
+ console.log(` ${dim("$")} piclet ${cmd("makeicon")} ${arg("logo.png")} ${dim("# Interactive")}`);
4765
+ console.log(` ${dim("$")} piclet ${cmd("makeicon")} ${arg("*.png")} ${opt("-y")} ${dim("# Batch with defaults")}`);
4766
+ console.log(` ${dim("$")} piclet ${cmd("remove-bg")} ${arg("photo.png")} ${dim("# Interactive prompts")}`);
4767
+ console.log(` ${dim("$")} piclet ${cmd("scale")} ${arg("image.jpg")} ${dim("# Interactive resize")}`);
4768
+ console.log(` ${dim("$")} piclet ${cmd("gif")} ${arg("anim.gif")} ${dim("# Extract GIF frames")}`);
4769
+ console.log(` ${dim("$")} piclet ${cmd("iconpack")} ${arg("icon.png")} ${opt("-y")} ${dim("# All platforms")}`);
4770
+ console.log(` ${dim("$")} piclet ${cmd("storepack")} ${arg("image.png")} ${opt("-g")} ${dim("# GUI for store assets")}`);
4771
+ console.log(
4772
+ `
4773
+ Run "piclet ${opt("--help")}" for full documentation.`
4774
+ );
4752
4775
  console.log();
4753
4776
  });
4754
4777
  }
4755
4778
 
4756
4779
  // src/cli/commands/makeicon.ts
4757
- import chalk8 from "chalk";
4780
+ import chalk9 from "chalk";
4758
4781
  function registerMakeiconCommand(program2) {
4759
4782
  program2.command("makeicon <files...>").description("Convert PNG to multi-resolution ICO file").option("-y, --yes", "Use defaults, skip prompts").option("-g, --gui", "Use GUI for confirmation").action(async (files, options) => {
4760
4783
  if (options.gui) {
4761
4784
  const { valid, invalid } = validateExtensions(files, config5.extensions);
4762
4785
  if (invalid.length > 0) {
4763
- console.error(chalk8.red("Invalid file types:"));
4786
+ console.error(chalk9.red("Invalid file types:"));
4764
4787
  for (const file of invalid) {
4765
- console.error(chalk8.red(` - ${file}`));
4788
+ console.error(chalk9.red(` - ${file}`));
4766
4789
  }
4767
4790
  }
4768
4791
  if (valid.length === 0) {
4769
4792
  process.exit(1);
4770
4793
  }
4771
- const result = await runGUI5(valid[0]);
4794
+ const result = await picletTool.runGUI(valid[0]);
4772
4795
  process.exit(result ? 0 : 1);
4773
4796
  }
4774
4797
  const success2 = await runToolOnFiles(
@@ -4781,13 +4804,13 @@ function registerMakeiconCommand(program2) {
4781
4804
  }
4782
4805
 
4783
4806
  // src/cli/commands/piclet.ts
4784
- import chalk9 from "chalk";
4807
+ import chalk10 from "chalk";
4785
4808
  function registerPicletCommand(program2) {
4786
4809
  program2.command("piclet <file>").description("Open unified PicLet window with all tools").option("-g, --gui", "Use GUI (default)").action(async (file) => {
4787
4810
  const { valid, invalid } = validateExtensions([file], picletTool.config.extensions);
4788
4811
  if (invalid.length > 0) {
4789
- console.error(chalk9.red(`Invalid file type: ${file}`));
4790
- console.error(chalk9.yellow(`Supported: ${picletTool.config.extensions.join(", ")}`));
4812
+ console.error(chalk10.red(`Invalid file type: ${file}`));
4813
+ console.error(chalk10.yellow(`Supported: ${picletTool.config.extensions.join(", ")}`));
4791
4814
  process.exit(1);
4792
4815
  }
4793
4816
  const result = await picletTool.runGUI(valid[0]);
@@ -4796,21 +4819,21 @@ function registerPicletCommand(program2) {
4796
4819
  }
4797
4820
 
4798
4821
  // src/cli/commands/recolor.ts
4799
- import chalk10 from "chalk";
4822
+ import chalk11 from "chalk";
4800
4823
  function registerRecolorCommand(program2) {
4801
4824
  program2.command("recolor <files...>").alias("replace-color").description("Replace one color with another").option("-y, --yes", "Use defaults, skip prompts").option("-g, --gui", "Use GUI for options").action(async (files, options) => {
4802
4825
  if (options.gui) {
4803
4826
  const { valid, invalid } = validateExtensions(files, config7.extensions);
4804
4827
  if (invalid.length > 0) {
4805
- console.error(chalk10.red("Invalid file types:"));
4828
+ console.error(chalk11.red("Invalid file types:"));
4806
4829
  for (const file of invalid) {
4807
- console.error(chalk10.red(` - ${file}`));
4830
+ console.error(chalk11.red(` - ${file}`));
4808
4831
  }
4809
4832
  }
4810
4833
  if (valid.length === 0) {
4811
4834
  process.exit(1);
4812
4835
  }
4813
- const result = await runGUI7(valid[0]);
4836
+ const result = await picletTool.runGUI(valid[0]);
4814
4837
  process.exit(result ? 0 : 1);
4815
4838
  }
4816
4839
  const success2 = await runToolOnFiles(
@@ -4823,21 +4846,21 @@ function registerRecolorCommand(program2) {
4823
4846
  }
4824
4847
 
4825
4848
  // src/cli/commands/remove-bg.ts
4826
- import chalk11 from "chalk";
4849
+ import chalk12 from "chalk";
4827
4850
  function registerRemoveBgCommand(program2) {
4828
4851
  program2.command("remove-bg <files...>").alias("removebg").description("Remove solid background from image").option("-y, --yes", "Use defaults, skip prompts").option("-g, --gui", "Use TUI (terminal GUI) for options").option("-f, --fuzz <percent>", "Fuzz tolerance 0-100 (default: 10)").option("-t, --trim", "Trim transparent edges (default: true)").option("--no-trim", "Do not trim transparent edges").option("-p, --preserve-inner", "Preserve inner areas of same color").option("-s, --square", "Make output square with padding").action(async (files, options) => {
4829
4852
  if (options.gui) {
4830
4853
  const { valid, invalid } = validateExtensions(files, config8.extensions);
4831
4854
  if (invalid.length > 0) {
4832
- console.error(chalk11.red("Invalid file types:"));
4855
+ console.error(chalk12.red("Invalid file types:"));
4833
4856
  for (const file of invalid) {
4834
- console.error(chalk11.red(` - ${file}`));
4857
+ console.error(chalk12.red(` - ${file}`));
4835
4858
  }
4836
4859
  }
4837
4860
  if (valid.length === 0) {
4838
4861
  process.exit(1);
4839
4862
  }
4840
- const result = await runGUI8(valid[0]);
4863
+ const result = await picletTool.runGUI(valid[0]);
4841
4864
  process.exit(result ? 0 : 1);
4842
4865
  }
4843
4866
  if (options.fuzz !== void 0) {
@@ -4863,21 +4886,21 @@ function registerRemoveBgCommand(program2) {
4863
4886
  }
4864
4887
 
4865
4888
  // src/cli/commands/scale.ts
4866
- import chalk12 from "chalk";
4889
+ import chalk13 from "chalk";
4867
4890
  function registerScaleCommand(program2) {
4868
4891
  program2.command("scale <files...>").alias("rescale").description("Resize image with optional padding").option("-y, --yes", "Use defaults, skip prompts").option("-g, --gui", "Use GUI for options").action(async (files, options) => {
4869
4892
  if (options.gui) {
4870
4893
  const { valid, invalid } = validateExtensions(files, config9.extensions);
4871
4894
  if (invalid.length > 0) {
4872
- console.error(chalk12.red("Invalid file types:"));
4895
+ console.error(chalk13.red("Invalid file types:"));
4873
4896
  for (const file of invalid) {
4874
- console.error(chalk12.red(` - ${file}`));
4897
+ console.error(chalk13.red(` - ${file}`));
4875
4898
  }
4876
4899
  }
4877
4900
  if (valid.length === 0) {
4878
4901
  process.exit(1);
4879
4902
  }
4880
- const result = await runGUI9(valid[0]);
4903
+ const result = await picletTool.runGUI(valid[0]);
4881
4904
  process.exit(result ? 0 : 1);
4882
4905
  }
4883
4906
  const success2 = await runToolOnFiles(
@@ -4890,21 +4913,21 @@ function registerScaleCommand(program2) {
4890
4913
  }
4891
4914
 
4892
4915
  // src/cli/commands/storepack.ts
4893
- import chalk13 from "chalk";
4916
+ import chalk14 from "chalk";
4894
4917
  function registerStorepackCommand(program2) {
4895
4918
  program2.command("storepack <files...>").description("Generate assets for app stores (Windows, Unity, Steam, etc.)").option("-y, --yes", "Use defaults, skip prompts").option("-g, --gui", "Use GUI for options").action(async (files, options) => {
4896
4919
  if (options.gui) {
4897
4920
  const { valid, invalid } = validateExtensions(files, config10.extensions);
4898
4921
  if (invalid.length > 0) {
4899
- console.error(chalk13.red("Invalid file types:"));
4922
+ console.error(chalk14.red("Invalid file types:"));
4900
4923
  for (const file of invalid) {
4901
- console.error(chalk13.red(` - ${file}`));
4924
+ console.error(chalk14.red(` - ${file}`));
4902
4925
  }
4903
4926
  }
4904
4927
  if (valid.length === 0) {
4905
4928
  process.exit(1);
4906
4929
  }
4907
- const result = await runGUI10(valid[0]);
4930
+ const result = await picletTool.runGUI(valid[0]);
4908
4931
  process.exit(result ? 0 : 1);
4909
4932
  }
4910
4933
  const success2 = await runToolOnFiles(
@@ -4917,21 +4940,21 @@ function registerStorepackCommand(program2) {
4917
4940
  }
4918
4941
 
4919
4942
  // src/cli/commands/transform.ts
4920
- import chalk14 from "chalk";
4943
+ import chalk15 from "chalk";
4921
4944
  function registerTransformCommand(program2) {
4922
4945
  program2.command("transform <files...>").alias("flip").description("Flip or rotate images").option("-y, --yes", "Use defaults, skip prompts").option("-g, --gui", "Use GUI for options").action(async (files, options) => {
4923
4946
  if (options.gui) {
4924
4947
  const { valid, invalid } = validateExtensions(files, config11.extensions);
4925
4948
  if (invalid.length > 0) {
4926
- console.error(chalk14.red("Invalid file types:"));
4949
+ console.error(chalk15.red("Invalid file types:"));
4927
4950
  for (const file of invalid) {
4928
- console.error(chalk14.red(` - ${file}`));
4951
+ console.error(chalk15.red(` - ${file}`));
4929
4952
  }
4930
4953
  }
4931
4954
  if (valid.length === 0) {
4932
4955
  process.exit(1);
4933
4956
  }
4934
- const result = await runGUI11(valid[0]);
4957
+ const result = await picletTool.runGUI(valid[0]);
4935
4958
  process.exit(result ? 0 : 1);
4936
4959
  }
4937
4960
  const success2 = await runToolOnFiles(
@@ -4944,41 +4967,41 @@ function registerTransformCommand(program2) {
4944
4967
  }
4945
4968
 
4946
4969
  // src/cli/commands/uninstall.ts
4947
- import chalk15 from "chalk";
4970
+ import chalk16 from "chalk";
4948
4971
  function registerUninstallCommand(program2) {
4949
4972
  program2.command("uninstall").description("Remove Windows shell context menu integration").action(async () => {
4950
4973
  showBanner();
4951
- console.log(chalk15.bold("Uninstalling...\n"));
4974
+ console.log(chalk16.bold("Uninstalling...\n"));
4952
4975
  if (!isWSL()) {
4953
4976
  console.log(
4954
- chalk15.yellow("! Not running in WSL. Registry cleanup skipped.")
4977
+ chalk16.yellow("! Not running in WSL. Registry cleanup skipped.")
4955
4978
  );
4956
4979
  console.log(
4957
- chalk15.yellow(
4980
+ chalk16.yellow(
4958
4981
  '! Run "piclet uninstall" from WSL to remove context menu.'
4959
4982
  )
4960
4983
  );
4961
4984
  return;
4962
4985
  }
4963
4986
  if (!isWSLInteropEnabled()) {
4964
- console.log(chalk15.yellow("WSL Interop not available. Generating registry file...\n"));
4987
+ console.log(chalk16.yellow("WSL Interop not available. Generating registry file...\n"));
4965
4988
  const regPath = await generateUninstallRegFile();
4966
4989
  const winPath = wslToWindows(regPath);
4967
- console.log(chalk15.green("\u2713 Generated uninstall registry file:"));
4968
- console.log(chalk15.cyan(` ${winPath}
4990
+ console.log(chalk16.green("\u2713 Generated uninstall registry file:"));
4991
+ console.log(chalk16.cyan(` ${winPath}
4969
4992
  `));
4970
- console.log(chalk15.bold("To uninstall, either:"));
4971
- console.log(chalk15.dim(" 1. Double-click the .reg file in Windows Explorer"));
4972
- console.log(chalk15.dim(` 2. Run in elevated PowerShell: reg import "${winPath}"`));
4993
+ console.log(chalk16.bold("To uninstall, either:"));
4994
+ console.log(chalk16.dim(" 1. Double-click the .reg file in Windows Explorer"));
4995
+ console.log(chalk16.dim(` 2. Run in elevated PowerShell: reg import "${winPath}"`));
4973
4996
  console.log();
4974
4997
  return;
4975
4998
  }
4976
- console.log(chalk15.dim("Cleaning up legacy entries...\n"));
4999
+ console.log(chalk16.dim("Cleaning up legacy entries...\n"));
4977
5000
  const legacyResult = await cleanupLegacyEntries();
4978
5001
  if (legacyResult.removed.length > 0) {
4979
- console.log(chalk15.yellow(`Removed ${legacyResult.removed.length} legacy entries:`));
5002
+ console.log(chalk16.yellow(`Removed ${legacyResult.removed.length} legacy entries:`));
4980
5003
  for (const entry of legacyResult.removed) {
4981
- console.log(` ${chalk15.green("\u2713")} ${entry}`);
5004
+ console.log(` ${chalk16.green("\u2713")} ${entry}`);
4982
5005
  }
4983
5006
  console.log();
4984
5007
  }
@@ -4987,40 +5010,40 @@ function registerUninstallCommand(program2) {
4987
5010
  for (const result of results) {
4988
5011
  if (result.success) {
4989
5012
  console.log(
4990
- `${chalk15.green("\u2713")} Removed: ${result.extension} \u2192 ${result.toolName}`
5013
+ `${chalk16.green("\u2713")} Removed: ${result.extension} \u2192 ${result.toolName}`
4991
5014
  );
4992
5015
  } else {
4993
5016
  console.log(
4994
- `${chalk15.gray("-")} Skipped: ${result.extension} \u2192 ${result.toolName}`
5017
+ `${chalk16.gray("-")} Skipped: ${result.extension} \u2192 ${result.toolName}`
4995
5018
  );
4996
5019
  }
4997
5020
  }
4998
5021
  const totalRemoved = removedCount + legacyResult.removed.length;
4999
5022
  console.log();
5000
5023
  console.log(
5001
- chalk15.green(
5024
+ chalk16.green(
5002
5025
  `\u2713 Cleanup complete. Removed ${totalRemoved} entries total.`
5003
5026
  )
5004
5027
  );
5005
- console.log(chalk15.dim("\nThanks for using PicLet!\n"));
5028
+ console.log(chalk16.dim("\nThanks for using PicLet!\n"));
5006
5029
  });
5007
5030
  }
5008
5031
 
5009
5032
  // src/cli/index.ts
5010
5033
  function showHelp() {
5011
5034
  showBanner();
5012
- const dim = chalk16.gray;
5013
- const cmd = chalk16.cyan;
5014
- const arg = chalk16.yellow;
5015
- const opt = chalk16.green;
5016
- const head = chalk16.white.bold;
5035
+ const dim = chalk17.gray;
5036
+ const cmd = chalk17.cyan;
5037
+ const arg = chalk17.hex("#cc8800");
5038
+ const opt = chalk17.green;
5039
+ const head = chalk17.white.bold;
5017
5040
  console.log(
5018
5041
  ` ${head("Usage:")} piclet ${cmd("<command>")} ${arg("<file>")} ${opt("[options]")}`
5019
5042
  );
5020
5043
  console.log();
5021
- console.log(head(" Unified"));
5044
+ console.log(head(" GUI"));
5022
5045
  console.log(
5023
- ` ${cmd("piclet")} ${arg("<file>")} Open all tools in one window`
5046
+ ` ${cmd("piclet")} ${arg("<file>")} Opens PicLet GUI with all tools in one window`
5024
5047
  );
5025
5048
  console.log();
5026
5049
  console.log(head(" Individual Tools"));
@@ -5034,19 +5057,7 @@ function showHelp() {
5034
5057
  ` ${cmd("scale")} ${arg("<file>")} Resize image with optional padding`
5035
5058
  );
5036
5059
  console.log(
5037
- ` ${cmd("transform")} ${arg("<file>")} Flip or rotate images`
5038
- );
5039
- console.log(
5040
- ` ${cmd("filter")} ${arg("<file>")} Apply color filters (grayscale, sepia)`
5041
- );
5042
- console.log(
5043
- ` ${cmd("border")} ${arg("<file>")} Add solid color border`
5044
- );
5045
- console.log(
5046
- ` ${cmd("recolor")} ${arg("<file>")} Replace one color with another`
5047
- );
5048
- console.log(
5049
- ` ${cmd("frames")} ${arg("<file>")} Extract frames from animated GIF`
5060
+ ` ${cmd("gif")} ${arg("<file>")} Extract frames from animated GIF`
5050
5061
  );
5051
5062
  console.log(
5052
5063
  ` ${cmd("iconpack")} ${arg("<file>")} Generate icon sets for Web/Android/iOS`
@@ -5071,6 +5082,7 @@ function showHelp() {
5071
5082
  console.log(` ${dim("$")} piclet ${cmd("makeicon")} ${arg("*.png")} ${opt("-y")} ${dim("# Batch with defaults")}`);
5072
5083
  console.log(` ${dim("$")} piclet ${cmd("remove-bg")} ${arg("photo.png")} ${dim("# Interactive prompts")}`);
5073
5084
  console.log(` ${dim("$")} piclet ${cmd("scale")} ${arg("image.jpg")} ${dim("# Interactive resize")}`);
5085
+ console.log(` ${dim("$")} piclet ${cmd("gif")} ${arg("anim.gif")} ${dim("# Extract GIF frames")}`);
5074
5086
  console.log(` ${dim("$")} piclet ${cmd("iconpack")} ${arg("icon.png")} ${opt("-y")} ${dim("# All platforms")}`);
5075
5087
  console.log();
5076
5088
  console.log(head(" Requirements"));
@@ -5082,6 +5094,7 @@ function createProgram() {
5082
5094
  const program2 = new Command();
5083
5095
  program2.helpInformation = () => "";
5084
5096
  program2.on("--help", () => {
5097
+ showHelp();
5085
5098
  });
5086
5099
  program2.name("piclet").description("Image manipulation utility toolkit with Windows shell integration").version("1.0.0").action(() => {
5087
5100
  showHelp();
@@ -5107,7 +5120,7 @@ function createProgram() {
5107
5120
  // src/cli.ts
5108
5121
  var program = createProgram();
5109
5122
  program.parseAsync(process.argv).catch((error2) => {
5110
- console.error(chalk17.red(`Error: ${error2.message}`));
5123
+ console.error(chalk18.red(`Error: ${error2.message}`));
5111
5124
  process.exit(1);
5112
5125
  });
5113
5126
  //# sourceMappingURL=cli.js.map