gunni 0.3.5 → 0.3.7
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 +84 -55
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -69400,7 +69400,8 @@ async function downloadImage(url2, outputPath, onProgress) {
|
|
|
69400
69400
|
const correctExt = await detectImageFormat(outputPath);
|
|
69401
69401
|
const currentExt = extname(outputPath).toLowerCase();
|
|
69402
69402
|
if (correctExt && correctExt !== currentExt) {
|
|
69403
|
-
const
|
|
69403
|
+
const basePath = currentExt ? outputPath.slice(0, -currentExt.length) : outputPath;
|
|
69404
|
+
const fixedPath = basePath + correctExt;
|
|
69404
69405
|
await rename(outputPath, fixedPath);
|
|
69405
69406
|
return fixedPath;
|
|
69406
69407
|
}
|
|
@@ -69431,7 +69432,8 @@ async function saveImageData(data, outputPath, onProgress) {
|
|
|
69431
69432
|
const correctExt = await detectImageFormat(outputPath);
|
|
69432
69433
|
const currentExt = extname(outputPath).toLowerCase();
|
|
69433
69434
|
if (correctExt && correctExt !== currentExt) {
|
|
69434
|
-
const
|
|
69435
|
+
const basePath = currentExt ? outputPath.slice(0, -currentExt.length) : outputPath;
|
|
69436
|
+
const fixedPath = basePath + correctExt;
|
|
69435
69437
|
await rename(outputPath, fixedPath);
|
|
69436
69438
|
return fixedPath;
|
|
69437
69439
|
}
|
|
@@ -70466,7 +70468,7 @@ var ModelRouter = class {
|
|
|
70466
70468
|
const provider = this.resolveProvider(opts.model);
|
|
70467
70469
|
let spinner;
|
|
70468
70470
|
if (opts.showSpinner !== false) {
|
|
70469
|
-
spinner = ora("
|
|
70471
|
+
spinner = ora("Painting pixels\u2026").start();
|
|
70470
70472
|
}
|
|
70471
70473
|
const updateSpinner = (status) => {
|
|
70472
70474
|
if (spinner) spinner.text = status;
|
|
@@ -86261,7 +86263,7 @@ var RemoteClient = class {
|
|
|
86261
86263
|
}
|
|
86262
86264
|
}
|
|
86263
86265
|
);
|
|
86264
|
-
this.client = new Client({ name: "gunni-cli", version: "0.3.
|
|
86266
|
+
this.client = new Client({ name: "gunni-cli", version: "0.3.7" });
|
|
86265
86267
|
await this.client.connect(transport);
|
|
86266
86268
|
}
|
|
86267
86269
|
async callTool(name, args) {
|
|
@@ -86553,7 +86555,14 @@ function resolveVariantPath(template, index) {
|
|
|
86553
86555
|
return `${base}-${index}${ext}`;
|
|
86554
86556
|
}
|
|
86555
86557
|
async function handleRemote(input, prompt, operation, opts, json2, apiKey, serverUrl) {
|
|
86556
|
-
const
|
|
86558
|
+
const spinnerLabels = {
|
|
86559
|
+
generate: "Painting pixels\u2026",
|
|
86560
|
+
edit: "Reworking the canvas\u2026",
|
|
86561
|
+
describe: "Studying the image\u2026",
|
|
86562
|
+
upscale: "Enhancing resolution\u2026",
|
|
86563
|
+
"remove-bg": "Cutting out the background\u2026"
|
|
86564
|
+
};
|
|
86565
|
+
const spinner = json2 ? void 0 : ora(spinnerLabels[operation]).start();
|
|
86557
86566
|
const update = (s2) => {
|
|
86558
86567
|
if (spinner) spinner.text = s2;
|
|
86559
86568
|
};
|
|
@@ -86603,7 +86612,7 @@ async function handleRemote(input, prompt, operation, opts, json2, apiKey, serve
|
|
|
86603
86612
|
if (opts.width) toolArgs.width = opts.width;
|
|
86604
86613
|
if (opts.height) toolArgs.height = opts.height;
|
|
86605
86614
|
if (opts.seed !== void 0) toolArgs.seed = opts.seed;
|
|
86606
|
-
update(
|
|
86615
|
+
update(spinnerLabels[operation]);
|
|
86607
86616
|
const client2 = new RemoteClient();
|
|
86608
86617
|
await client2.connect(apiKey, serverUrl);
|
|
86609
86618
|
const result = await client2.callTool("image", toolArgs);
|
|
@@ -86624,7 +86633,7 @@ async function handleRemote(input, prompt, operation, opts, json2, apiKey, serve
|
|
|
86624
86633
|
const r2 = remoteResults[i2];
|
|
86625
86634
|
if (!r2.assetUrl) continue;
|
|
86626
86635
|
const requestedPath2 = remoteResults.length === 1 ? opts.output ?? `gunni-${operation}-${Date.now()}.png` : opts.output ? resolveVariantPath(opts.output, i2 + 1) : `gunni-${operation}-${Date.now()}-${i2 + 1}.png`;
|
|
86627
|
-
update("
|
|
86636
|
+
update("Saving to disk\u2026");
|
|
86628
86637
|
const finalPath2 = await downloadImage(r2.assetUrl, requestedPath2, update);
|
|
86629
86638
|
downloadedResults.push({
|
|
86630
86639
|
image: { path: finalPath2, url: r2.assetUrl, width: r2.width ?? 0, height: r2.height ?? 0 },
|
|
@@ -86656,7 +86665,7 @@ async function handleRemote(input, prompt, operation, opts, json2, apiKey, serve
|
|
|
86656
86665
|
throw new GunniError("No image in remote response", "NO_IMAGE");
|
|
86657
86666
|
}
|
|
86658
86667
|
const requestedPath = opts.output ?? `gunni-${operation}-${Date.now()}.png`;
|
|
86659
|
-
update("
|
|
86668
|
+
update("Saving to disk\u2026");
|
|
86660
86669
|
const finalPath = await downloadImage(img.assetUrl, requestedPath, update);
|
|
86661
86670
|
spinner?.succeed("Done");
|
|
86662
86671
|
if (json2) {
|
|
@@ -86724,9 +86733,9 @@ async function handleGenerate(prompt, modelId, opts, json2) {
|
|
|
86724
86733
|
return;
|
|
86725
86734
|
}
|
|
86726
86735
|
const results = [];
|
|
86727
|
-
const spinner = json2 ? void 0 : ora(`
|
|
86736
|
+
const spinner = json2 ? void 0 : ora(`Painting variant 1 of ${variantCount}\u2026`).start();
|
|
86728
86737
|
for (let i2 = 1; i2 <= variantCount; i2++) {
|
|
86729
|
-
if (spinner) spinner.text = `
|
|
86738
|
+
if (spinner) spinner.text = `Painting variant ${i2} of ${variantCount}\u2026`;
|
|
86730
86739
|
const outputPath = opts.output ? resolveVariantPath(opts.output, i2) : `gunni-${modelId}-${Date.now()}-${i2}.png`;
|
|
86731
86740
|
const router = new ModelRouter();
|
|
86732
86741
|
const result = await router.generate({
|
|
@@ -86775,15 +86784,15 @@ async function handleGenerate(prompt, modelId, opts, json2) {
|
|
|
86775
86784
|
}
|
|
86776
86785
|
async function handleEdit(imagePath, prompt, modelId, opts, json2) {
|
|
86777
86786
|
const variantCount = opts.variants ?? 1;
|
|
86778
|
-
const spinner = json2 ? void 0 : ora("
|
|
86787
|
+
const spinner = json2 ? void 0 : ora("Reworking the canvas\u2026").start();
|
|
86779
86788
|
const update = (s2) => {
|
|
86780
86789
|
if (spinner) spinner.text = s2;
|
|
86781
86790
|
};
|
|
86782
86791
|
const provider = getProviderForModel(modelId);
|
|
86783
86792
|
const results = [];
|
|
86784
86793
|
for (let i2 = 1; i2 <= variantCount; i2++) {
|
|
86785
|
-
if (variantCount > 1) update(`
|
|
86786
|
-
else update("
|
|
86794
|
+
if (variantCount > 1) update(`Reworking variant ${i2} of ${variantCount}\u2026`);
|
|
86795
|
+
else update("Reworking the canvas\u2026");
|
|
86787
86796
|
const editResult = await provider.editImage({
|
|
86788
86797
|
imagePath,
|
|
86789
86798
|
prompt,
|
|
@@ -86843,7 +86852,7 @@ async function handleEdit(imagePath, prompt, modelId, opts, json2) {
|
|
|
86843
86852
|
}
|
|
86844
86853
|
}
|
|
86845
86854
|
async function handleDescribe(imagePath, modelId, json2) {
|
|
86846
|
-
const spinner = json2 ? void 0 : ora("
|
|
86855
|
+
const spinner = json2 ? void 0 : ora("Studying the image\u2026").start();
|
|
86847
86856
|
const update = (s2) => {
|
|
86848
86857
|
if (spinner) spinner.text = s2;
|
|
86849
86858
|
};
|
|
@@ -86857,7 +86866,7 @@ async function handleDescribe(imagePath, modelId, json2) {
|
|
|
86857
86866
|
);
|
|
86858
86867
|
}
|
|
86859
86868
|
const imageUrl = await uploadToFal(imagePath, update);
|
|
86860
|
-
update("
|
|
86869
|
+
update("Reading the pixels\u2026");
|
|
86861
86870
|
const provider = new FalProvider();
|
|
86862
86871
|
const result = await provider.call(
|
|
86863
86872
|
modelDef.endpoint,
|
|
@@ -86888,7 +86897,7 @@ async function handleDescribe(imagePath, modelId, json2) {
|
|
|
86888
86897
|
}
|
|
86889
86898
|
}
|
|
86890
86899
|
async function handleUpscale(imagePath, modelId, opts, json2) {
|
|
86891
|
-
const spinner = json2 ? void 0 : ora("
|
|
86900
|
+
const spinner = json2 ? void 0 : ora("Enhancing resolution\u2026").start();
|
|
86892
86901
|
const update = (s2) => {
|
|
86893
86902
|
if (spinner) spinner.text = s2;
|
|
86894
86903
|
};
|
|
@@ -86898,7 +86907,7 @@ async function handleUpscale(imagePath, modelId, opts, json2) {
|
|
|
86898
86907
|
throw new GunniError(`Unknown model: ${modelId}`, "UNKNOWN_MODEL");
|
|
86899
86908
|
}
|
|
86900
86909
|
const imageUrl = await uploadToFal(imagePath, update);
|
|
86901
|
-
update("
|
|
86910
|
+
update("Adding more pixels\u2026");
|
|
86902
86911
|
const provider = new FalProvider();
|
|
86903
86912
|
const result = await provider.call(
|
|
86904
86913
|
modelDef.endpoint,
|
|
@@ -86947,7 +86956,7 @@ async function handleUpscale(imagePath, modelId, opts, json2) {
|
|
|
86947
86956
|
}
|
|
86948
86957
|
}
|
|
86949
86958
|
async function handleRemoveBg(imagePath, modelId, opts, json2) {
|
|
86950
|
-
const spinner = json2 ? void 0 : ora("
|
|
86959
|
+
const spinner = json2 ? void 0 : ora("Cutting out the background\u2026").start();
|
|
86951
86960
|
const update = (s2) => {
|
|
86952
86961
|
if (spinner) spinner.text = s2;
|
|
86953
86962
|
};
|
|
@@ -86957,7 +86966,7 @@ async function handleRemoveBg(imagePath, modelId, opts, json2) {
|
|
|
86957
86966
|
throw new GunniError(`Unknown model: ${modelId}`, "UNKNOWN_MODEL");
|
|
86958
86967
|
}
|
|
86959
86968
|
const imageUrl = await uploadToFal(imagePath, update);
|
|
86960
|
-
update("
|
|
86969
|
+
update("Snipping away\u2026");
|
|
86961
86970
|
const provider = new FalProvider();
|
|
86962
86971
|
const result = await provider.call(
|
|
86963
86972
|
modelDef.endpoint,
|
|
@@ -87044,7 +87053,7 @@ Run 'gunni list models --type video' for details.
|
|
|
87044
87053
|
"NO_API_KEY",
|
|
87045
87054
|
json2 ? void 0 : `Run ${import_picocolors4.default.bold("gunni")} to set up, or: gunni config --set-gunni-key YOUR_KEY`
|
|
87046
87055
|
);
|
|
87047
|
-
const spinner = json2 ? void 0 : ora("
|
|
87056
|
+
const spinner = json2 ? void 0 : ora("Rolling camera\u2026").start();
|
|
87048
87057
|
const update = (s2) => {
|
|
87049
87058
|
if (spinner) spinner.text = s2;
|
|
87050
87059
|
};
|
|
@@ -87101,7 +87110,7 @@ Run 'gunni list models --type video' for details.
|
|
|
87101
87110
|
}
|
|
87102
87111
|
}
|
|
87103
87112
|
const provider = getProviderForModel(modelId);
|
|
87104
|
-
update("
|
|
87113
|
+
update("Rendering frames\u2026");
|
|
87105
87114
|
const result = await provider.generateVideo({
|
|
87106
87115
|
prompt,
|
|
87107
87116
|
model: modelId,
|
|
@@ -87160,7 +87169,7 @@ Run 'gunni list models --type video' for details.
|
|
|
87160
87169
|
});
|
|
87161
87170
|
}
|
|
87162
87171
|
async function handleRemote2(input, opts, json2, apiKey, serverUrl) {
|
|
87163
|
-
const spinner = json2 ? void 0 : ora("
|
|
87172
|
+
const spinner = json2 ? void 0 : ora("Rolling camera\u2026").start();
|
|
87164
87173
|
const update = (s2) => {
|
|
87165
87174
|
if (spinner) spinner.text = s2;
|
|
87166
87175
|
};
|
|
@@ -87224,7 +87233,7 @@ async function handleRemote2(input, opts, json2, apiKey, serverUrl) {
|
|
|
87224
87233
|
if (imageUrl) toolArgs.image = imageUrl;
|
|
87225
87234
|
if (opts.duration !== void 0) toolArgs.duration = opts.duration;
|
|
87226
87235
|
if (opts.style) toolArgs.style = opts.style;
|
|
87227
|
-
update("
|
|
87236
|
+
update("Rendering frames\u2026");
|
|
87228
87237
|
const client2 = new RemoteClient();
|
|
87229
87238
|
await client2.connect(apiKey, serverUrl);
|
|
87230
87239
|
let result = await client2.callTool("video", toolArgs);
|
|
@@ -87250,7 +87259,7 @@ async function handleRemote2(input, opts, json2, apiKey, serverUrl) {
|
|
|
87250
87259
|
spinner?.fail("No video returned");
|
|
87251
87260
|
throw new GunniError("No video in remote response", "NO_VIDEO");
|
|
87252
87261
|
}
|
|
87253
|
-
update("
|
|
87262
|
+
update("Saving to disk\u2026");
|
|
87254
87263
|
const finalPath = await downloadMedia(videoAssetUrl, requestedPath, update);
|
|
87255
87264
|
let audioPath;
|
|
87256
87265
|
const audioAssetUrl = result.audio?.assetUrl;
|
|
@@ -87325,7 +87334,7 @@ Run 'gunni list models --type audio' for details.
|
|
|
87325
87334
|
"NO_API_KEY",
|
|
87326
87335
|
json2 ? void 0 : `Run ${import_picocolors5.default.bold("gunni")} to set up, or: gunni config --set-gunni-key YOUR_KEY`
|
|
87327
87336
|
);
|
|
87328
|
-
const spinner = json2 ? void 0 : ora("
|
|
87337
|
+
const spinner = json2 ? void 0 : ora("Finding the right voice\u2026").start();
|
|
87329
87338
|
const update = (s2) => {
|
|
87330
87339
|
if (spinner) spinner.text = s2;
|
|
87331
87340
|
};
|
|
@@ -87349,7 +87358,7 @@ Run 'gunni list models --type audio' for details.
|
|
|
87349
87358
|
falInput.audio_url = opts.voice;
|
|
87350
87359
|
}
|
|
87351
87360
|
}
|
|
87352
|
-
update("
|
|
87361
|
+
update("Recording the take\u2026");
|
|
87353
87362
|
const provider = new FalProvider();
|
|
87354
87363
|
const result = await provider.call(endpoint, falInput, update);
|
|
87355
87364
|
const data = result.data;
|
|
@@ -87401,7 +87410,7 @@ function getEndpoint(modelId) {
|
|
|
87401
87410
|
return model.endpoint;
|
|
87402
87411
|
}
|
|
87403
87412
|
async function handleRemote3(text, opts, json2, apiKey, serverUrl) {
|
|
87404
|
-
const spinner = json2 ? void 0 : ora("
|
|
87413
|
+
const spinner = json2 ? void 0 : ora("Finding the right voice\u2026").start();
|
|
87405
87414
|
const update = (s2) => {
|
|
87406
87415
|
if (spinner) spinner.text = s2;
|
|
87407
87416
|
};
|
|
@@ -87419,7 +87428,7 @@ async function handleRemote3(text, opts, json2, apiKey, serverUrl) {
|
|
|
87419
87428
|
throw new GunniError("No audio in remote response", "NO_AUDIO");
|
|
87420
87429
|
}
|
|
87421
87430
|
const requestedPath = opts.output ?? `gunni-audio-${Date.now()}.mp3`;
|
|
87422
|
-
update("
|
|
87431
|
+
update("Saving to disk\u2026");
|
|
87423
87432
|
const finalPath = await downloadMedia(audioAssetUrl, requestedPath, update);
|
|
87424
87433
|
spinner?.succeed("Done");
|
|
87425
87434
|
const output = {
|
|
@@ -87493,7 +87502,7 @@ Run 'gunni list models --type lipsync' for details.
|
|
|
87493
87502
|
"NO_API_KEY",
|
|
87494
87503
|
json2 ? void 0 : `Run ${import_picocolors6.default.bold("gunni")} to set up, or: gunni config --set-gunni-key YOUR_KEY`
|
|
87495
87504
|
);
|
|
87496
|
-
const spinner = json2 ? void 0 : ora("
|
|
87505
|
+
const spinner = json2 ? void 0 : ora("Matching lips to audio\u2026").start();
|
|
87497
87506
|
const update = (s2) => {
|
|
87498
87507
|
if (spinner) spinner.text = s2;
|
|
87499
87508
|
};
|
|
@@ -87506,7 +87515,7 @@ Run 'gunni list models --type lipsync' for details.
|
|
|
87506
87515
|
);
|
|
87507
87516
|
}
|
|
87508
87517
|
const provider = new FalProvider();
|
|
87509
|
-
update("
|
|
87518
|
+
update("Animating the performance\u2026");
|
|
87510
87519
|
const result = await provider.generateLipsync({
|
|
87511
87520
|
model: modelId,
|
|
87512
87521
|
videoPath: opts.video,
|
|
@@ -87556,7 +87565,7 @@ Run 'gunni list models --type lipsync' for details.
|
|
|
87556
87565
|
});
|
|
87557
87566
|
}
|
|
87558
87567
|
async function handleRemote4(audio, opts, json2, apiKey, serverUrl) {
|
|
87559
|
-
const spinner = json2 ? void 0 : ora("
|
|
87568
|
+
const spinner = json2 ? void 0 : ora("Matching lips to audio\u2026").start();
|
|
87560
87569
|
const update = (s2) => {
|
|
87561
87570
|
if (spinner) spinner.text = s2;
|
|
87562
87571
|
};
|
|
@@ -87591,7 +87600,7 @@ async function handleRemote4(audio, opts, json2, apiKey, serverUrl) {
|
|
|
87591
87600
|
};
|
|
87592
87601
|
if (videoUrl) toolArgs.video = videoUrl;
|
|
87593
87602
|
if (imageUrl) toolArgs.image = imageUrl;
|
|
87594
|
-
update("
|
|
87603
|
+
update("Animating the performance\u2026");
|
|
87595
87604
|
const client2 = new RemoteClient();
|
|
87596
87605
|
await client2.connect(apiKey, serverUrl);
|
|
87597
87606
|
let result = await client2.callTool("lipsync", toolArgs);
|
|
@@ -87617,7 +87626,7 @@ async function handleRemote4(audio, opts, json2, apiKey, serverUrl) {
|
|
|
87617
87626
|
throw new GunniError("No video in remote lip sync response", "NO_VIDEO");
|
|
87618
87627
|
}
|
|
87619
87628
|
const requestedPath = opts.output ?? `gunni-lipsync-${Date.now()}.mp4`;
|
|
87620
|
-
update("
|
|
87629
|
+
update("Saving to disk\u2026");
|
|
87621
87630
|
const finalPath = await downloadMedia(videoAssetUrl, requestedPath, update);
|
|
87622
87631
|
spinner?.succeed("Done");
|
|
87623
87632
|
const output = {
|
|
@@ -87884,7 +87893,7 @@ KEY PRINCIPLES
|
|
|
87884
87893
|
}
|
|
87885
87894
|
},
|
|
87886
87895
|
latest: {
|
|
87887
|
-
version: "0.3.
|
|
87896
|
+
version: "0.3.7",
|
|
87888
87897
|
date: "2026-03-29",
|
|
87889
87898
|
updates: [
|
|
87890
87899
|
"Production system: templates (proven prompts with variables), styles (visual direction), presets (platform rules), pipelines (multi-step workflows).",
|
|
@@ -87962,9 +87971,27 @@ ${import_picocolors8.default.dim("Run: gunni learn <topic>")}
|
|
|
87962
87971
|
`);
|
|
87963
87972
|
} else {
|
|
87964
87973
|
console.log(`
|
|
87965
|
-
${import_picocolors8.default.bold(result.title)}
|
|
87974
|
+
${import_picocolors8.default.bold(import_picocolors8.default.cyan(result.title))}
|
|
87966
87975
|
`);
|
|
87967
|
-
|
|
87976
|
+
const lines = result.content.split("\n");
|
|
87977
|
+
for (const line of lines) {
|
|
87978
|
+
if (/^[A-Z][A-Z _/()]+:/.test(line)) {
|
|
87979
|
+
const colonIdx = line.indexOf(":");
|
|
87980
|
+
console.log(`${import_picocolors8.default.bold(line.slice(0, colonIdx + 1))}${import_picocolors8.default.dim(line.slice(colonIdx + 1))}`);
|
|
87981
|
+
} else if (line.startsWith("- ")) {
|
|
87982
|
+
const dashEnd = line.indexOf(" ", 2);
|
|
87983
|
+
const toolMatch = line.match(/^- (\w+\(\)[^ ]*)(.*)/);
|
|
87984
|
+
if (toolMatch) {
|
|
87985
|
+
console.log(` ${import_picocolors8.default.green("\u2022")} ${import_picocolors8.default.cyan(toolMatch[1])}${import_picocolors8.default.dim(toolMatch[2])}`);
|
|
87986
|
+
} else {
|
|
87987
|
+
console.log(` ${import_picocolors8.default.green("\u2022")} ${line.slice(2)}`);
|
|
87988
|
+
}
|
|
87989
|
+
} else if (/^\d+\./.test(line)) {
|
|
87990
|
+
console.log(` ${import_picocolors8.default.dim(line)}`);
|
|
87991
|
+
} else {
|
|
87992
|
+
console.log(line);
|
|
87993
|
+
}
|
|
87994
|
+
}
|
|
87968
87995
|
console.log();
|
|
87969
87996
|
}
|
|
87970
87997
|
} catch (err) {
|
|
@@ -89384,7 +89411,8 @@ Examples:
|
|
|
89384
89411
|
console.log(`
|
|
89385
89412
|
${import_picocolors14.default.bold(import_picocolors14.default.cyan(category.toUpperCase()))}`);
|
|
89386
89413
|
for (const m2 of catModels) {
|
|
89387
|
-
|
|
89414
|
+
const tag = m2.isDefault ? import_picocolors14.default.green(" \u2605") : "";
|
|
89415
|
+
console.log(` ${import_picocolors14.default.bold(m2.id)}${tag} ${import_picocolors14.default.dim(m2.description)}`);
|
|
89388
89416
|
}
|
|
89389
89417
|
}
|
|
89390
89418
|
console.log();
|
|
@@ -90889,7 +90917,7 @@ async function runOnboarding() {
|
|
|
90889
90917
|
|
|
90890
90918
|
// src/index.ts
|
|
90891
90919
|
var program2 = new Command();
|
|
90892
|
-
program2.name("gunni").description("AI media toolkit \u2014 give any agent the ability to create professional media").version("0.3.
|
|
90920
|
+
program2.name("gunni").description("AI media toolkit \u2014 give any agent the ability to create professional media").version("0.3.7").option("--json", "Output results as JSON").addHelpText(
|
|
90893
90921
|
"after",
|
|
90894
90922
|
`
|
|
90895
90923
|
Examples:
|
|
@@ -90899,18 +90927,18 @@ Examples:
|
|
|
90899
90927
|
$ gunni init --template brand # Start a brand project
|
|
90900
90928
|
|
|
90901
90929
|
Image (generate, edit, describe, upscale, remove-bg):
|
|
90902
|
-
$ gunni image "a coffee bag on white background" -o bag
|
|
90903
|
-
$ gunni image bag.
|
|
90904
|
-
$ gunni image bag-clean.png "place on marble counter" -o hero
|
|
90905
|
-
$ gunni image hero.
|
|
90906
|
-
$ gunni image hero-final.
|
|
90930
|
+
$ gunni image "a coffee bag on white background" -o bag
|
|
90931
|
+
$ gunni image bag.jpg --remove-bg -o bag-clean
|
|
90932
|
+
$ gunni image bag-clean.png "place on marble counter" -o hero
|
|
90933
|
+
$ gunni image hero.jpg --upscale -o hero-final
|
|
90934
|
+
$ gunni image hero-final.jpg # describe
|
|
90907
90935
|
|
|
90908
90936
|
Video & audio:
|
|
90909
|
-
$ gunni video hero.
|
|
90937
|
+
$ gunni video hero.jpg -p "slow cinematic zoom in" -o hero.mp4
|
|
90910
90938
|
$ gunni audio "Welcome to our roastery" -o intro.mp3
|
|
90911
90939
|
|
|
90912
90940
|
Explore with variants:
|
|
90913
|
-
$ gunni image "logo concepts" --variants 4 -o logo-{n}
|
|
90941
|
+
$ gunni image "logo concepts" --variants 4 -o logo-{n}
|
|
90914
90942
|
|
|
90915
90943
|
Creative expertise:
|
|
90916
90944
|
$ gunni learn exploration # How to explore creatively
|
|
@@ -90919,8 +90947,8 @@ Examples:
|
|
|
90919
90947
|
Agent workflow (structured JSON):
|
|
90920
90948
|
$ gunni --json learn overview # Load capabilities
|
|
90921
90949
|
$ gunni --json image "product photo" --variants 3 # Explore
|
|
90922
|
-
$ gunni --json image best.
|
|
90923
|
-
$ gunni --json image final.
|
|
90950
|
+
$ gunni --json image best.jpg "refine the lighting" # Iterate
|
|
90951
|
+
$ gunni --json image final.jpg --upscale # Polish
|
|
90924
90952
|
`
|
|
90925
90953
|
);
|
|
90926
90954
|
registerImageCommand(program2);
|
|
@@ -90941,7 +90969,7 @@ program2.command("models").description("List available models (alias for: gunni
|
|
|
90941
90969
|
return;
|
|
90942
90970
|
}
|
|
90943
90971
|
if (models.length === 0) {
|
|
90944
|
-
console.log(`No models found${opts.type ? ` for category "${opts.type}"` : ""}.`);
|
|
90972
|
+
console.log(import_picocolors23.default.dim(`No models found${opts.type ? ` for category "${opts.type}"` : ""}.`));
|
|
90945
90973
|
return;
|
|
90946
90974
|
}
|
|
90947
90975
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -90952,9 +90980,10 @@ program2.command("models").description("List available models (alias for: gunni
|
|
|
90952
90980
|
}
|
|
90953
90981
|
for (const [category, catModels] of grouped) {
|
|
90954
90982
|
console.log(`
|
|
90955
|
-
${category.toUpperCase()}`);
|
|
90983
|
+
${import_picocolors23.default.bold(import_picocolors23.default.cyan(category.toUpperCase()))}`);
|
|
90956
90984
|
for (const m2 of catModels) {
|
|
90957
|
-
|
|
90985
|
+
const tag = m2.isDefault ? import_picocolors23.default.green(" \u2605") : "";
|
|
90986
|
+
console.log(` ${import_picocolors23.default.bold(m2.id)}${tag} ${import_picocolors23.default.dim(m2.description)}`);
|
|
90958
90987
|
}
|
|
90959
90988
|
}
|
|
90960
90989
|
console.log();
|
|
@@ -90988,7 +91017,7 @@ program2.action(async () => {
|
|
|
90988
91017
|
{ name: "models", usage: "gunni models [--type <category>]", description: "List available models" },
|
|
90989
91018
|
{ name: "config", usage: "gunni config", description: "Manage API keys" }
|
|
90990
91019
|
];
|
|
90991
|
-
console.log(JSON.stringify({ version: "0.3.
|
|
91020
|
+
console.log(JSON.stringify({ version: "0.3.7", commands, categories, models }, null, 2));
|
|
90992
91021
|
return;
|
|
90993
91022
|
}
|
|
90994
91023
|
const configured = await hasGunniKey();
|
|
@@ -91044,10 +91073,10 @@ ${import_picocolors23.default.bold("Models:")} ${import_picocolors23.default.dim
|
|
|
91044
91073
|
}
|
|
91045
91074
|
console.log(`
|
|
91046
91075
|
${import_picocolors23.default.bold("Quick start:")}
|
|
91047
|
-
${import_picocolors23.default.dim("$")} gunni image "coffee bag product shot" -o bag
|
|
91048
|
-
${import_picocolors23.default.dim("$")} gunni image bag.
|
|
91049
|
-
${import_picocolors23.default.dim("$")} gunni image bag-clean.png "on marble counter" -o hero
|
|
91050
|
-
${import_picocolors23.default.dim("$")} gunni image hero.
|
|
91076
|
+
${import_picocolors23.default.dim("$")} gunni image "coffee bag product shot" -o bag
|
|
91077
|
+
${import_picocolors23.default.dim("$")} gunni image bag.jpg --remove-bg -o bag-clean
|
|
91078
|
+
${import_picocolors23.default.dim("$")} gunni image bag-clean.png "on marble counter" -o hero
|
|
91079
|
+
${import_picocolors23.default.dim("$")} gunni image hero.jpg --upscale -o hero-final
|
|
91051
91080
|
|
|
91052
91081
|
${import_picocolors23.default.dim("Add --json to any command for structured output.")}
|
|
91053
91082
|
${import_picocolors23.default.dim("Run gunni learn to load creative expertise.")}
|