@coreviz/cli 1.0.8 → 1.0.9
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/README.md +1 -1
- package/bin/cli.js +237 -61
- package/examples/bulk_edit_with_nanobanana/62cc0c0ab7208b594ba989daa450cf54263667fc-3718x2400.jpg +0 -0
- package/examples/bulk_edit_with_nanobanana/DSC_0359.jpg +0 -0
- package/examples/bulk_edit_with_nanobanana/Elfreth's_Alley.jpeg +0 -0
- package/examples/bulk_edit_with_nanobanana/edited-1764197873666-62cc0c0ab7208b594ba989daa450cf54263667fc-3718x2400.jpg +0 -0
- package/examples/bulk_edit_with_nanobanana/edited-1764197885861-DSC_0359.jpg +0 -0
- package/examples/bulk_edit_with_nanobanana/edited-1764197898854-Elfreth's_Alley.jpeg +0 -0
- package/examples/bulk_edit_with_nanobanana/script.sh +13 -0
- package/examples/organize_by_jersey_number/2221019486.webp +0 -0
- package/examples/organize_by_jersey_number/84107528007.webp +0 -0
- package/examples/organize_by_jersey_number/DP5BW7BGSFEGTEANNGOOM6GXGA.jpg +0 -0
- package/examples/organize_by_jersey_number/Jalen Williams Oklahoma City Thunder.jpg +0 -0
- package/examples/organize_by_jersey_number/README.md +0 -0
- package/examples/organize_by_jersey_number/download-player.jpeg +0 -0
- package/examples/organize_by_jersey_number/download-thunder.jpeg +0 -0
- package/examples/organize_by_jersey_number/download.jpeg +0 -0
- package/examples/organize_by_jersey_number/okc-thunder copy.jpg +0 -0
- package/examples/organize_by_jersey_number/okc-thunder.jpg +0 -0
- package/examples/organize_by_jersey_number/script.sh +22 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ npx @coreviz/cli describe path/to/image.jpg
|
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
Edit an image with a text prompt:
|
|
55
|
+
Edit an image with a text prompt (🍌 Nano Banan + Flux Kontext in the CLI!):
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
58
|
npx @coreviz/cli edit path/to/image.jpg --prompt "make it cyberpunk style"
|
package/bin/cli.js
CHANGED
|
@@ -195,25 +195,38 @@ program.command('whoami')
|
|
|
195
195
|
}
|
|
196
196
|
});
|
|
197
197
|
|
|
198
|
-
program.command('edit <image-path>')
|
|
198
|
+
program.command('edit <image-path> <prompt>')
|
|
199
199
|
.description('Edit an image using AI')
|
|
200
|
-
.option('
|
|
201
|
-
.action(async (imagePath, options) => {
|
|
202
|
-
|
|
200
|
+
.option('--quiet', 'Suppress UI output (for scripting)')
|
|
201
|
+
.action(async (imagePath, prompt, options) => {
|
|
202
|
+
if (!options.quiet) {
|
|
203
|
+
intro(chalk.bgHex('#663399').white('CoreViz'));
|
|
204
|
+
}
|
|
203
205
|
|
|
204
206
|
const session = config.get('session');
|
|
205
207
|
if (!session || !session.access_token) {
|
|
208
|
+
if (options.quiet) {
|
|
209
|
+
console.error('Not logged in.');
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
206
212
|
cancel('You are not logged in. Please run `coreviz login` first.');
|
|
207
213
|
process.exit(1);
|
|
208
214
|
}
|
|
209
215
|
|
|
210
216
|
if (!fs.existsSync(imagePath)) {
|
|
217
|
+
if (options.quiet) {
|
|
218
|
+
console.error(`File not found: ${imagePath}`);
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
211
221
|
cancel(`File not found: ${imagePath}`);
|
|
212
222
|
process.exit(1);
|
|
213
223
|
}
|
|
214
224
|
|
|
215
|
-
let prompt = options.prompt;
|
|
216
225
|
if (!prompt) {
|
|
226
|
+
if (options.quiet) {
|
|
227
|
+
console.error('Prompt is required in quiet mode.');
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
217
230
|
prompt = await text({
|
|
218
231
|
message: 'What would you like to change in the image?',
|
|
219
232
|
placeholder: 'e.g., "Make it look like a painting" or "Add a red hat"',
|
|
@@ -228,8 +241,11 @@ program.command('edit <image-path>')
|
|
|
228
241
|
}
|
|
229
242
|
}
|
|
230
243
|
|
|
231
|
-
|
|
232
|
-
|
|
244
|
+
let spinner;
|
|
245
|
+
if (!options.quiet) {
|
|
246
|
+
spinner = yoctoSpinner({ text: "Processing image..." });
|
|
247
|
+
spinner.start();
|
|
248
|
+
}
|
|
233
249
|
|
|
234
250
|
try {
|
|
235
251
|
const base64Image = readImageAsBase64(imagePath);
|
|
@@ -239,57 +255,199 @@ program.command('edit <image-path>')
|
|
|
239
255
|
prompt
|
|
240
256
|
});
|
|
241
257
|
|
|
242
|
-
spinner.stop();
|
|
258
|
+
if (spinner) spinner.stop();
|
|
243
259
|
|
|
244
260
|
// Save result
|
|
245
261
|
const outputFilename = `edited-${Date.now()}-${path.basename(imagePath)}`;
|
|
246
262
|
const outputBuffer = Buffer.from(resultBase64.replace(/^data:image\/\w+;base64,/, ""), 'base64');
|
|
247
263
|
fs.writeFileSync(outputFilename, outputBuffer);
|
|
248
264
|
|
|
249
|
-
|
|
265
|
+
if (options.quiet) {
|
|
266
|
+
console.log(outputFilename);
|
|
267
|
+
} else {
|
|
268
|
+
outro(chalk.green(`✅ Image edited successfully! Saved as ${outputFilename}`));
|
|
269
|
+
}
|
|
250
270
|
|
|
251
271
|
} catch (error) {
|
|
252
|
-
spinner.stop();
|
|
253
|
-
|
|
272
|
+
if (spinner) spinner.stop();
|
|
273
|
+
const msg = error.message.includes('credits')
|
|
274
|
+
? 'Insufficient credits. Please add credits to your account on https://lab.coreviz.io.'
|
|
275
|
+
: `Failed to edit image: ${error.message}`;
|
|
276
|
+
if (options.quiet) {
|
|
277
|
+
console.error(msg);
|
|
278
|
+
} else {
|
|
279
|
+
cancel(msg);
|
|
280
|
+
}
|
|
254
281
|
process.exit(1);
|
|
255
282
|
}
|
|
256
283
|
});
|
|
257
284
|
|
|
258
285
|
program.command('describe <image-path>')
|
|
259
286
|
.description('Describe an image using AI')
|
|
260
|
-
.
|
|
261
|
-
|
|
287
|
+
.option('--quiet', 'Suppress UI output (for scripting)')
|
|
288
|
+
.action(async (imagePath, options) => {
|
|
289
|
+
if (!options.quiet) {
|
|
290
|
+
intro(chalk.bgHex('#663399').white('CoreViz'));
|
|
291
|
+
}
|
|
262
292
|
|
|
263
293
|
const session = config.get('session');
|
|
264
294
|
if (!session || !session.access_token) {
|
|
295
|
+
if (options.quiet) {
|
|
296
|
+
console.error('Not logged in.');
|
|
297
|
+
process.exit(1);
|
|
298
|
+
}
|
|
265
299
|
cancel('You are not logged in. Please run `coreviz login` first.');
|
|
266
300
|
process.exit(1);
|
|
267
301
|
}
|
|
268
302
|
|
|
269
303
|
if (!fs.existsSync(imagePath)) {
|
|
304
|
+
if (options.quiet) {
|
|
305
|
+
console.error(`File not found: ${imagePath}`);
|
|
306
|
+
process.exit(1);
|
|
307
|
+
}
|
|
270
308
|
cancel(`File not found: ${imagePath}`);
|
|
271
309
|
process.exit(1);
|
|
272
310
|
}
|
|
273
311
|
|
|
274
|
-
|
|
275
|
-
|
|
312
|
+
let spinner;
|
|
313
|
+
if (!options.quiet) {
|
|
314
|
+
spinner = yoctoSpinner({ text: "Analyzing image..." });
|
|
315
|
+
spinner.start();
|
|
316
|
+
}
|
|
276
317
|
|
|
277
318
|
try {
|
|
278
319
|
const base64Image = readImageAsBase64(imagePath);
|
|
279
320
|
const coreviz = new CoreViz({ token: session.access_token });
|
|
280
321
|
const description = await coreviz.describe(base64Image);
|
|
281
322
|
|
|
282
|
-
spinner.stop();
|
|
323
|
+
if (spinner) spinner.stop();
|
|
283
324
|
|
|
284
|
-
|
|
285
|
-
|
|
325
|
+
if (options.quiet) {
|
|
326
|
+
console.log(description);
|
|
327
|
+
} else {
|
|
328
|
+
outro(chalk.green('✅ Image description:'));
|
|
329
|
+
console.log(description);
|
|
330
|
+
}
|
|
286
331
|
} catch (error) {
|
|
287
|
-
spinner.stop();
|
|
288
|
-
|
|
289
|
-
|
|
332
|
+
if (spinner) spinner.stop();
|
|
333
|
+
const msg = error.message.includes('credits')
|
|
334
|
+
? 'Insufficient credits. Please add credits to your account on https://lab.coreviz.io.'
|
|
335
|
+
: `Failed to describe image: ${error.message}`;
|
|
336
|
+
|
|
337
|
+
if (options.quiet) {
|
|
338
|
+
console.error(msg);
|
|
339
|
+
} else {
|
|
340
|
+
cancel(msg);
|
|
341
|
+
}
|
|
342
|
+
process.exit(1);
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
program.command('tag <image-path> <prompt>')
|
|
347
|
+
.description('Generate tags for an image using AI')
|
|
348
|
+
.option('--choices <items>', 'Comma-separated list of possible tags to choose from (optional)', '')
|
|
349
|
+
.option('--single', 'Return only one tag', false)
|
|
350
|
+
.option('-m, --mode <mode>', 'The mode to use for tagging. Defaults to "api".', 'api')
|
|
351
|
+
.option('--quiet', 'Output raw text for scripting (suppresses UI)')
|
|
352
|
+
.action(async (imagePath, prompt, options) => {
|
|
353
|
+
if (!options.quiet) {
|
|
354
|
+
intro(chalk.bgHex('#663399').white('CoreViz'));
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const session = config.get('session');
|
|
358
|
+
if (!session || !session.access_token) {
|
|
359
|
+
if (options.quiet) {
|
|
360
|
+
console.error('Not logged in.');
|
|
361
|
+
process.exit(1);
|
|
362
|
+
}
|
|
363
|
+
cancel('You are not logged in. Please run `coreviz login` first.');
|
|
364
|
+
process.exit(1);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (!fs.existsSync(imagePath)) {
|
|
368
|
+
if (options.quiet) {
|
|
369
|
+
console.error(`File not found: ${imagePath}`);
|
|
290
370
|
process.exit(1);
|
|
291
371
|
}
|
|
292
|
-
cancel(`
|
|
372
|
+
cancel(`File not found: ${imagePath}`);
|
|
373
|
+
process.exit(1);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
let tagList = options.choices ? options.choices.split(',').map(s => s.trim()) : undefined;
|
|
377
|
+
|
|
378
|
+
if (!prompt) {
|
|
379
|
+
if (tagList && tagList.length > 0) {
|
|
380
|
+
prompt = "Select the best matching tags";
|
|
381
|
+
} else {
|
|
382
|
+
if (options.quiet) {
|
|
383
|
+
console.error('Prompt is required in quiet mode.');
|
|
384
|
+
process.exit(1);
|
|
385
|
+
}
|
|
386
|
+
prompt = await text({
|
|
387
|
+
message: 'What kind of tags do you want to generate?',
|
|
388
|
+
placeholder: 'e.g., "jersey number of the player", "color of the car", etc.',
|
|
389
|
+
validate(value) {
|
|
390
|
+
if (value.length === 0) return `Value is required!`;
|
|
391
|
+
},
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
if (isCancel(prompt)) {
|
|
395
|
+
cancel('Operation cancelled.');
|
|
396
|
+
process.exit(0);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
let spinner;
|
|
402
|
+
if (!options.quiet) {
|
|
403
|
+
setTimeout(() => {
|
|
404
|
+
if (spinner.isSpinning && options.mode === 'local') {
|
|
405
|
+
spinner.text = "On the first run, it might take a few minutes to load the local model, please wait...";
|
|
406
|
+
} else if (spinner.isSpinning && options.mode === 'api') {
|
|
407
|
+
spinner.text = "This might take a few seconds...";
|
|
408
|
+
}
|
|
409
|
+
}, 8000);
|
|
410
|
+
spinner = yoctoSpinner({ text: "Generating tags..." });
|
|
411
|
+
spinner.start();
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
try {
|
|
415
|
+
const base64Image = readImageAsBase64(imagePath);
|
|
416
|
+
const coreviz = new CoreViz({ token: session.access_token });
|
|
417
|
+
|
|
418
|
+
const response = await coreviz.tag(base64Image, {
|
|
419
|
+
mode: options.mode,
|
|
420
|
+
prompt,
|
|
421
|
+
options: tagList,
|
|
422
|
+
multiple: !options.single
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
if (spinner) spinner.stop();
|
|
426
|
+
|
|
427
|
+
if (options.quiet) {
|
|
428
|
+
if (response.tags && response.tags.length > 0) {
|
|
429
|
+
console.log(response.tags.join('\n'));
|
|
430
|
+
}
|
|
431
|
+
} else {
|
|
432
|
+
if (response.tags && response.tags.length > 0) {
|
|
433
|
+
outro(chalk.green('✅ Tags generated:'));
|
|
434
|
+
response.tags.forEach(tag => console.log(chalk.blue(`• ${tag}`)));
|
|
435
|
+
} else {
|
|
436
|
+
outro(chalk.yellow('No tags generated.'));
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
} catch (error) {
|
|
441
|
+
if (spinner) spinner.stop();
|
|
442
|
+
const msg = error.message.includes('credits')
|
|
443
|
+
? 'Insufficient credits. Please add credits to your account on https://lab.coreviz.io.'
|
|
444
|
+
: `Failed to generate tags: ${error.message}`;
|
|
445
|
+
|
|
446
|
+
if (options.quiet) {
|
|
447
|
+
console.error(msg);
|
|
448
|
+
} else {
|
|
449
|
+
cancel(msg);
|
|
450
|
+
}
|
|
293
451
|
process.exit(1);
|
|
294
452
|
}
|
|
295
453
|
});
|
|
@@ -297,19 +455,29 @@ program.command('describe <image-path>')
|
|
|
297
455
|
program.command('search <query>')
|
|
298
456
|
.description('Search for images in the current directory using AI')
|
|
299
457
|
.option('-m, --mode <mode>', 'The mode to use for embedding. Defaults to "local".', 'local')
|
|
458
|
+
.option('--quiet', 'Suppress UI output (for scripting)')
|
|
300
459
|
.action(async (query, options) => {
|
|
301
|
-
|
|
460
|
+
if (!options.quiet) {
|
|
461
|
+
intro(chalk.bgHex('#663399').white('CoreViz'));
|
|
462
|
+
}
|
|
302
463
|
|
|
303
464
|
const mode = options.mode || 'local';
|
|
304
465
|
|
|
305
466
|
const session = config.get('session');
|
|
306
467
|
if (!session || !session.access_token) {
|
|
468
|
+
if (options.quiet) {
|
|
469
|
+
console.error('Not logged in.');
|
|
470
|
+
process.exit(1);
|
|
471
|
+
}
|
|
307
472
|
cancel('You are not logged in. Please run `coreviz login` first.');
|
|
308
473
|
process.exit(1);
|
|
309
474
|
}
|
|
310
475
|
|
|
311
|
-
|
|
312
|
-
|
|
476
|
+
let spinner;
|
|
477
|
+
if (!options.quiet) {
|
|
478
|
+
spinner = yoctoSpinner({ text: "Indexing directory..." });
|
|
479
|
+
spinner.start();
|
|
480
|
+
}
|
|
313
481
|
|
|
314
482
|
const dbPath = path.join(process.cwd(), '.index.db');
|
|
315
483
|
const db = new Database(dbPath);
|
|
@@ -328,7 +496,12 @@ program.command('search <query>')
|
|
|
328
496
|
.filter(file => imageExtensions.includes(path.extname(file).toLowerCase()));
|
|
329
497
|
|
|
330
498
|
if (files.length === 0) {
|
|
331
|
-
spinner.stop();
|
|
499
|
+
if (spinner) spinner.stop();
|
|
500
|
+
if (options.quiet) {
|
|
501
|
+
// No images found, just exit with 0 (empty result) or 1?
|
|
502
|
+
// Usually empty search is exit 0 with empty stdout.
|
|
503
|
+
process.exit(0);
|
|
504
|
+
}
|
|
332
505
|
cancel('No images found in the current directory.');
|
|
333
506
|
process.exit(0);
|
|
334
507
|
}
|
|
@@ -350,10 +523,13 @@ program.command('search <query>')
|
|
|
350
523
|
|
|
351
524
|
if (mode === 'local') {
|
|
352
525
|
// You're using the local model, it might take a few minutes for the model to load on the first run.
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
526
|
+
setTimeout(() => {
|
|
527
|
+
if (spinner.isSpinning && mode === 'local') {
|
|
528
|
+
spinner.text = "On the first run, it might take a few minutes to load the local model, please wait...";
|
|
529
|
+
}
|
|
530
|
+
}, 8000);
|
|
531
|
+
await coreviz.embed('text', { type: 'text', mode: mode });
|
|
532
|
+
if (spinner) spinner.stop();
|
|
357
533
|
}
|
|
358
534
|
|
|
359
535
|
for (const file of files) {
|
|
@@ -368,7 +544,7 @@ program.command('search <query>')
|
|
|
368
544
|
continue;
|
|
369
545
|
}
|
|
370
546
|
|
|
371
|
-
spinner.text = `Indexing ${file}...`;
|
|
547
|
+
if (spinner) spinner.text = `Indexing ${file}...`;
|
|
372
548
|
|
|
373
549
|
try {
|
|
374
550
|
const base64Image = readImageAsBase64(filePath);
|
|
@@ -377,11 +553,17 @@ program.command('search <query>')
|
|
|
377
553
|
upsertFile.run(file, mtime, JSON.stringify(embedding));
|
|
378
554
|
} catch (error) {
|
|
379
555
|
// Log error but continue
|
|
380
|
-
|
|
556
|
+
if (!options.quiet) {
|
|
557
|
+
if (error.message.includes('credits')) {
|
|
558
|
+
cancel('Insufficient credits. Please add credits to your account on https://lab.coreviz.io.');
|
|
559
|
+
process.exit(1);
|
|
560
|
+
}
|
|
561
|
+
console.error(`Failed to index ${file}: ${error.message}`);
|
|
562
|
+
}
|
|
381
563
|
}
|
|
382
564
|
}
|
|
383
565
|
|
|
384
|
-
spinner.text = "Processing search query...";
|
|
566
|
+
if (spinner) spinner.text = "Processing search query...";
|
|
385
567
|
|
|
386
568
|
try {
|
|
387
569
|
const { embedding: queryEmbedding } = await coreviz.embed(query, { type: 'text', mode: mode });
|
|
@@ -395,50 +577,44 @@ program.command('search <query>')
|
|
|
395
577
|
const fileEmbedding = JSON.parse(row.embedding);
|
|
396
578
|
|
|
397
579
|
// Calculate cosine similarity
|
|
398
|
-
const similarity =
|
|
580
|
+
const similarity = coreviz.similarity(queryEmbedding, fileEmbedding);
|
|
399
581
|
results.push({ file: row.path, similarity });
|
|
400
582
|
}
|
|
401
583
|
|
|
402
584
|
// Sort by similarity descending
|
|
403
585
|
results.sort((a, b) => b.similarity - a.similarity);
|
|
404
586
|
|
|
405
|
-
spinner.stop();
|
|
587
|
+
if (spinner) spinner.stop();
|
|
406
588
|
|
|
407
|
-
|
|
589
|
+
if (options.quiet) {
|
|
590
|
+
// Output raw file paths (top 5)
|
|
591
|
+
results.slice(0, 5).forEach(result => {
|
|
592
|
+
console.log(result.file);
|
|
593
|
+
});
|
|
594
|
+
} else {
|
|
595
|
+
outro(chalk.green(`✅ Search results for "${query}"`));
|
|
408
596
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
597
|
+
// Show top 5 results
|
|
598
|
+
results.slice(0, 5).forEach((result, i) => {
|
|
599
|
+
const score = (result.similarity * 100).toFixed(1);
|
|
600
|
+
console.log(`${i + 1}. ${chalk.bold(result.file)} ${chalk.gray(`(${score}%)`)}`);
|
|
601
|
+
});
|
|
602
|
+
}
|
|
414
603
|
|
|
415
604
|
} catch (error) {
|
|
416
|
-
spinner.stop();
|
|
417
|
-
|
|
605
|
+
if (spinner) spinner.stop();
|
|
606
|
+
const msg = `Search failed: ${error.message}`;
|
|
607
|
+
if (options.quiet) {
|
|
608
|
+
console.error(msg);
|
|
609
|
+
} else {
|
|
610
|
+
cancel(msg);
|
|
611
|
+
}
|
|
418
612
|
process.exit(1);
|
|
419
613
|
} finally {
|
|
420
614
|
db.close();
|
|
421
615
|
}
|
|
422
616
|
});
|
|
423
617
|
|
|
424
|
-
function cosineSimilarity(vecA, vecB) {
|
|
425
|
-
if (vecA.length !== vecB.length) return 0;
|
|
426
|
-
|
|
427
|
-
let dotProduct = 0;
|
|
428
|
-
let normA = 0;
|
|
429
|
-
let normB = 0;
|
|
430
|
-
|
|
431
|
-
for (let i = 0; i < vecA.length; i++) {
|
|
432
|
-
dotProduct += vecA[i] * vecB[i];
|
|
433
|
-
normA += vecA[i] * vecA[i];
|
|
434
|
-
normB += vecB[i] * vecB[i];
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
if (normA === 0 || normB === 0) return 0;
|
|
438
|
-
|
|
439
|
-
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
440
|
-
}
|
|
441
|
-
|
|
442
618
|
function readImageAsBase64(imagePath) {
|
|
443
619
|
const imageBuffer = fs.readFileSync(imagePath);
|
|
444
620
|
return `data:image/${path.extname(imagePath).slice(1) || 'jpeg'};base64,${imageBuffer.toString('base64')}`;
|
package/examples/bulk_edit_with_nanobanana/62cc0c0ab7208b594ba989daa450cf54263667fc-3718x2400.jpg
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Loop through all image files
|
|
4
|
+
for file in *.jpg *.png *.jpeg *.webp; do
|
|
5
|
+
[ -e "$file" ] || continue
|
|
6
|
+
|
|
7
|
+
echo "Processing $file..."
|
|
8
|
+
|
|
9
|
+
# Extract jersey number using coreviz tag with --quiet
|
|
10
|
+
jersey_number=$(npx @coreviz/cli edit "$file" --prompt "make it cyberpunk style")
|
|
11
|
+
|
|
12
|
+
echo " Edited image: $edited_image"
|
|
13
|
+
done
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Loop through all image files
|
|
4
|
+
for file in *.jpg *.png *.jpeg *.webp; do
|
|
5
|
+
[ -e "$file" ] || continue
|
|
6
|
+
|
|
7
|
+
echo "Processing $file..."
|
|
8
|
+
|
|
9
|
+
# Extract jersey number using coreviz tag with --quiet
|
|
10
|
+
jersey_number=$(npx @coreviz/cli tag "$file" "What is the player's jersey number? Return only the number." \
|
|
11
|
+
--single \
|
|
12
|
+
--mode local \
|
|
13
|
+
--quiet)
|
|
14
|
+
|
|
15
|
+
if [ -n "$jersey_number" ]; then
|
|
16
|
+
echo " Found jersey number: $jersey_number"
|
|
17
|
+
mkdir -p "player_$jersey_number"
|
|
18
|
+
mv "$file" "player_$jersey_number/"
|
|
19
|
+
else
|
|
20
|
+
echo " Could not detect jersey number for $file"
|
|
21
|
+
fi
|
|
22
|
+
done
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreviz/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CoreViz CLI tool",
|
|
6
6
|
"main": "index.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"homepage": "https://github.com/CoreViz/cli#readme",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@clack/prompts": "^0.11.0",
|
|
30
|
-
"@coreviz/sdk": "^1.0.
|
|
30
|
+
"@coreviz/sdk": "^1.0.10",
|
|
31
31
|
"better-auth": "^1.4.2",
|
|
32
32
|
"better-sqlite3": "^12.4.6",
|
|
33
33
|
"chalk": "^5.6.2",
|