gunni 0.3.7 → 0.3.8
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.js +51 -23
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -86263,7 +86263,7 @@ var RemoteClient = class {
|
|
|
86263
86263
|
}
|
|
86264
86264
|
}
|
|
86265
86265
|
);
|
|
86266
|
-
this.client = new Client({ name: "gunni-cli", version: "0.3.
|
|
86266
|
+
this.client = new Client({ name: "gunni-cli", version: "0.3.8" });
|
|
86267
86267
|
await this.client.connect(transport);
|
|
86268
86268
|
}
|
|
86269
86269
|
async callTool(name, args) {
|
|
@@ -86437,40 +86437,58 @@ var DEFAULT_MODELS = {
|
|
|
86437
86437
|
"remove-bg": "bria-bg-remove"
|
|
86438
86438
|
};
|
|
86439
86439
|
function registerImageCommand(program3) {
|
|
86440
|
-
program3.command("image").description("Unified image command: generate, edit, describe, upscale, or remove background").argument("[
|
|
86440
|
+
program3.command("image").description("Unified image command: generate, edit, describe, upscale, or remove background").argument("[inputs...]", "Image path(s) or text prompt. Multiple images for multi-ref editing.").option("-m, --model <model>", "Model to use (auto-selected by operation if omitted)").option("-o, --output <path>", "Output file path (default: auto-generated)").option("--width <pixels>", "Image width in pixels", parseInt).option("--height <pixels>", "Image height in pixels", parseInt).option("--seed <number>", "Random seed for reproducibility", parseInt).option("--upscale", "Upscale the input image").option("--remove-bg", "Remove background from the input image").option("--scale <factor>", "Scale factor for upscale (default: 2)", parseInt, 2).option("--variants <count>", "Number of variants to generate", parseInt).option("--style <name>", "Apply a saved visual style").addHelpText(
|
|
86441
86441
|
"after",
|
|
86442
86442
|
`
|
|
86443
86443
|
Examples:
|
|
86444
86444
|
|
|
86445
86445
|
Generate an image:
|
|
86446
|
-
$ gunni image "a cat on a beach" -o cat
|
|
86447
|
-
$ gunni image "product photo" --model nano-banana -o product
|
|
86446
|
+
$ gunni image "a cat on a beach" -o cat
|
|
86447
|
+
$ gunni image "product photo" --model nano-banana -o product
|
|
86448
86448
|
|
|
86449
86449
|
Edit an image:
|
|
86450
|
-
$ gunni image photo.jpg "make the lighting warmer" -o photo-warm
|
|
86451
|
-
$ gunni image logo.png "place on a coffee cup mockup" -o mockup
|
|
86450
|
+
$ gunni image photo.jpg "make the lighting warmer" -o photo-warm
|
|
86451
|
+
$ gunni image logo.png "place on a coffee cup mockup" -o mockup
|
|
86452
|
+
|
|
86453
|
+
Multi-image edit (combine references):
|
|
86454
|
+
$ gunni image fox.jpg forest.jpg "place the fox from @image1 on the path in @image2"
|
|
86455
|
+
$ gunni image character.png style-ref.png "redraw @image1 in the style of @image2"
|
|
86452
86456
|
|
|
86453
86457
|
Describe an image:
|
|
86454
86458
|
$ gunni image photo.jpg
|
|
86455
86459
|
|
|
86456
|
-
Upscale
|
|
86457
|
-
$ gunni image photo.jpg --upscale -o photo-hires
|
|
86458
|
-
$ gunni image
|
|
86459
|
-
|
|
86460
|
-
Remove background:
|
|
86461
|
-
$ gunni image product.png --remove-bg -o product-clean.png
|
|
86460
|
+
Upscale / remove background:
|
|
86461
|
+
$ gunni image photo.jpg --upscale -o photo-hires
|
|
86462
|
+
$ gunni image product.png --remove-bg -o product-clean
|
|
86462
86463
|
|
|
86463
86464
|
Explore with variants:
|
|
86464
|
-
$ gunni image "logo concepts" --variants 4 -o concepts/logo-{n}
|
|
86465
|
+
$ gunni image "logo concepts" --variants 4 -o concepts/logo-{n}
|
|
86465
86466
|
|
|
86466
86467
|
Agent usage:
|
|
86467
86468
|
$ gunni --json image "product photo" --variants 3
|
|
86468
|
-
|
|
86469
|
-
Returns: { operation, results: [{ image: { path, url, width, height }, seed }], model, prompt }
|
|
86470
86469
|
`
|
|
86471
|
-
).action(async (
|
|
86470
|
+
).action(async (inputs, opts) => {
|
|
86472
86471
|
const json2 = program3.opts().json ?? false;
|
|
86473
86472
|
try {
|
|
86473
|
+
if (!inputs || inputs.length === 0) {
|
|
86474
|
+
throw new GunniError(
|
|
86475
|
+
"No input provided. Pass an image path or text prompt.",
|
|
86476
|
+
"MISSING_INPUT",
|
|
86477
|
+
"Run `gunni image --help` for usage examples."
|
|
86478
|
+
);
|
|
86479
|
+
}
|
|
86480
|
+
const imagePaths = [];
|
|
86481
|
+
let prompt;
|
|
86482
|
+
for (const arg of inputs) {
|
|
86483
|
+
if (existsSync(arg)) {
|
|
86484
|
+
imagePaths.push(arg);
|
|
86485
|
+
} else if (!prompt) {
|
|
86486
|
+
prompt = arg;
|
|
86487
|
+
} else {
|
|
86488
|
+
prompt += " " + arg;
|
|
86489
|
+
}
|
|
86490
|
+
}
|
|
86491
|
+
const input = imagePaths.length > 0 ? imagePaths[0] : prompt;
|
|
86474
86492
|
if (!input) {
|
|
86475
86493
|
throw new GunniError(
|
|
86476
86494
|
"No input provided. Pass an image path or text prompt.",
|
|
@@ -86478,13 +86496,13 @@ Examples:
|
|
|
86478
86496
|
"Run `gunni image --help` for usage examples."
|
|
86479
86497
|
);
|
|
86480
86498
|
}
|
|
86481
|
-
const isFile =
|
|
86499
|
+
const isFile = imagePaths.length > 0;
|
|
86482
86500
|
const operation = routeOperation(isFile, prompt, opts);
|
|
86483
86501
|
const config2 = new ConfigManager();
|
|
86484
86502
|
const gunniKey = await config2.getGunniApiKey();
|
|
86485
86503
|
if (gunniKey) {
|
|
86486
86504
|
const serverUrl = await config2.getServerUrl();
|
|
86487
|
-
return handleRemote(input, prompt, operation, opts, json2, gunniKey, serverUrl);
|
|
86505
|
+
return handleRemote(imagePaths.length > 1 ? imagePaths : input, prompt, operation, opts, json2, gunniKey, serverUrl);
|
|
86488
86506
|
}
|
|
86489
86507
|
throw new GunniError(
|
|
86490
86508
|
"No API key configured",
|
|
@@ -86555,9 +86573,10 @@ function resolveVariantPath(template, index) {
|
|
|
86555
86573
|
return `${base}-${index}${ext}`;
|
|
86556
86574
|
}
|
|
86557
86575
|
async function handleRemote(input, prompt, operation, opts, json2, apiKey, serverUrl) {
|
|
86576
|
+
const isMultiImage = Array.isArray(input);
|
|
86558
86577
|
const spinnerLabels = {
|
|
86559
86578
|
generate: "Painting pixels\u2026",
|
|
86560
|
-
edit: "Reworking the canvas\u2026",
|
|
86579
|
+
edit: isMultiImage ? `Combining ${input.length} images\u2026` : "Reworking the canvas\u2026",
|
|
86561
86580
|
describe: "Studying the image\u2026",
|
|
86562
86581
|
upscale: "Enhancing resolution\u2026",
|
|
86563
86582
|
"remove-bg": "Cutting out the background\u2026"
|
|
@@ -86569,8 +86588,17 @@ async function handleRemote(input, prompt, operation, opts, json2, apiKey, serve
|
|
|
86569
86588
|
try {
|
|
86570
86589
|
let imageUrl;
|
|
86571
86590
|
if (operation !== "generate") {
|
|
86572
|
-
|
|
86573
|
-
|
|
86591
|
+
if (isMultiImage) {
|
|
86592
|
+
const urls = [];
|
|
86593
|
+
for (let i2 = 0; i2 < input.length; i2++) {
|
|
86594
|
+
update(`Uploading image ${i2 + 1} of ${input.length}\u2026`);
|
|
86595
|
+
urls.push(await uploadLocalFile(input[i2], apiKey, serverUrl));
|
|
86596
|
+
}
|
|
86597
|
+
imageUrl = urls;
|
|
86598
|
+
} else {
|
|
86599
|
+
update("Uploading image\u2026");
|
|
86600
|
+
imageUrl = await uploadLocalFile(input, apiKey, serverUrl);
|
|
86601
|
+
}
|
|
86574
86602
|
}
|
|
86575
86603
|
let effectiveModel = opts.model ?? DEFAULT_MODELS[operation];
|
|
86576
86604
|
let effectivePrompt = operation === "generate" ? input : prompt;
|
|
@@ -90917,7 +90945,7 @@ async function runOnboarding() {
|
|
|
90917
90945
|
|
|
90918
90946
|
// src/index.ts
|
|
90919
90947
|
var program2 = new Command();
|
|
90920
|
-
program2.name("gunni").description("AI media toolkit \u2014 give any agent the ability to create professional media").version("0.3.
|
|
90948
|
+
program2.name("gunni").description("AI media toolkit \u2014 give any agent the ability to create professional media").version("0.3.8").option("--json", "Output results as JSON").addHelpText(
|
|
90921
90949
|
"after",
|
|
90922
90950
|
`
|
|
90923
90951
|
Examples:
|
|
@@ -91017,7 +91045,7 @@ program2.action(async () => {
|
|
|
91017
91045
|
{ name: "models", usage: "gunni models [--type <category>]", description: "List available models" },
|
|
91018
91046
|
{ name: "config", usage: "gunni config", description: "Manage API keys" }
|
|
91019
91047
|
];
|
|
91020
|
-
console.log(JSON.stringify({ version: "0.3.
|
|
91048
|
+
console.log(JSON.stringify({ version: "0.3.8", commands, categories, models }, null, 2));
|
|
91021
91049
|
return;
|
|
91022
91050
|
}
|
|
91023
91051
|
const configured = await hasGunniKey();
|