@exreve/exk 1.0.64 → 1.0.65

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.
@@ -298,23 +298,45 @@ export async function executeGenImage(args, _config) {
298
298
  if (!dataUrl || !dataUrl.startsWith('data:')) {
299
299
  return { content: [{ type: 'text', text: `Error: Unexpected image format from Flux API.` }], isError: true };
300
300
  }
301
- // Decode base64 and save to temp dir
301
+ // Decode base64
302
302
  const base64 = dataUrl.split(',')[1];
303
303
  if (!base64) {
304
304
  return { content: [{ type: 'text', text: 'Error: Empty image data from Flux API.' }], isError: true };
305
305
  }
306
- const imgBuf = Buffer.from(base64, 'base64');
306
+ const rawBuf = Buffer.from(base64, 'base64');
307
+ const rawKb = (rawBuf.length / 1024).toFixed(0);
308
+ // Compress to WebP with sharp (high quality, same dimensions)
309
+ let finalBuf;
310
+ let ext = 'webp';
311
+ try {
312
+ const sharp = (await import('sharp')).default;
313
+ finalBuf = await sharp(rawBuf)
314
+ .webp({ quality: 90, effort: 4 })
315
+ .toBuffer();
316
+ // If compression didn't help (rare), keep original PNG
317
+ if (finalBuf.length >= rawBuf.length) {
318
+ finalBuf = rawBuf;
319
+ ext = 'png';
320
+ }
321
+ }
322
+ catch {
323
+ // sharp not available — save raw PNG
324
+ finalBuf = rawBuf;
325
+ ext = 'png';
326
+ }
307
327
  const tmpDir = path.join(os.tmpdir(), 'talk-to-code', 'gen-images');
308
328
  fs.mkdirSync(tmpDir, { recursive: true });
309
329
  const safeName = (args.filename || `gen_${Date.now()}`).replace(/[^a-zA-Z0-9._-]/g, '_');
310
- const fileName = safeName.endsWith('.png') ? safeName : `${safeName}.png`;
330
+ const baseName = safeName.replace(/\.(png|webp|jpg|jpeg)$/i, '');
331
+ const fileName = `${baseName}.${ext}`;
311
332
  const filePath = path.join(tmpDir, fileName);
312
- fs.writeFileSync(filePath, imgBuf);
313
- const sizeKb = (imgBuf.length / 1024).toFixed(0);
333
+ fs.writeFileSync(filePath, finalBuf);
334
+ const sizeKb = (finalBuf.length / 1024).toFixed(0);
335
+ const saved = ext === 'webp' ? ` (${rawKb} KB PNG → ${sizeKb} KB WebP)` : '';
314
336
  return {
315
337
  content: [{
316
338
  type: 'text',
317
- text: `Image generated successfully.\n\nFile: ${filePath}\nSize: ${sizeKb} KB\nPrompt: ${args.prompt}`,
339
+ text: `Image generated successfully.\n\nFile: ${filePath}\nSize: ${sizeKb} KB${saved}\nPrompt: ${args.prompt}`,
318
340
  }],
319
341
  details: { filePath, sizeKb, prompt: args.prompt },
320
342
  };
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exreve/exk",
3
- "version": "1.0.64",
3
+ "version": "1.0.65",
4
4
  "description": "exk - Control Claude CLI with voice and programmable interfaces",
5
5
  "type": "module",
6
6
  "bin": {