@opentray/vite-plugin 0.18.0 → 0.19.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/dist/index.d.mts CHANGED
@@ -15,10 +15,21 @@ interface OpenTrayAppIconOptions {
15
15
  readonly implementationPath?: string;
16
16
  /** Advanced: override the source file whose bytes identify the generator implementation. */
17
17
  readonly implementationSourcePath?: string;
18
+ /**
19
+ * Pre-composed source: skip glyph re-tiling; pass pixels through verbatim.
20
+ */
21
+ readonly composed?: boolean;
22
+ /**
23
+ * Separate macOS content source; ICNS encodes from this while ICO/Linux
24
+ * use sourcePath.
25
+ */
26
+ readonly macosSourcePath?: string;
18
27
  }
19
28
  interface OpenTrayAppIconCacheMetadata {
20
29
  readonly schemaVersion: number;
21
30
  readonly sourceSha256: string;
31
+ readonly macosSourceSha256?: string;
32
+ readonly composed?: boolean;
22
33
  readonly sourceImplementationSha256: string | null;
23
34
  readonly implementationSha256: string;
24
35
  readonly recipeVersion: string;
@@ -44,6 +55,17 @@ interface OpenTrayAppIconManifest {
44
55
  interface OpenTrayAppIconPluginOptions {
45
56
  /** Brand source image. This is intentionally explicit so the plugin is app-agnostic. */
46
57
  readonly sourcePath: string;
58
+ /**
59
+ * Pre-composed source: the image already carries its background and
60
+ * squircle mask, so glyph re-tiling (trim → symbol → white tile) is
61
+ * skipped and the pixels pass through verbatim.
62
+ */
63
+ readonly composed?: boolean;
64
+ /**
65
+ * Separate macOS content source (e.g. the best-practice 824-in-1024
66
+ * variant): ICNS encodes from this while ICO/Linux use sourcePath.
67
+ */
68
+ readonly macosSourcePath?: string;
47
69
  readonly outputPath?: string;
48
70
  readonly icnsOutputPath?: string;
49
71
  readonly icoOutputPath?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/app-icon.ts","../src/index.ts"],"mappings":";;;;;UAmDiB,sBAAA;EAAA,SACN,UAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;EAAA,SACA,aAAA;EAAA,SACA,oBAAA;EAAA,SACA,kBAAA;EAAA,SACA,SAAA;EALA;EAAA,SAOA,kBAAA;EALA;EAAA,SAOA,wBAAA;AAAA;AAAA,UAGM,4BAAA;EAAA,SACN,aAAA;EAAA,SACA,YAAA;EAAA,SACA,0BAAA;EAAA,SACA,oBAAA;EAAA,SACA,aAAA;EAAA,SACA,YAAA;EAAA,SACA,kBAAA;EAAA,SACA,oBAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;EAAA,SACA,aAAA;EAAA,SACA,mBAAA;IAAA,SACE,IAAA;IAAA,SACA,IAAA;EAAA;EAAA,SAEF,kBAAA;EAPA;EAAA,SASA,OAAA,EAAS,OAAO;AAAA;AAAA,UAGV,uBAAA;EAAA,SACN,aAAA;EARE;EAAA,SAUF,OAAA,EAAS,OAAO;AAAA;AAAA,UAGV,4BAAA;EATU;EAAA,SAWhB,UAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;EAAA,SACA,aAAA;EAAA,SACA,oBAAA;EAAA,SACA,kBAAA;EAAA,SACA,SAAA;AAAA;;iBAIW,uBAAA,CACpB,OAAA,EAAS,sBAAA,GACR,OAAA,CAAQ,4BAAA;AAdX;AAAA,iBAoEgB,qBAAA,CACd,OAAA,EAAS,4BAAA,GACR,MAAM;;;UC9IQ,yBAAA;EAAA,SACN,GAAA,EAAK,oBAAA;EAAA,SACL,WAAA,EAAa,qBAAA;EAAA,SACb,eAAA,GAAkB,QAAA,CAAS,MAAA,SAAe,qBAAA;EAAA,SAC1C,eAAA,GAAkB,QAAA,CAAS,MAAA,SAAe,qBAAA;EAAA,SAC1C,KAAA;EAAA,SACA,YAAA;AAAA;AAAA,UAGM,sBAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;IAAA,SACE,MAAA;EAAA;AAAA;AAAA,UAII,mBAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA;EAAA,SACA,QAAA;EAAA,SACA,cAAA;EAAA,SACA,IAAA;AAAA;AAAA,KAGC,cAAA,GAAiB,QAAQ,CAAC,MAAA;AAAA,UAErB,kBAAA;EAAA,SACN,IAAA;EAAA,SACA,KAAA;EACT,cAAA,CAAe,MAAA,EAAQ,sBAAA;EACvB,WAAA,CAAY,OAAA,WAAkB,MAAA,EAAQ,cAAA,GAAiB,OAAA;EAAA,SAC9C,aAAA,QAAqB,qBAAA;AAAA;AAAA,UAGf,kCAAA,SACP,IAAI,CAAC,sBAAA;EDkBJ;EAAA,SChBA,UAAA;AAAA;AAAA,UAGM,2BAAA;EAAA,SACN,IAAA;EAAA,SACA,KAAA;EACT,cAAA,CAAe,MAAA,EAAQ,sBAAA;EACvB,WAAA,IAAe,OAAA;EAAA,SACN,aAAA,QAAqB,6BAAA;AAAA;ADiBL;AAAA,cCbd,uBAAA,GACX,OAAA,EAAS,kCAAA,KACR,2BAyBF;AAAA,cAEY,kBAAA,GAAsB,OAAA,EAAS,yBAAA,KAA4B,kBAiCvE;AAAA,cAEY,gBAAA,GAAoB,MAAsB,EAAd,cAAc"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/app-icon.ts","../src/index.ts"],"mappings":";;;;;UAmDiB,sBAAA;EAAA,SACN,UAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;EAAA,SACA,aAAA;EAAA,SACA,oBAAA;EAAA,SACA,kBAAA;EAAA,SACA,SAAA;EALA;EAAA,SAOA,kBAAA;EALA;EAAA,SAOA,wBAAA;EALA;;;EAAA,SASA,QAAA;EAAA;;;AAKe;EALf,SAKA,eAAA;AAAA;AAAA,UAGM,4BAAA;EAAA,SACN,aAAA;EAAA,SACA,YAAA;EAAA,SACA,iBAAA;EAAA,SACA,QAAA;EAAA,SACA,0BAAA;EAAA,SACA,oBAAA;EAAA,SACA,aAAA;EAAA,SACA,YAAA;EAAA,SACA,kBAAA;EAAA,SACA,oBAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;EAAA,SACA,aAAA;EAAA,SACA,mBAAA;IAAA,SACE,IAAA;IAAA,SACA,IAAA;EAAA;EAAA,SAEF,kBAAA;EAEA;EAAA,SAAA,OAAA,EAAS,OAAO;AAAA;AAAA,UAGV,uBAAA;EAAA,SACN,aAAA;EAD6B;EAAA,SAG7B,OAAA,EAAS,OAAO;AAAA;AAAA,UAGV,4BAAA;EAHN;EAAA,SAKA,UAAA;EALgB;AAAA;AAG3B;;;EAH2B,SAWhB,QAAA;EANA;;;;EAAA,SAWA,eAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;EAAA,SACA,aAAA;EAAA,SACA,oBAAA;EAAA,SACA,kBAAA;EAAA,SACA,SAAA;AAAA;;iBAIW,uBAAA,CACpB,OAAA,EAAS,sBAAA,GACR,OAAA,CAAQ,4BAAA;;iBA8DK,qBAAA,CACd,OAAA,EAAS,4BAAA,GACR,MAAM;;;UC5KQ,yBAAA;EAAA,SACN,GAAA,EAAK,oBAAA;EAAA,SACL,WAAA,EAAa,qBAAA;EAAA,SACb,eAAA,GAAkB,QAAA,CAAS,MAAA,SAAe,qBAAA;EAAA,SAC1C,eAAA,GAAkB,QAAA,CAAS,MAAA,SAAe,qBAAA;EAAA,SAC1C,KAAA;EAAA,SACA,YAAA;AAAA;AAAA,UAGM,sBAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;IAAA,SACE,MAAA;EAAA;AAAA;AAAA,UAII,mBAAA;EAAA,SACN,IAAA;EAAA,SACA,OAAA;EAAA,SACA,QAAA;EAAA,SACA,cAAA;EAAA,SACA,IAAA;AAAA;AAAA,KAGC,cAAA,GAAiB,QAAQ,CAAC,MAAA;AAAA,UAErB,kBAAA;EAAA,SACN,IAAA;EAAA,SACA,KAAA;EACT,cAAA,CAAe,MAAA,EAAQ,sBAAA;EACvB,WAAA,CAAY,OAAA,WAAkB,MAAA,EAAQ,cAAA,GAAiB,OAAA;EAAA,SAC9C,aAAA,QAAqB,qBAAA;AAAA;AAAA,UAGf,kCAAA,SACP,IAAI,CAAC,sBAAA;EDyBJ;EAAA,SCvBA,UAAA;AAAA;AAAA,UAGM,2BAAA;EAAA,SACN,IAAA;EAAA,SACA,KAAA;EACT,cAAA,CAAe,MAAA,EAAQ,sBAAA;EACvB,WAAA,IAAe,OAAA;EAAA,SACN,aAAA,QAAqB,6BAAA;AAAA;;cAInB,uBAAA,GACX,OAAA,EAAS,kCAAA,KACR,2BAyBF;AAAA,cAEY,kBAAA,GAAsB,OAAA,EAAS,yBAAA,KAA4B,kBAiCvE;AAAA,cAEY,gBAAA,GAAoB,MAAsB,EAAd,cAAc"}
package/dist/index.mjs CHANGED
@@ -90,6 +90,8 @@ async function generateOpenTrayAppIcon(options) {
90
90
  const metadata = await createCacheMetadata({
91
91
  sourcePath: options.sourcePath,
92
92
  implementationPath,
93
+ ...options.composed === true ? { composed: true } : {},
94
+ ...options.macosSourcePath === void 0 ? {} : { macosSourcePath: options.macosSourcePath },
93
95
  outputPath,
94
96
  icnsOutputPath,
95
97
  icoOutputPath,
@@ -98,13 +100,14 @@ async function generateOpenTrayAppIcon(options) {
98
100
  ...options.implementationSourcePath === void 0 ? {} : { implementationSourcePath: options.implementationSourcePath }
99
101
  });
100
102
  if (await cacheMatches(cachePath, metadata)) return metadata;
101
- const rendered = await renderAppIcon(options.sourcePath);
103
+ const rendered = await renderAppIcon(options.sourcePath, options.composed === true);
104
+ const macosRendered = options.macosSourcePath === void 0 || options.macosSourcePath === options.sourcePath ? rendered : await renderAppIcon(options.macosSourcePath, options.composed === true);
102
105
  await fs.mkdir(path.dirname(outputPath), { recursive: true });
103
106
  await fs.mkdir(path.dirname(icnsOutputPath), { recursive: true });
104
107
  await fs.mkdir(path.dirname(icoOutputPath), { recursive: true });
105
108
  await fs.mkdir(path.dirname(cachePath), { recursive: true });
106
109
  await fs.writeFile(outputPath, rendered);
107
- await encodeNativeIcons(rendered, icnsOutputPath, icoOutputPath);
110
+ await encodeNativeIcons(rendered, macosRendered, icnsOutputPath, icoOutputPath);
108
111
  await writeLinuxIcons(rendered, metadata.linuxPngOutputPaths);
109
112
  await writeManifest(metadata);
110
113
  await fs.writeFile(cachePath, `${JSON.stringify(metadata, null, 2)}\n`, "utf8");
@@ -125,6 +128,8 @@ function openTrayAppIconPlugin(options) {
125
128
  const cachePath = options.cachePath ?? path.resolve(config.root, ".cache/app-icon.json");
126
129
  generation ??= generateOpenTrayAppIcon({
127
130
  sourcePath: path.resolve(options.sourcePath),
131
+ ...options.composed === true ? { composed: true } : {},
132
+ ...options.macosSourcePath === void 0 ? {} : { macosSourcePath: path.resolve(options.macosSourcePath) },
128
133
  outputPath,
129
134
  icnsOutputPath,
130
135
  icoOutputPath,
@@ -174,6 +179,8 @@ async function createCacheMetadata(options) {
174
179
  return {
175
180
  schemaVersion: CACHE_SCHEMA_VERSION,
176
181
  sourceSha256: await sha256(options.sourcePath),
182
+ ...options.macosSourcePath === void 0 ? {} : { macosSourceSha256: await sha256(options.macosSourcePath) },
183
+ ...options.composed === true ? { composed: true } : {},
177
184
  sourceImplementationSha256: sourceImplementationPath === null ? null : await sha256(sourceImplementationPath),
178
185
  implementationSha256: await sha256(options.implementationPath),
179
186
  recipeVersion: RECIPE_VERSION,
@@ -188,7 +195,11 @@ async function createCacheMetadata(options) {
188
195
  appIcon
189
196
  };
190
197
  }
191
- async function renderAppIcon(sourcePath) {
198
+ async function renderAppIcon(sourcePath, composed = false) {
199
+ if (composed) return sharp(sourcePath, { failOn: "none" }).resize(ICON_SIZE, ICON_SIZE, {
200
+ fit: "contain",
201
+ kernel: sharp.kernel.lanczos3
202
+ }).withMetadata({ density: APP_ICON_DENSITY }).png({ compressionLevel: 9 }).toBuffer();
192
203
  const symbol = await sharp(sourcePath).trim({ threshold: 0 }).resize(SYMBOL_SIZE, SYMBOL_SIZE, {
193
204
  fit: "inside",
194
205
  kernel: sharp.kernel.lanczos3
@@ -223,21 +234,25 @@ async function renderAppIcon(sourcePath) {
223
234
  left: symbolLeft
224
235
  }]).withMetadata({ density: APP_ICON_DENSITY }).png({ compressionLevel: 9 }).toBuffer();
225
236
  }
226
- async function encodeNativeIcons(rendered, icnsOutputPath, icoOutputPath) {
227
- const pngBySize = /* @__PURE__ */ new Map();
228
- const pngAt = async (size) => {
229
- const cached = pngBySize.get(size);
230
- if (cached !== void 0) return cached;
231
- const png = await sharp(rendered).resize(size, size, { fit: "contain" }).withMetadata({ density: APP_ICON_DENSITY }).png({ compressionLevel: 9 }).toBuffer();
232
- pngBySize.set(size, png);
233
- return png;
237
+ async function encodeNativeIcons(rendered, macosRendered, icnsOutputPath, icoOutputPath) {
238
+ const cacheFor = (source) => {
239
+ const bySize = /* @__PURE__ */ new Map();
240
+ return { async pngAt(size) {
241
+ const cached = bySize.get(size);
242
+ if (cached !== void 0) return cached;
243
+ const png = await sharp(source).resize(size, size, { fit: "contain" }).withMetadata({ density: APP_ICON_DENSITY }).png({ compressionLevel: 9 }).toBuffer();
244
+ bySize.set(size, png);
245
+ return png;
246
+ } };
234
247
  };
248
+ const windows = cacheFor(rendered);
249
+ const macos = cacheFor(macosRendered);
235
250
  const icns = new IconIcns();
236
251
  icns.toc = true;
237
- for (const { tag, size } of ICNS_REPRESENTATIONS) await icns.addFromPng(await pngAt(size), [tag], false);
252
+ for (const { tag, size } of ICNS_REPRESENTATIONS) await icns.addFromPng(await macos.pngAt(size), [tag], false);
238
253
  await fs.writeFile(icnsOutputPath, icns.encode());
239
254
  const ico = new IconIco();
240
- for (const size of ICO_SIZES) await ico.addFromPng(await pngAt(size), null, false);
255
+ for (const size of ICO_SIZES) await ico.addFromPng(await windows.pngAt(size), null, false);
241
256
  await fs.writeFile(icoOutputPath, ico.encode());
242
257
  }
243
258
  async function writeLinuxIcons(rendered, outputs) {
@@ -293,12 +308,12 @@ async function cacheMatches(file, expected) {
293
308
  }
294
309
  }
295
310
  function sameCacheIdentity(actual, expected) {
296
- return actual.schemaVersion === expected.schemaVersion && actual.sourceSha256 === expected.sourceSha256 && actual.sourceImplementationSha256 === expected.sourceImplementationSha256 && actual.implementationSha256 === expected.implementationSha256 && actual.recipeVersion === expected.recipeVersion && actual.sharpVersion === expected.sharpVersion && actual.iconEncoderVersion === expected.iconEncoderVersion && actual.figmaSquircleVersion === expected.figmaSquircleVersion && actual.outputPath === expected.outputPath && actual.icnsOutputPath === expected.icnsOutputPath && actual.icoOutputPath === expected.icoOutputPath && actual.manifestOutputPath === expected.manifestOutputPath && JSON.stringify(actual.linuxPngOutputPaths) === JSON.stringify(expected.linuxPngOutputPaths) && JSON.stringify(actual.appIcon) === JSON.stringify(expected.appIcon);
311
+ return actual.schemaVersion === expected.schemaVersion && actual.sourceSha256 === expected.sourceSha256 && actual.macosSourceSha256 === expected.macosSourceSha256 && actual.composed === expected.composed && actual.sourceImplementationSha256 === expected.sourceImplementationSha256 && actual.implementationSha256 === expected.implementationSha256 && actual.recipeVersion === expected.recipeVersion && actual.sharpVersion === expected.sharpVersion && actual.iconEncoderVersion === expected.iconEncoderVersion && actual.figmaSquircleVersion === expected.figmaSquircleVersion && actual.outputPath === expected.outputPath && actual.icnsOutputPath === expected.icnsOutputPath && actual.icoOutputPath === expected.icoOutputPath && actual.manifestOutputPath === expected.manifestOutputPath && JSON.stringify(actual.linuxPngOutputPaths) === JSON.stringify(expected.linuxPngOutputPaths) && JSON.stringify(actual.appIcon) === JSON.stringify(expected.appIcon);
297
312
  }
298
313
  function isCacheMetadata(value) {
299
314
  if (typeof value !== "object" || value === null) return false;
300
315
  const record = value;
301
- return typeof record.schemaVersion === "number" && typeof record.sourceSha256 === "string" && (record.sourceImplementationSha256 === null || typeof record.sourceImplementationSha256 === "string") && typeof record.implementationSha256 === "string" && typeof record.recipeVersion === "string" && typeof record.sharpVersion === "string" && typeof record.iconEncoderVersion === "string" && typeof record.figmaSquircleVersion === "string" && typeof record.outputPath === "string" && typeof record.icnsOutputPath === "string" && typeof record.icoOutputPath === "string" && Array.isArray(record.linuxPngOutputPaths) && typeof record.manifestOutputPath === "string" && Array.isArray(record.appIcon);
316
+ return typeof record.schemaVersion === "number" && typeof record.sourceSha256 === "string" && (record.macosSourceSha256 === void 0 || typeof record.macosSourceSha256 === "string") && (record.composed === void 0 || typeof record.composed === "boolean") && (record.sourceImplementationSha256 === null || typeof record.sourceImplementationSha256 === "string") && typeof record.implementationSha256 === "string" && typeof record.recipeVersion === "string" && typeof record.sharpVersion === "string" && typeof record.iconEncoderVersion === "string" && typeof record.figmaSquircleVersion === "string" && typeof record.outputPath === "string" && typeof record.icnsOutputPath === "string" && typeof record.icoOutputPath === "string" && Array.isArray(record.linuxPngOutputPaths) && typeof record.manifestOutputPath === "string" && Array.isArray(record.appIcon);
302
317
  }
303
318
  async function resolveSourceImplementationPath(implementationPath) {
304
319
  if (implementationPath.endsWith(`${path.sep}src${path.sep}app-icon.ts`)) return implementationPath;
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/app-icon.ts","../src/index.ts"],"sourcesContent":["// Orthogonal intents (maintained 2026-07-20; original user request: move the\n// skill-creator-v2 app-icon build chain into OpenTray's Vite plugin):\n// 1. Normalize a brand source image into a readable application icon with a\n// white safe-area tile and a transparent outer margin.\n// 2. Produce standard macOS ICNS, Windows ICO, and Linux theme PNG assets.\n// 3. Cache the output by source, source implementation, bundled implementation,\n// recipe, encoder, and output identity so stale generated assets cannot leak\n// into a dev runtime.\n// Compromise: published packages do not ship TypeScript sources, so their cache\n// uses a null source hash and the bundled plugin hash as the implementation\n// authority; linked consumers hash both layers.\n\nimport crypto from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { getSvgPath } from \"figma-squircle\";\nimport sharp from \"sharp\";\nimport type { Plugin } from \"vite\";\n\nimport type { AppIcon } from \"@opentray/spec\";\nimport { IconIcns, IconIco } from \"@shockpkg/icon-encoder\";\n\nconst ICON_SIZE = 1024;\nconst TILE_INSET = 64;\nconst TILE_SIZE = ICON_SIZE - TILE_INSET * 2;\nconst TILE_RADIUS = 196;\nconst TILE_SMOOTHING = 1;\nconst SYMBOL_SIZE = 704;\nconst APP_ICON_DENSITY = 72;\nconst CACHE_SCHEMA_VERSION = 6;\nconst RECIPE_VERSION = `squircle-v3:${ICON_SIZE}:${TILE_INSET}:${TILE_RADIUS}:${TILE_SMOOTHING}:${SYMBOL_SIZE}:${APP_ICON_DENSITY}dpi:icns-tagged`;\nconst ICO_SIZES = [16, 24, 32, 48, 64, 128, 256] as const;\nconst LINUX_SIZES = [16, 32, 48, 64, 128, 256, 512] as const;\nconst ICNS_REPRESENTATIONS = [\n { tag: \"ic12\", size: 64 },\n { tag: \"ic07\", size: 128 },\n { tag: \"ic13\", size: 256 },\n { tag: \"ic08\", size: 256 },\n { tag: \"ic04\", size: 16 },\n { tag: \"ic14\", size: 512 },\n { tag: \"ic09\", size: 512 },\n { tag: \"ic05\", size: 32 },\n { tag: \"ic10\", size: 1024 },\n { tag: \"ic11\", size: 32 },\n] as const;\n\nconst require = createRequire(import.meta.url);\n\nexport interface OpenTrayAppIconOptions {\n readonly sourcePath: string;\n readonly outputPath?: string;\n readonly icnsOutputPath?: string;\n readonly icoOutputPath?: string;\n readonly linuxOutputDirectory?: string;\n readonly manifestOutputPath?: string;\n readonly cachePath?: string;\n /** Advanced: override the module whose bytes identify the generator implementation. */\n readonly implementationPath?: string;\n /** Advanced: override the source file whose bytes identify the generator implementation. */\n readonly implementationSourcePath?: string;\n}\n\nexport interface OpenTrayAppIconCacheMetadata {\n readonly schemaVersion: number;\n readonly sourceSha256: string;\n readonly sourceImplementationSha256: string | null;\n readonly implementationSha256: string;\n readonly recipeVersion: string;\n readonly sharpVersion: string;\n readonly iconEncoderVersion: string;\n readonly figmaSquircleVersion: string;\n readonly outputPath: string;\n readonly icnsOutputPath: string;\n readonly icoOutputPath: string;\n readonly linuxPngOutputPaths: readonly {\n readonly size: number;\n readonly path: string;\n }[];\n readonly manifestOutputPath: string;\n /** Absolute file sources ready to pass to OpenTray at runtime. */\n readonly appIcon: AppIcon;\n}\n\nexport interface OpenTrayAppIconManifest {\n readonly schemaVersion: 1;\n /** File paths are relative to the manifest file. */\n readonly appIcon: AppIcon;\n}\n\nexport interface OpenTrayAppIconPluginOptions {\n /** Brand source image. This is intentionally explicit so the plugin is app-agnostic. */\n readonly sourcePath: string;\n readonly outputPath?: string;\n readonly icnsOutputPath?: string;\n readonly icoOutputPath?: string;\n readonly linuxOutputDirectory?: string;\n readonly manifestOutputPath?: string;\n readonly cachePath?: string;\n}\n\n/** Generate one strict cross-platform AppIcon asset set. */\nexport async function generateOpenTrayAppIcon(\n options: OpenTrayAppIconOptions\n): Promise<OpenTrayAppIconCacheMetadata> {\n const outputPath =\n options.outputPath ??\n path.join(path.dirname(options.sourcePath), \"app-icon.png\");\n const icnsOutputPath =\n options.icnsOutputPath ??\n path.join(path.dirname(outputPath), \"app-icon.icns\");\n const icoOutputPath =\n options.icoOutputPath ??\n path.join(path.dirname(outputPath), \"app-icon.ico\");\n const linuxOutputDirectory =\n options.linuxOutputDirectory ??\n path.join(path.dirname(outputPath), \"linux\");\n const manifestOutputPath =\n options.manifestOutputPath ??\n path.join(path.dirname(outputPath), \"app-icon.json\");\n const cachePath =\n options.cachePath ??\n path.join(path.dirname(outputPath), \"../../.cache/app-icon.json\");\n const implementationPath =\n options.implementationPath ?? fileURLToPath(import.meta.url);\n const metadata = await createCacheMetadata({\n sourcePath: options.sourcePath,\n implementationPath,\n outputPath,\n icnsOutputPath,\n icoOutputPath,\n linuxOutputDirectory,\n manifestOutputPath,\n ...(options.implementationSourcePath === undefined\n ? {}\n : { implementationSourcePath: options.implementationSourcePath }),\n });\n\n if (await cacheMatches(cachePath, metadata)) return metadata;\n\n const rendered = await renderAppIcon(options.sourcePath);\n await fs.mkdir(path.dirname(outputPath), { recursive: true });\n await fs.mkdir(path.dirname(icnsOutputPath), { recursive: true });\n await fs.mkdir(path.dirname(icoOutputPath), { recursive: true });\n await fs.mkdir(path.dirname(cachePath), { recursive: true });\n await fs.writeFile(outputPath, rendered);\n await encodeNativeIcons(rendered, icnsOutputPath, icoOutputPath);\n await writeLinuxIcons(rendered, metadata.linuxPngOutputPaths);\n await writeManifest(metadata);\n await fs.writeFile(\n cachePath,\n `${JSON.stringify(metadata, null, 2)}\\n`,\n \"utf8\"\n );\n return metadata;\n}\n\n/** Create the Vite plugin used by both serve and build modes. */\nexport function openTrayAppIconPlugin(\n options: OpenTrayAppIconPluginOptions\n): Plugin {\n let generation: Promise<OpenTrayAppIconCacheMetadata> | undefined;\n\n return {\n name: \"opentray/app-icon\",\n enforce: \"pre\",\n async configResolved(config) {\n const outputPath =\n options.outputPath ??\n path.resolve(config.root, \"static/icons/app-icon.png\");\n const icnsOutputPath =\n options.icnsOutputPath ??\n path.resolve(config.root, \"static/icons/app-icon.icns\");\n const icoOutputPath =\n options.icoOutputPath ??\n path.resolve(config.root, \"static/icons/app-icon.ico\");\n const linuxOutputDirectory =\n options.linuxOutputDirectory ??\n path.resolve(config.root, \"static/icons/linux\");\n const manifestOutputPath =\n options.manifestOutputPath ??\n path.resolve(config.root, \"static/icons/app-icon.json\");\n const cachePath =\n options.cachePath ?? path.resolve(config.root, \".cache/app-icon.json\");\n generation ??= generateOpenTrayAppIcon({\n sourcePath: path.resolve(options.sourcePath),\n outputPath,\n icnsOutputPath,\n icoOutputPath,\n linuxOutputDirectory,\n manifestOutputPath,\n cachePath,\n });\n await generation;\n },\n };\n}\n\nasync function createCacheMetadata(options: {\n sourcePath: string;\n implementationPath: string;\n implementationSourcePath?: string;\n outputPath: string;\n icnsOutputPath: string;\n icoOutputPath: string;\n linuxOutputDirectory: string;\n manifestOutputPath: string;\n}): Promise<OpenTrayAppIconCacheMetadata> {\n const sourceImplementationPath =\n options.implementationSourcePath ??\n (await resolveSourceImplementationPath(options.implementationPath));\n const linuxPngOutputPaths = LINUX_SIZES.map((size) => ({\n size,\n path: path.resolve(\n options.linuxOutputDirectory,\n `${size}x${size}`,\n \"app-icon.png\"\n ),\n }));\n const icnsOutputPath = path.resolve(options.icnsOutputPath);\n const icoOutputPath = path.resolve(options.icoOutputPath);\n const appIcon: AppIcon = [\n {\n platform: \"darwin\",\n format: \"icns\",\n source: { type: \"file\", path: icnsOutputPath },\n },\n {\n platform: \"windows\",\n format: \"ico\",\n source: { type: \"file\", path: icoOutputPath },\n },\n ...linuxPngOutputPaths.map(({ size, path: pngPath }) => ({\n platform: \"linux\" as const,\n format: \"png\" as const,\n size,\n source: { type: \"file\" as const, path: pngPath },\n })),\n ];\n return {\n schemaVersion: CACHE_SCHEMA_VERSION,\n sourceSha256: await sha256(options.sourcePath),\n sourceImplementationSha256:\n sourceImplementationPath === null\n ? null\n : await sha256(sourceImplementationPath),\n implementationSha256: await sha256(options.implementationPath),\n recipeVersion: RECIPE_VERSION,\n sharpVersion: await packageVersion(\"sharp\"),\n iconEncoderVersion: await packageVersion(\"@shockpkg/icon-encoder\"),\n figmaSquircleVersion: await packageVersion(\"figma-squircle\"),\n outputPath: path.resolve(options.outputPath),\n icnsOutputPath,\n icoOutputPath,\n linuxPngOutputPaths,\n manifestOutputPath: path.resolve(options.manifestOutputPath),\n appIcon,\n };\n}\n\nasync function renderAppIcon(sourcePath: string): Promise<Buffer> {\n const symbol = await sharp(sourcePath)\n .trim({ threshold: 0 })\n .resize(SYMBOL_SIZE, SYMBOL_SIZE, {\n fit: \"inside\",\n kernel: sharp.kernel.lanczos3,\n })\n .png()\n .toBuffer({ resolveWithObject: true });\n const symbolLeft = Math.round((ICON_SIZE - symbol.info.width) / 2);\n const symbolTop = Math.round((ICON_SIZE - symbol.info.height) / 2);\n const squirclePath = getSvgPath({\n width: TILE_SIZE,\n height: TILE_SIZE,\n cornerRadius: TILE_RADIUS,\n cornerSmoothing: TILE_SMOOTHING,\n preserveSmoothing: true,\n });\n const whiteTile = Buffer.from(\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${TILE_SIZE}\" height=\"${TILE_SIZE}\"><path d=\"${squirclePath}\" fill=\"#fff\"/></svg>`\n );\n return sharp({\n create: {\n width: ICON_SIZE,\n height: ICON_SIZE,\n channels: 4,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n },\n })\n .composite([\n { input: whiteTile, top: TILE_INSET, left: TILE_INSET },\n { input: symbol.data, top: symbolTop, left: symbolLeft },\n ])\n .withMetadata({ density: APP_ICON_DENSITY })\n .png({ compressionLevel: 9 })\n .toBuffer();\n}\n\nasync function encodeNativeIcons(\n rendered: Buffer,\n icnsOutputPath: string,\n icoOutputPath: string\n): Promise<void> {\n const pngBySize = new Map<number, Buffer>();\n const pngAt = async (size: number): Promise<Buffer> => {\n const cached = pngBySize.get(size);\n if (cached !== undefined) return cached;\n const png = await sharp(rendered)\n .resize(size, size, { fit: \"contain\" })\n .withMetadata({ density: APP_ICON_DENSITY })\n .png({ compressionLevel: 9 })\n .toBuffer();\n pngBySize.set(size, png);\n return png;\n };\n\n const icns = new IconIcns();\n icns.toc = true;\n for (const { tag, size } of ICNS_REPRESENTATIONS) {\n await icns.addFromPng(await pngAt(size), [tag], false);\n }\n await fs.writeFile(icnsOutputPath, icns.encode());\n\n const ico = new IconIco();\n for (const size of ICO_SIZES) {\n await ico.addFromPng(await pngAt(size), null, false);\n }\n await fs.writeFile(icoOutputPath, ico.encode());\n}\n\nasync function writeLinuxIcons(\n rendered: Buffer,\n outputs: OpenTrayAppIconCacheMetadata[\"linuxPngOutputPaths\"]\n): Promise<void> {\n await Promise.all(\n outputs.map(async ({ size, path: outputPath }) => {\n await fs.mkdir(path.dirname(outputPath), { recursive: true });\n await sharp(rendered)\n .resize(size, size, { fit: \"contain\" })\n .withMetadata({ density: APP_ICON_DENSITY })\n .png({ compressionLevel: 9 })\n .toFile(outputPath);\n })\n );\n}\n\nasync function writeManifest(\n metadata: OpenTrayAppIconCacheMetadata\n): Promise<void> {\n const manifestDirectory = path.dirname(metadata.manifestOutputPath);\n const relativeSource = (\n sourcePath: string\n ): { type: \"file\"; path: string } => ({\n type: \"file\",\n path: path\n .relative(manifestDirectory, sourcePath)\n .split(path.sep)\n .join(\"/\"),\n });\n const manifest: OpenTrayAppIconManifest = {\n schemaVersion: 1,\n appIcon: [\n {\n platform: \"darwin\",\n format: \"icns\",\n source: relativeSource(metadata.icnsOutputPath),\n },\n {\n platform: \"windows\",\n format: \"ico\",\n source: relativeSource(metadata.icoOutputPath),\n },\n ...metadata.linuxPngOutputPaths.map(({ size, path: pngPath }) => ({\n platform: \"linux\" as const,\n format: \"png\" as const,\n size,\n source: relativeSource(pngPath),\n })),\n ],\n };\n await fs.mkdir(manifestDirectory, { recursive: true });\n await fs.writeFile(\n metadata.manifestOutputPath,\n `${JSON.stringify(manifest, null, 2)}\\n`\n );\n}\n\nasync function cacheMatches(\n file: string,\n expected: OpenTrayAppIconCacheMetadata\n): Promise<boolean> {\n try {\n const parsed: unknown = JSON.parse(await fs.readFile(file, \"utf8\"));\n if (!isCacheMetadata(parsed) || !sameCacheIdentity(parsed, expected))\n return false;\n await Promise.all([\n fs.access(expected.outputPath),\n fs.access(expected.icnsOutputPath),\n fs.access(expected.icoOutputPath),\n fs.access(expected.manifestOutputPath),\n ...expected.linuxPngOutputPaths.map(({ path: outputPath }) =>\n fs.access(outputPath)\n ),\n ]);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction sameCacheIdentity(\n actual: OpenTrayAppIconCacheMetadata,\n expected: OpenTrayAppIconCacheMetadata\n): boolean {\n return (\n actual.schemaVersion === expected.schemaVersion &&\n actual.sourceSha256 === expected.sourceSha256 &&\n actual.sourceImplementationSha256 === expected.sourceImplementationSha256 &&\n actual.implementationSha256 === expected.implementationSha256 &&\n actual.recipeVersion === expected.recipeVersion &&\n actual.sharpVersion === expected.sharpVersion &&\n actual.iconEncoderVersion === expected.iconEncoderVersion &&\n actual.figmaSquircleVersion === expected.figmaSquircleVersion &&\n actual.outputPath === expected.outputPath &&\n actual.icnsOutputPath === expected.icnsOutputPath &&\n actual.icoOutputPath === expected.icoOutputPath &&\n actual.manifestOutputPath === expected.manifestOutputPath &&\n JSON.stringify(actual.linuxPngOutputPaths) ===\n JSON.stringify(expected.linuxPngOutputPaths) &&\n JSON.stringify(actual.appIcon) === JSON.stringify(expected.appIcon)\n );\n}\n\nfunction isCacheMetadata(\n value: unknown\n): value is OpenTrayAppIconCacheMetadata {\n if (typeof value !== \"object\" || value === null) return false;\n const record = value as Record<string, unknown>;\n return (\n typeof record.schemaVersion === \"number\" &&\n typeof record.sourceSha256 === \"string\" &&\n (record.sourceImplementationSha256 === null ||\n typeof record.sourceImplementationSha256 === \"string\") &&\n typeof record.implementationSha256 === \"string\" &&\n typeof record.recipeVersion === \"string\" &&\n typeof record.sharpVersion === \"string\" &&\n typeof record.iconEncoderVersion === \"string\" &&\n typeof record.figmaSquircleVersion === \"string\" &&\n typeof record.outputPath === \"string\" &&\n typeof record.icnsOutputPath === \"string\" &&\n typeof record.icoOutputPath === \"string\" &&\n Array.isArray(record.linuxPngOutputPaths) &&\n typeof record.manifestOutputPath === \"string\" &&\n Array.isArray(record.appIcon)\n );\n}\n\nasync function resolveSourceImplementationPath(\n implementationPath: string\n): Promise<string | null> {\n if (implementationPath.endsWith(`${path.sep}src${path.sep}app-icon.ts`)) {\n return implementationPath;\n }\n const candidate = path.join(\n path.dirname(path.dirname(implementationPath)),\n \"src\",\n \"app-icon.ts\"\n );\n try {\n await fs.access(candidate);\n return candidate;\n } catch {\n return null;\n }\n}\n\nasync function packageVersion(packageName: string): Promise<string> {\n const entryPath = require.resolve(packageName);\n let directory = path.dirname(entryPath);\n while (true) {\n const packagePath = path.join(directory, \"package.json\");\n try {\n const parsed: unknown = JSON.parse(\n await fs.readFile(packagePath, \"utf8\")\n );\n if (isPackageMetadata(parsed, packageName)) return parsed.version;\n } catch {\n // Continue towards the package root; package exports may hide package.json.\n }\n const parent = path.dirname(directory);\n if (parent === directory) break;\n directory = parent;\n }\n throw new Error(`Unable to resolve ${packageName} package version`);\n}\n\nfunction isPackageMetadata(\n value: unknown,\n packageName: string\n): value is { name: string; version: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"name\" in value &&\n value.name === packageName &&\n \"version\" in value &&\n typeof value.version === \"string\"\n );\n}\n\nasync function sha256(file: string): Promise<string> {\n return crypto\n .createHash(\"sha256\")\n .update(await fs.readFile(file))\n .digest(\"hex\");\n}\n","// Orthogonal intents (maintained 2026-07-20; original user request: expose the\n// OpenTray Vite packaging adapter and move skill-creator-v2 app-icon generation into it):\n// 1. Stage Vite bundle metadata and native runtime artifacts through one adapter.\n// 2. Re-export the app-icon generator without coupling the packaging contract to a consumer.\n// Compromise: both exports share the package entrypoint because Vite resolves one public adapter\n// module and the icon plugin has no runtime dependency on the artifact manifest.\n\nimport { resolve } from \"node:path\";\n\nimport {\n buildDarwinAppBundle,\n stageOpenTrayPackage,\n type DarwinAppBundleOptions,\n type OpenTrayArtifactInput,\n type OpenTrayPackagingApp,\n type OpenTrayPackageManifest,\n type OpenTrayPackageResult,\n type OpenTrayDarwinAppBundleResult,\n} from \"@opentray/packaging\";\n\nexport interface OpenTrayVitePluginOptions {\n readonly app: OpenTrayPackagingApp;\n readonly runtimeHost: OpenTrayArtifactInput;\n readonly nativeArtifacts?: Readonly<Record<string, OpenTrayArtifactInput>>;\n readonly companionAssets?: Readonly<Record<string, OpenTrayArtifactInput>>;\n readonly entry?: string;\n readonly manifestPath?: string;\n}\n\nexport interface ViteResolvedConfigLike {\n readonly root: string;\n readonly mode: string;\n readonly build: {\n readonly outDir: string;\n };\n}\n\nexport interface ViteOutputChunkLike {\n readonly type?: string;\n readonly isEntry?: boolean;\n readonly fileName?: string;\n readonly facadeModuleId?: string | null;\n readonly name?: string;\n}\n\nexport type ViteBundleLike = Readonly<Record<string, unknown>>;\n\nexport interface OpenTrayVitePlugin {\n readonly name: \"opentray-packaging\";\n readonly apply: \"build\";\n configResolved(config: ViteResolvedConfigLike): void;\n writeBundle(options: unknown, bundle: ViteBundleLike): Promise<void>;\n readonly getLastResult: () => OpenTrayPackageResult | undefined;\n}\n\nexport interface OpenTrayViteAppBundlePluginOptions\n extends Omit<DarwinAppBundleOptions, \"bundlePath\" | \"reinitialize\"> {\n /** Optional output path. Defaults to `<vite outDir>/<appName>.app`. */\n readonly bundlePath?: string;\n}\n\nexport interface OpenTrayViteAppBundlePlugin {\n readonly name: \"opentray-app-bundle\";\n readonly apply: \"build\";\n configResolved(config: ViteResolvedConfigLike): void;\n writeBundle(): Promise<void>;\n readonly getLastResult: () => OpenTrayDarwinAppBundleResult | undefined;\n}\n\n/** Vite lifecycle adapter for the shared Darwin app bundle contract. */\nexport const openTrayAppBundlePlugin = (\n options: OpenTrayViteAppBundlePluginOptions,\n): OpenTrayViteAppBundlePlugin => {\n let config: ViteResolvedConfigLike | undefined;\n let lastResult: OpenTrayDarwinAppBundleResult | undefined;\n return {\n name: \"opentray-app-bundle\",\n apply: \"build\",\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n async writeBundle() {\n const resolvedConfig = config ?? {\n root: process.cwd(),\n mode: \"production\",\n build: { outDir: \"dist\" },\n };\n const bundlePath =\n options.bundlePath ?? resolve(\n resolvedConfig.root,\n resolvedConfig.build.outDir,\n `${options.appName}.app`,\n );\n lastResult = await buildDarwinAppBundle({ ...options, bundlePath });\n },\n getLastResult: () => lastResult,\n };\n};\n\nexport const openTrayVitePlugin = (options: OpenTrayVitePluginOptions): OpenTrayVitePlugin => {\n let config: ViteResolvedConfigLike | undefined;\n let lastResult: OpenTrayPackageResult | undefined;\n\n return {\n name: \"opentray-packaging\",\n apply: \"build\",\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n async writeBundle(_options, bundle) {\n const resolvedConfig = config ?? {\n root: process.cwd(),\n mode: \"production\",\n build: { outDir: \"dist\" },\n };\n lastResult = await stageOpenTrayPackage({\n app: options.app,\n outDir: resolve(resolvedConfig.root, resolvedConfig.build.outDir),\n entry: options.entry ?? resolveViteEntry(bundle),\n adapter: { name: \"vite\", mode: resolvedConfig.mode },\n runtimeHost: options.runtimeHost,\n ...(options.nativeArtifacts === undefined\n ? {}\n : { nativeArtifacts: options.nativeArtifacts }),\n ...(options.companionAssets === undefined\n ? {}\n : { companionAssets: options.companionAssets }),\n ...(options.manifestPath === undefined ? {} : { manifestPath: options.manifestPath }),\n });\n },\n getLastResult: () => lastResult,\n };\n};\n\nexport const resolveViteEntry = (bundle: ViteBundleLike): string => {\n const entry = Object.values(bundle)\n .map(asOutputChunk)\n .find((chunk): chunk is ViteOutputChunkLike => chunk?.isEntry === true);\n const identity = entry?.facadeModuleId ?? entry?.fileName ?? entry?.name;\n if (identity === undefined || identity.length === 0) {\n throw new Error(\"OpenTray Vite packaging requires a Vite entry chunk or explicit entry option\");\n }\n return identity;\n};\n\nconst asOutputChunk = (value: unknown): ViteOutputChunkLike | undefined => {\n if (typeof value !== \"object\" || value === null) {\n return undefined;\n }\n const record = value as Record<string, unknown>;\n return {\n ...(record.type === \"chunk\" ? { type: \"chunk\" } : {}),\n ...(typeof record.isEntry === \"boolean\" ? { isEntry: record.isEntry } : {}),\n ...(typeof record.fileName === \"string\" ? { fileName: record.fileName } : {}),\n ...(typeof record.facadeModuleId === \"string\" || record.facadeModuleId === null\n ? { facadeModuleId: record.facadeModuleId }\n : {}),\n ...(typeof record.name === \"string\" ? { name: record.name } : {}),\n };\n};\n\nexport type { OpenTrayPackageManifest, OpenTrayPackageResult };\n\nexport {\n generateOpenTrayAppIcon,\n openTrayAppIconPlugin,\n type OpenTrayAppIconCacheMetadata,\n type OpenTrayAppIconManifest,\n type OpenTrayAppIconOptions,\n type OpenTrayAppIconPluginOptions,\n} from \"./app-icon\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/app-icon.ts","../src/index.ts"],"sourcesContent":["// Orthogonal intents (maintained 2026-07-20; original user request: move the\n// skill-creator-v2 app-icon build chain into OpenTray's Vite plugin):\n// 1. Normalize a brand source image into a readable application icon with a\n// white safe-area tile and a transparent outer margin.\n// 2. Produce standard macOS ICNS, Windows ICO, and Linux theme PNG assets.\n// 3. Cache the output by source, source implementation, bundled implementation,\n// recipe, encoder, and output identity so stale generated assets cannot leak\n// into a dev runtime.\n// Compromise: published packages do not ship TypeScript sources, so their cache\n// uses a null source hash and the bundled plugin hash as the implementation\n// authority; linked consumers hash both layers.\n\nimport crypto from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { getSvgPath } from \"figma-squircle\";\nimport sharp from \"sharp\";\nimport type { Plugin } from \"vite\";\n\nimport type { AppIcon } from \"@opentray/spec\";\nimport { IconIcns, IconIco } from \"@shockpkg/icon-encoder\";\n\nconst ICON_SIZE = 1024;\nconst TILE_INSET = 64;\nconst TILE_SIZE = ICON_SIZE - TILE_INSET * 2;\nconst TILE_RADIUS = 196;\nconst TILE_SMOOTHING = 1;\nconst SYMBOL_SIZE = 704;\nconst APP_ICON_DENSITY = 72;\nconst CACHE_SCHEMA_VERSION = 6;\nconst RECIPE_VERSION = `squircle-v3:${ICON_SIZE}:${TILE_INSET}:${TILE_RADIUS}:${TILE_SMOOTHING}:${SYMBOL_SIZE}:${APP_ICON_DENSITY}dpi:icns-tagged`;\nconst ICO_SIZES = [16, 24, 32, 48, 64, 128, 256] as const;\nconst LINUX_SIZES = [16, 32, 48, 64, 128, 256, 512] as const;\nconst ICNS_REPRESENTATIONS = [\n { tag: \"ic12\", size: 64 },\n { tag: \"ic07\", size: 128 },\n { tag: \"ic13\", size: 256 },\n { tag: \"ic08\", size: 256 },\n { tag: \"ic04\", size: 16 },\n { tag: \"ic14\", size: 512 },\n { tag: \"ic09\", size: 512 },\n { tag: \"ic05\", size: 32 },\n { tag: \"ic10\", size: 1024 },\n { tag: \"ic11\", size: 32 },\n] as const;\n\nconst require = createRequire(import.meta.url);\n\nexport interface OpenTrayAppIconOptions {\n readonly sourcePath: string;\n readonly outputPath?: string;\n readonly icnsOutputPath?: string;\n readonly icoOutputPath?: string;\n readonly linuxOutputDirectory?: string;\n readonly manifestOutputPath?: string;\n readonly cachePath?: string;\n /** Advanced: override the module whose bytes identify the generator implementation. */\n readonly implementationPath?: string;\n /** Advanced: override the source file whose bytes identify the generator implementation. */\n readonly implementationSourcePath?: string;\n /**\n * Pre-composed source: skip glyph re-tiling; pass pixels through verbatim.\n */\n readonly composed?: boolean;\n /**\n * Separate macOS content source; ICNS encodes from this while ICO/Linux\n * use sourcePath.\n */\n readonly macosSourcePath?: string;\n}\n\nexport interface OpenTrayAppIconCacheMetadata {\n readonly schemaVersion: number;\n readonly sourceSha256: string;\n readonly macosSourceSha256?: string;\n readonly composed?: boolean;\n readonly sourceImplementationSha256: string | null;\n readonly implementationSha256: string;\n readonly recipeVersion: string;\n readonly sharpVersion: string;\n readonly iconEncoderVersion: string;\n readonly figmaSquircleVersion: string;\n readonly outputPath: string;\n readonly icnsOutputPath: string;\n readonly icoOutputPath: string;\n readonly linuxPngOutputPaths: readonly {\n readonly size: number;\n readonly path: string;\n }[];\n readonly manifestOutputPath: string;\n /** Absolute file sources ready to pass to OpenTray at runtime. */\n readonly appIcon: AppIcon;\n}\n\nexport interface OpenTrayAppIconManifest {\n readonly schemaVersion: 1;\n /** File paths are relative to the manifest file. */\n readonly appIcon: AppIcon;\n}\n\nexport interface OpenTrayAppIconPluginOptions {\n /** Brand source image. This is intentionally explicit so the plugin is app-agnostic. */\n readonly sourcePath: string;\n /**\n * Pre-composed source: the image already carries its background and\n * squircle mask, so glyph re-tiling (trim → symbol → white tile) is\n * skipped and the pixels pass through verbatim.\n */\n readonly composed?: boolean;\n /**\n * Separate macOS content source (e.g. the best-practice 824-in-1024\n * variant): ICNS encodes from this while ICO/Linux use sourcePath.\n */\n readonly macosSourcePath?: string;\n readonly outputPath?: string;\n readonly icnsOutputPath?: string;\n readonly icoOutputPath?: string;\n readonly linuxOutputDirectory?: string;\n readonly manifestOutputPath?: string;\n readonly cachePath?: string;\n}\n\n/** Generate one strict cross-platform AppIcon asset set. */\nexport async function generateOpenTrayAppIcon(\n options: OpenTrayAppIconOptions\n): Promise<OpenTrayAppIconCacheMetadata> {\n const outputPath =\n options.outputPath ??\n path.join(path.dirname(options.sourcePath), \"app-icon.png\");\n const icnsOutputPath =\n options.icnsOutputPath ??\n path.join(path.dirname(outputPath), \"app-icon.icns\");\n const icoOutputPath =\n options.icoOutputPath ??\n path.join(path.dirname(outputPath), \"app-icon.ico\");\n const linuxOutputDirectory =\n options.linuxOutputDirectory ??\n path.join(path.dirname(outputPath), \"linux\");\n const manifestOutputPath =\n options.manifestOutputPath ??\n path.join(path.dirname(outputPath), \"app-icon.json\");\n const cachePath =\n options.cachePath ??\n path.join(path.dirname(outputPath), \"../../.cache/app-icon.json\");\n const implementationPath =\n options.implementationPath ?? fileURLToPath(import.meta.url);\n const metadata = await createCacheMetadata({\n sourcePath: options.sourcePath,\n implementationPath,\n ...(options.composed === true ? { composed: true } : {}),\n ...(options.macosSourcePath === undefined\n ? {}\n : { macosSourcePath: options.macosSourcePath }),\n outputPath,\n icnsOutputPath,\n icoOutputPath,\n linuxOutputDirectory,\n manifestOutputPath,\n ...(options.implementationSourcePath === undefined\n ? {}\n : { implementationSourcePath: options.implementationSourcePath }),\n });\n\n if (await cacheMatches(cachePath, metadata)) return metadata;\n\n const rendered = await renderAppIcon(options.sourcePath, options.composed === true);\n const macosRendered =\n options.macosSourcePath === undefined || options.macosSourcePath === options.sourcePath\n ? rendered\n : await renderAppIcon(options.macosSourcePath, options.composed === true);\n await fs.mkdir(path.dirname(outputPath), { recursive: true });\n await fs.mkdir(path.dirname(icnsOutputPath), { recursive: true });\n await fs.mkdir(path.dirname(icoOutputPath), { recursive: true });\n await fs.mkdir(path.dirname(cachePath), { recursive: true });\n await fs.writeFile(outputPath, rendered);\n await encodeNativeIcons(rendered, macosRendered, icnsOutputPath, icoOutputPath);\n await writeLinuxIcons(rendered, metadata.linuxPngOutputPaths);\n await writeManifest(metadata);\n await fs.writeFile(\n cachePath,\n `${JSON.stringify(metadata, null, 2)}\\n`,\n \"utf8\"\n );\n return metadata;\n}\n\n/** Create the Vite plugin used by both serve and build modes. */\nexport function openTrayAppIconPlugin(\n options: OpenTrayAppIconPluginOptions\n): Plugin {\n let generation: Promise<OpenTrayAppIconCacheMetadata> | undefined;\n\n return {\n name: \"opentray/app-icon\",\n enforce: \"pre\",\n async configResolved(config) {\n const outputPath =\n options.outputPath ??\n path.resolve(config.root, \"static/icons/app-icon.png\");\n const icnsOutputPath =\n options.icnsOutputPath ??\n path.resolve(config.root, \"static/icons/app-icon.icns\");\n const icoOutputPath =\n options.icoOutputPath ??\n path.resolve(config.root, \"static/icons/app-icon.ico\");\n const linuxOutputDirectory =\n options.linuxOutputDirectory ??\n path.resolve(config.root, \"static/icons/linux\");\n const manifestOutputPath =\n options.manifestOutputPath ??\n path.resolve(config.root, \"static/icons/app-icon.json\");\n const cachePath =\n options.cachePath ?? path.resolve(config.root, \".cache/app-icon.json\");\n generation ??= generateOpenTrayAppIcon({\n sourcePath: path.resolve(options.sourcePath),\n ...(options.composed === true ? { composed: true } : {}),\n ...(options.macosSourcePath === undefined\n ? {}\n : { macosSourcePath: path.resolve(options.macosSourcePath) }),\n outputPath,\n icnsOutputPath,\n icoOutputPath,\n linuxOutputDirectory,\n manifestOutputPath,\n cachePath,\n });\n await generation;\n },\n };\n}\n\nasync function createCacheMetadata(options: {\n sourcePath: string;\n implementationPath: string;\n implementationSourcePath?: string;\n /** Pass-through mode: skip glyph re-tiling (part of cache identity). */\n composed?: boolean;\n /** Separate macOS content source (part of cache identity). */\n macosSourcePath?: string;\n outputPath: string;\n icnsOutputPath: string;\n icoOutputPath: string;\n linuxOutputDirectory: string;\n manifestOutputPath: string;\n}): Promise<OpenTrayAppIconCacheMetadata> {\n const sourceImplementationPath =\n options.implementationSourcePath ??\n (await resolveSourceImplementationPath(options.implementationPath));\n const linuxPngOutputPaths = LINUX_SIZES.map((size) => ({\n size,\n path: path.resolve(\n options.linuxOutputDirectory,\n `${size}x${size}`,\n \"app-icon.png\"\n ),\n }));\n const icnsOutputPath = path.resolve(options.icnsOutputPath);\n const icoOutputPath = path.resolve(options.icoOutputPath);\n const appIcon: AppIcon = [\n {\n platform: \"darwin\",\n format: \"icns\",\n source: { type: \"file\", path: icnsOutputPath },\n },\n {\n platform: \"windows\",\n format: \"ico\",\n source: { type: \"file\", path: icoOutputPath },\n },\n ...linuxPngOutputPaths.map(({ size, path: pngPath }) => ({\n platform: \"linux\" as const,\n format: \"png\" as const,\n size,\n source: { type: \"file\" as const, path: pngPath },\n })),\n ];\n return {\n schemaVersion: CACHE_SCHEMA_VERSION,\n sourceSha256: await sha256(options.sourcePath),\n ...(options.macosSourcePath === undefined\n ? {}\n : { macosSourceSha256: await sha256(options.macosSourcePath) }),\n ...(options.composed === true ? { composed: true } : {}),\n sourceImplementationSha256:\n sourceImplementationPath === null\n ? null\n : await sha256(sourceImplementationPath),\n implementationSha256: await sha256(options.implementationPath),\n recipeVersion: RECIPE_VERSION,\n sharpVersion: await packageVersion(\"sharp\"),\n iconEncoderVersion: await packageVersion(\"@shockpkg/icon-encoder\"),\n figmaSquircleVersion: await packageVersion(\"figma-squircle\"),\n outputPath: path.resolve(options.outputPath),\n icnsOutputPath,\n icoOutputPath,\n linuxPngOutputPaths,\n manifestOutputPath: path.resolve(options.manifestOutputPath),\n appIcon,\n };\n}\n\nasync function renderAppIcon(sourcePath: string, composed = false): Promise<Buffer> {\n if (composed) {\n // Pre-composed art: normalize to the 1024 canvas and pass through —\n // the background and squircle mask are already baked in.\n return sharp(sourcePath, { failOn: \"none\" })\n .resize(ICON_SIZE, ICON_SIZE, { fit: \"contain\", kernel: sharp.kernel.lanczos3 })\n .withMetadata({ density: APP_ICON_DENSITY })\n .png({ compressionLevel: 9 })\n .toBuffer();\n }\n const symbol = await sharp(sourcePath)\n .trim({ threshold: 0 })\n .resize(SYMBOL_SIZE, SYMBOL_SIZE, {\n fit: \"inside\",\n kernel: sharp.kernel.lanczos3,\n })\n .png()\n .toBuffer({ resolveWithObject: true });\n const symbolLeft = Math.round((ICON_SIZE - symbol.info.width) / 2);\n const symbolTop = Math.round((ICON_SIZE - symbol.info.height) / 2);\n const squirclePath = getSvgPath({\n width: TILE_SIZE,\n height: TILE_SIZE,\n cornerRadius: TILE_RADIUS,\n cornerSmoothing: TILE_SMOOTHING,\n preserveSmoothing: true,\n });\n const whiteTile = Buffer.from(\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${TILE_SIZE}\" height=\"${TILE_SIZE}\"><path d=\"${squirclePath}\" fill=\"#fff\"/></svg>`\n );\n return sharp({\n create: {\n width: ICON_SIZE,\n height: ICON_SIZE,\n channels: 4,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n },\n })\n .composite([\n { input: whiteTile, top: TILE_INSET, left: TILE_INSET },\n { input: symbol.data, top: symbolTop, left: symbolLeft },\n ])\n .withMetadata({ density: APP_ICON_DENSITY })\n .png({ compressionLevel: 9 })\n .toBuffer();\n}\n\nasync function encodeNativeIcons(\n rendered: Buffer,\n macosRendered: Buffer,\n icnsOutputPath: string,\n icoOutputPath: string\n): Promise<void> {\n const cacheFor = (source: Buffer): {\n pngAt(size: number): Promise<Buffer>;\n } => {\n const bySize = new Map<number, Buffer>();\n return {\n async pngAt(size: number): Promise<Buffer> {\n const cached = bySize.get(size);\n if (cached !== undefined) return cached;\n const png = await sharp(source)\n .resize(size, size, { fit: \"contain\" })\n .withMetadata({ density: APP_ICON_DENSITY })\n .png({ compressionLevel: 9 })\n .toBuffer();\n bySize.set(size, png);\n return png;\n },\n };\n };\n const windows = cacheFor(rendered);\n const macos = cacheFor(macosRendered);\n\n const icns = new IconIcns();\n icns.toc = true;\n for (const { tag, size } of ICNS_REPRESENTATIONS) {\n await icns.addFromPng(await macos.pngAt(size), [tag], false);\n }\n await fs.writeFile(icnsOutputPath, icns.encode());\n\n const ico = new IconIco();\n for (const size of ICO_SIZES) {\n await ico.addFromPng(await windows.pngAt(size), null, false);\n }\n await fs.writeFile(icoOutputPath, ico.encode());\n}\n\nasync function writeLinuxIcons(\n rendered: Buffer,\n outputs: OpenTrayAppIconCacheMetadata[\"linuxPngOutputPaths\"]\n): Promise<void> {\n await Promise.all(\n outputs.map(async ({ size, path: outputPath }) => {\n await fs.mkdir(path.dirname(outputPath), { recursive: true });\n await sharp(rendered)\n .resize(size, size, { fit: \"contain\" })\n .withMetadata({ density: APP_ICON_DENSITY })\n .png({ compressionLevel: 9 })\n .toFile(outputPath);\n })\n );\n}\n\nasync function writeManifest(\n metadata: OpenTrayAppIconCacheMetadata\n): Promise<void> {\n const manifestDirectory = path.dirname(metadata.manifestOutputPath);\n const relativeSource = (\n sourcePath: string\n ): { type: \"file\"; path: string } => ({\n type: \"file\",\n path: path\n .relative(manifestDirectory, sourcePath)\n .split(path.sep)\n .join(\"/\"),\n });\n const manifest: OpenTrayAppIconManifest = {\n schemaVersion: 1,\n appIcon: [\n {\n platform: \"darwin\",\n format: \"icns\",\n source: relativeSource(metadata.icnsOutputPath),\n },\n {\n platform: \"windows\",\n format: \"ico\",\n source: relativeSource(metadata.icoOutputPath),\n },\n ...metadata.linuxPngOutputPaths.map(({ size, path: pngPath }) => ({\n platform: \"linux\" as const,\n format: \"png\" as const,\n size,\n source: relativeSource(pngPath),\n })),\n ],\n };\n await fs.mkdir(manifestDirectory, { recursive: true });\n await fs.writeFile(\n metadata.manifestOutputPath,\n `${JSON.stringify(manifest, null, 2)}\\n`\n );\n}\n\nasync function cacheMatches(\n file: string,\n expected: OpenTrayAppIconCacheMetadata\n): Promise<boolean> {\n try {\n const parsed: unknown = JSON.parse(await fs.readFile(file, \"utf8\"));\n if (!isCacheMetadata(parsed) || !sameCacheIdentity(parsed, expected))\n return false;\n await Promise.all([\n fs.access(expected.outputPath),\n fs.access(expected.icnsOutputPath),\n fs.access(expected.icoOutputPath),\n fs.access(expected.manifestOutputPath),\n ...expected.linuxPngOutputPaths.map(({ path: outputPath }) =>\n fs.access(outputPath)\n ),\n ]);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction sameCacheIdentity(\n actual: OpenTrayAppIconCacheMetadata,\n expected: OpenTrayAppIconCacheMetadata\n): boolean {\n return (\n actual.schemaVersion === expected.schemaVersion &&\n actual.sourceSha256 === expected.sourceSha256 &&\n actual.macosSourceSha256 === expected.macosSourceSha256 &&\n actual.composed === expected.composed &&\n actual.sourceImplementationSha256 === expected.sourceImplementationSha256 &&\n actual.implementationSha256 === expected.implementationSha256 &&\n actual.recipeVersion === expected.recipeVersion &&\n actual.sharpVersion === expected.sharpVersion &&\n actual.iconEncoderVersion === expected.iconEncoderVersion &&\n actual.figmaSquircleVersion === expected.figmaSquircleVersion &&\n actual.outputPath === expected.outputPath &&\n actual.icnsOutputPath === expected.icnsOutputPath &&\n actual.icoOutputPath === expected.icoOutputPath &&\n actual.manifestOutputPath === expected.manifestOutputPath &&\n JSON.stringify(actual.linuxPngOutputPaths) ===\n JSON.stringify(expected.linuxPngOutputPaths) &&\n JSON.stringify(actual.appIcon) === JSON.stringify(expected.appIcon)\n );\n}\n\nfunction isCacheMetadata(\n value: unknown\n): value is OpenTrayAppIconCacheMetadata {\n if (typeof value !== \"object\" || value === null) return false;\n const record = value as Record<string, unknown>;\n return (\n typeof record.schemaVersion === \"number\" &&\n typeof record.sourceSha256 === \"string\" &&\n (record.macosSourceSha256 === undefined ||\n typeof record.macosSourceSha256 === \"string\") &&\n (record.composed === undefined || typeof record.composed === \"boolean\") &&\n (record.sourceImplementationSha256 === null ||\n typeof record.sourceImplementationSha256 === \"string\") &&\n typeof record.implementationSha256 === \"string\" &&\n typeof record.recipeVersion === \"string\" &&\n typeof record.sharpVersion === \"string\" &&\n typeof record.iconEncoderVersion === \"string\" &&\n typeof record.figmaSquircleVersion === \"string\" &&\n typeof record.outputPath === \"string\" &&\n typeof record.icnsOutputPath === \"string\" &&\n typeof record.icoOutputPath === \"string\" &&\n Array.isArray(record.linuxPngOutputPaths) &&\n typeof record.manifestOutputPath === \"string\" &&\n Array.isArray(record.appIcon)\n );\n}\n\nasync function resolveSourceImplementationPath(\n implementationPath: string\n): Promise<string | null> {\n if (implementationPath.endsWith(`${path.sep}src${path.sep}app-icon.ts`)) {\n return implementationPath;\n }\n const candidate = path.join(\n path.dirname(path.dirname(implementationPath)),\n \"src\",\n \"app-icon.ts\"\n );\n try {\n await fs.access(candidate);\n return candidate;\n } catch {\n return null;\n }\n}\n\nasync function packageVersion(packageName: string): Promise<string> {\n const entryPath = require.resolve(packageName);\n let directory = path.dirname(entryPath);\n while (true) {\n const packagePath = path.join(directory, \"package.json\");\n try {\n const parsed: unknown = JSON.parse(\n await fs.readFile(packagePath, \"utf8\")\n );\n if (isPackageMetadata(parsed, packageName)) return parsed.version;\n } catch {\n // Continue towards the package root; package exports may hide package.json.\n }\n const parent = path.dirname(directory);\n if (parent === directory) break;\n directory = parent;\n }\n throw new Error(`Unable to resolve ${packageName} package version`);\n}\n\nfunction isPackageMetadata(\n value: unknown,\n packageName: string\n): value is { name: string; version: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"name\" in value &&\n value.name === packageName &&\n \"version\" in value &&\n typeof value.version === \"string\"\n );\n}\n\nasync function sha256(file: string): Promise<string> {\n return crypto\n .createHash(\"sha256\")\n .update(await fs.readFile(file))\n .digest(\"hex\");\n}\n","// Orthogonal intents (maintained 2026-07-20; original user request: expose the\n// OpenTray Vite packaging adapter and move skill-creator-v2 app-icon generation into it):\n// 1. Stage Vite bundle metadata and native runtime artifacts through one adapter.\n// 2. Re-export the app-icon generator without coupling the packaging contract to a consumer.\n// Compromise: both exports share the package entrypoint because Vite resolves one public adapter\n// module and the icon plugin has no runtime dependency on the artifact manifest.\n\nimport { resolve } from \"node:path\";\n\nimport {\n buildDarwinAppBundle,\n stageOpenTrayPackage,\n type DarwinAppBundleOptions,\n type OpenTrayArtifactInput,\n type OpenTrayPackagingApp,\n type OpenTrayPackageManifest,\n type OpenTrayPackageResult,\n type OpenTrayDarwinAppBundleResult,\n} from \"@opentray/packaging\";\n\nexport interface OpenTrayVitePluginOptions {\n readonly app: OpenTrayPackagingApp;\n readonly runtimeHost: OpenTrayArtifactInput;\n readonly nativeArtifacts?: Readonly<Record<string, OpenTrayArtifactInput>>;\n readonly companionAssets?: Readonly<Record<string, OpenTrayArtifactInput>>;\n readonly entry?: string;\n readonly manifestPath?: string;\n}\n\nexport interface ViteResolvedConfigLike {\n readonly root: string;\n readonly mode: string;\n readonly build: {\n readonly outDir: string;\n };\n}\n\nexport interface ViteOutputChunkLike {\n readonly type?: string;\n readonly isEntry?: boolean;\n readonly fileName?: string;\n readonly facadeModuleId?: string | null;\n readonly name?: string;\n}\n\nexport type ViteBundleLike = Readonly<Record<string, unknown>>;\n\nexport interface OpenTrayVitePlugin {\n readonly name: \"opentray-packaging\";\n readonly apply: \"build\";\n configResolved(config: ViteResolvedConfigLike): void;\n writeBundle(options: unknown, bundle: ViteBundleLike): Promise<void>;\n readonly getLastResult: () => OpenTrayPackageResult | undefined;\n}\n\nexport interface OpenTrayViteAppBundlePluginOptions\n extends Omit<DarwinAppBundleOptions, \"bundlePath\" | \"reinitialize\"> {\n /** Optional output path. Defaults to `<vite outDir>/<appName>.app`. */\n readonly bundlePath?: string;\n}\n\nexport interface OpenTrayViteAppBundlePlugin {\n readonly name: \"opentray-app-bundle\";\n readonly apply: \"build\";\n configResolved(config: ViteResolvedConfigLike): void;\n writeBundle(): Promise<void>;\n readonly getLastResult: () => OpenTrayDarwinAppBundleResult | undefined;\n}\n\n/** Vite lifecycle adapter for the shared Darwin app bundle contract. */\nexport const openTrayAppBundlePlugin = (\n options: OpenTrayViteAppBundlePluginOptions,\n): OpenTrayViteAppBundlePlugin => {\n let config: ViteResolvedConfigLike | undefined;\n let lastResult: OpenTrayDarwinAppBundleResult | undefined;\n return {\n name: \"opentray-app-bundle\",\n apply: \"build\",\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n async writeBundle() {\n const resolvedConfig = config ?? {\n root: process.cwd(),\n mode: \"production\",\n build: { outDir: \"dist\" },\n };\n const bundlePath =\n options.bundlePath ?? resolve(\n resolvedConfig.root,\n resolvedConfig.build.outDir,\n `${options.appName}.app`,\n );\n lastResult = await buildDarwinAppBundle({ ...options, bundlePath });\n },\n getLastResult: () => lastResult,\n };\n};\n\nexport const openTrayVitePlugin = (options: OpenTrayVitePluginOptions): OpenTrayVitePlugin => {\n let config: ViteResolvedConfigLike | undefined;\n let lastResult: OpenTrayPackageResult | undefined;\n\n return {\n name: \"opentray-packaging\",\n apply: \"build\",\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n async writeBundle(_options, bundle) {\n const resolvedConfig = config ?? {\n root: process.cwd(),\n mode: \"production\",\n build: { outDir: \"dist\" },\n };\n lastResult = await stageOpenTrayPackage({\n app: options.app,\n outDir: resolve(resolvedConfig.root, resolvedConfig.build.outDir),\n entry: options.entry ?? resolveViteEntry(bundle),\n adapter: { name: \"vite\", mode: resolvedConfig.mode },\n runtimeHost: options.runtimeHost,\n ...(options.nativeArtifacts === undefined\n ? {}\n : { nativeArtifacts: options.nativeArtifacts }),\n ...(options.companionAssets === undefined\n ? {}\n : { companionAssets: options.companionAssets }),\n ...(options.manifestPath === undefined ? {} : { manifestPath: options.manifestPath }),\n });\n },\n getLastResult: () => lastResult,\n };\n};\n\nexport const resolveViteEntry = (bundle: ViteBundleLike): string => {\n const entry = Object.values(bundle)\n .map(asOutputChunk)\n .find((chunk): chunk is ViteOutputChunkLike => chunk?.isEntry === true);\n const identity = entry?.facadeModuleId ?? entry?.fileName ?? entry?.name;\n if (identity === undefined || identity.length === 0) {\n throw new Error(\"OpenTray Vite packaging requires a Vite entry chunk or explicit entry option\");\n }\n return identity;\n};\n\nconst asOutputChunk = (value: unknown): ViteOutputChunkLike | undefined => {\n if (typeof value !== \"object\" || value === null) {\n return undefined;\n }\n const record = value as Record<string, unknown>;\n return {\n ...(record.type === \"chunk\" ? { type: \"chunk\" } : {}),\n ...(typeof record.isEntry === \"boolean\" ? { isEntry: record.isEntry } : {}),\n ...(typeof record.fileName === \"string\" ? { fileName: record.fileName } : {}),\n ...(typeof record.facadeModuleId === \"string\" || record.facadeModuleId === null\n ? { facadeModuleId: record.facadeModuleId }\n : {}),\n ...(typeof record.name === \"string\" ? { name: record.name } : {}),\n };\n};\n\nexport type { OpenTrayPackageManifest, OpenTrayPackageResult };\n\nexport {\n generateOpenTrayAppIcon,\n openTrayAppIconPlugin,\n type OpenTrayAppIconCacheMetadata,\n type OpenTrayAppIconManifest,\n type OpenTrayAppIconOptions,\n type OpenTrayAppIconPluginOptions,\n} from \"./app-icon\";\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentray/vite-plugin",
3
- "version": "0.18.0",
3
+ "version": "0.19.1",
4
4
  "description": "Vite adapter for the OpenTray runtime artifact packaging contract.",
5
5
  "keywords": [
6
6
  "app-icon",
@@ -30,8 +30,8 @@
30
30
  "@shockpkg/icon-encoder": "^3.2.3",
31
31
  "figma-squircle": "^1.1.0",
32
32
  "sharp": "^0.33.5",
33
- "@opentray/packaging": "0.18.0",
34
- "@opentray/spec": "0.18.0"
33
+ "@opentray/spec": "0.19.1",
34
+ "@opentray/packaging": "0.19.1"
35
35
  },
36
36
  "devDependencies": {
37
37
  "tsdown": "^0.22.1",