@doufunao123/asset-gateway 0.22.0 → 0.22.2
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 +404 -55
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command12 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/auth.ts
|
|
7
7
|
import { existsSync as existsSync2, unlinkSync } from "fs";
|
|
@@ -15,7 +15,7 @@ import { AssetForgeError } from "@doufunao123/assetforge-sdk";
|
|
|
15
15
|
|
|
16
16
|
// src/meta.ts
|
|
17
17
|
var CLI_NAME = "asset-gateway";
|
|
18
|
-
var CLI_VERSION = "0.
|
|
18
|
+
var CLI_VERSION = "0.22.2";
|
|
19
19
|
var CLI_DESCRIPTION = "Universal asset generation gateway CLI";
|
|
20
20
|
var DEFAULT_GATEWAY_URL = "https://asset.origingame.dev";
|
|
21
21
|
|
|
@@ -599,6 +599,7 @@ function createDescribeCommand() {
|
|
|
599
599
|
// src/commands/generate.ts
|
|
600
600
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
601
601
|
import { dirname as dirname2, extname, join as join2 } from "path";
|
|
602
|
+
import { AssetForgeError as AssetForgeError3 } from "@doufunao123/assetforge-sdk";
|
|
602
603
|
import { Command as Command3 } from "commander";
|
|
603
604
|
function inferExtension(assetType) {
|
|
604
605
|
const map = {
|
|
@@ -613,7 +614,17 @@ function inferExtension(assetType) {
|
|
|
613
614
|
prop: "glb",
|
|
614
615
|
text: "txt",
|
|
615
616
|
sprite: "png",
|
|
616
|
-
world: "spz"
|
|
617
|
+
world: "spz",
|
|
618
|
+
animation: "glb",
|
|
619
|
+
material: "zip",
|
|
620
|
+
hdri: "hdr",
|
|
621
|
+
vfx: "zip",
|
|
622
|
+
lut: "cube",
|
|
623
|
+
shader: "glsl",
|
|
624
|
+
font_typeface: "json",
|
|
625
|
+
skybox: "png",
|
|
626
|
+
decal: "png",
|
|
627
|
+
heightmap: "png"
|
|
617
628
|
};
|
|
618
629
|
return map[assetType] ?? "bin";
|
|
619
630
|
}
|
|
@@ -661,7 +672,9 @@ function inferMimeType(filePath) {
|
|
|
661
672
|
".jpeg": "image/jpeg",
|
|
662
673
|
".png": "image/png",
|
|
663
674
|
".webp": "image/webp",
|
|
664
|
-
".gif": "image/gif"
|
|
675
|
+
".gif": "image/gif",
|
|
676
|
+
".mp4": "video/mp4",
|
|
677
|
+
".mov": "video/quicktime"
|
|
665
678
|
};
|
|
666
679
|
return map[ext] ?? "application/octet-stream";
|
|
667
680
|
}
|
|
@@ -681,6 +694,10 @@ function parseCommaSeparatedValues(raw) {
|
|
|
681
694
|
}
|
|
682
695
|
return String(raw).split(",").map((value) => value.trim()).filter(Boolean);
|
|
683
696
|
}
|
|
697
|
+
function collectValue(value, previous = []) {
|
|
698
|
+
previous.push(value);
|
|
699
|
+
return previous;
|
|
700
|
+
}
|
|
684
701
|
async function saveOutput(result, assetType, outputDir, preferredFormat) {
|
|
685
702
|
const ext = inferExtFromResult(result) ?? infer3dExtension(preferredFormat) ?? inferExtension(assetType);
|
|
686
703
|
const timestamp = Date.now();
|
|
@@ -747,18 +764,66 @@ function assertHas3dInput(prompt, image, images) {
|
|
|
747
764
|
function toJsonObject(value) {
|
|
748
765
|
return value;
|
|
749
766
|
}
|
|
767
|
+
function isPackOnlyResult(value) {
|
|
768
|
+
return value.ok === false && value.pack_only === true;
|
|
769
|
+
}
|
|
770
|
+
async function runGeneratedAssetCommand(command, sdkMethod, commandName, assetType, options) {
|
|
771
|
+
const ctx = createContext(command);
|
|
772
|
+
const generate = ctx.client[sdkMethod];
|
|
773
|
+
const data = await generate.call(ctx.client, String(options.prompt), {
|
|
774
|
+
provider: options.provider,
|
|
775
|
+
model: options.model,
|
|
776
|
+
size: options.size,
|
|
777
|
+
quality: options.quality,
|
|
778
|
+
background: options.background,
|
|
779
|
+
output_format: options.outputFormat,
|
|
780
|
+
n: options.n ? Number(options.n) : void 0,
|
|
781
|
+
preset: options.preset,
|
|
782
|
+
transparent: options.transparent ? true : void 0,
|
|
783
|
+
input: toInputFile(options.input)
|
|
784
|
+
});
|
|
785
|
+
if (isPackOnlyResult(data)) {
|
|
786
|
+
throw new AssetForgeError3("This asset type requires a library pack. Run: asset-gateway pack list", {
|
|
787
|
+
code: "PACK_ONLY",
|
|
788
|
+
details: data
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
const localPath = await saveOutput(data, assetType, String(options.outputDir ?? "."));
|
|
792
|
+
if (localPath) data.local_path = localPath;
|
|
793
|
+
printSuccess(commandName, data, ctx);
|
|
794
|
+
}
|
|
795
|
+
function createGeneratedAssetCommand(name, sdkMethod, assetType, description) {
|
|
796
|
+
const command = new Command3(name).description(description).requiredOption("--prompt <text>", "Asset description prompt").option("--provider <id>", "Provider to use").option("--model <model>", "Model to use").option("--size <size>", "Output size when supported").option("--input <path>", "Input file path or URL when supported").option("--quality <quality>", "Image quality: low, medium, high").option("--background <background>", "Image background: auto, opaque, transparent").option("--output-format <fmt>", "Image output format: png, webp, jpeg").option("--n <num>", "Number of image variants (1-10)").option("--preset <preset>", "Image preset id").option("--transparent", "Request transparent background when supported").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
797
|
+
const commandName = `generate.${assetType}`;
|
|
798
|
+
try {
|
|
799
|
+
await runGeneratedAssetCommand(this, sdkMethod, commandName, assetType, options);
|
|
800
|
+
} catch (error2) {
|
|
801
|
+
printError(commandName, error2);
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
if (name === "font-typeface") {
|
|
805
|
+
command.alias("font_typeface");
|
|
806
|
+
}
|
|
807
|
+
return command;
|
|
808
|
+
}
|
|
750
809
|
function createGenerateCommand() {
|
|
751
810
|
const command = new Command3("generate").description("Generate assets via the gateway");
|
|
752
811
|
command.addCommand(
|
|
753
|
-
new Command3("image").description("Generate an image from a text prompt").requiredOption("--prompt <text>", "Image description prompt").option("--provider <id>", "Provider to use").option("--transparent", "Request transparent background").option("--model <model>", "Model to use").option("--size <size>", "Image size (e.g. 1024x1024)").option("--input <url>", "Input image URL for editing (Gemini/Grok)").option("--ref <urls...>", "Reference image URLs for multi-image editing (repeatable)").option("--edit-mode <mode>", "Edit mode: edit, inpaint, restyle, expand").option("--session <id>", "Session ID for multi-turn editing").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
812
|
+
new Command3("image").description("Generate an image from a text prompt").requiredOption("--prompt <text>", "Image description prompt").option("--provider <id>", "Provider to use").option("--transparent", "Request transparent background").option("--model <model>", "Model to use").option("--size <size>", "Image size (e.g. 1024x1024)").option("--quality <quality>", "Image quality: low, medium, high").option("--background <background>", "Image background: auto, opaque, transparent").option("--output-format <fmt>", "Image output format: png, webp, jpeg").option("--n <num>", "Number of image variants (1-10)").option("--preset <preset>", "Image preset id").option("--mask <path>", "PNG alpha mask path or URL for inpainting").option("--input <url>", "Input image URL for editing (Gemini/Grok)").option("--ref <urls...>", "Reference image URLs for multi-image editing (repeatable)").option("--edit-mode <mode>", "Edit mode: edit, inpaint, restyle, expand").option("--session <id>", "Session ID for multi-turn editing").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
754
813
|
try {
|
|
755
814
|
const ctx = createContext(this);
|
|
756
815
|
const data = await ctx.client.image(options.prompt, {
|
|
757
816
|
provider: options.provider,
|
|
758
817
|
model: options.model,
|
|
759
818
|
size: options.size,
|
|
819
|
+
quality: options.quality,
|
|
820
|
+
background: options.background,
|
|
821
|
+
output_format: options.outputFormat,
|
|
822
|
+
n: options.n ? Number(options.n) : void 0,
|
|
823
|
+
preset: options.preset,
|
|
824
|
+
mask: toInputFile(options.mask),
|
|
760
825
|
transparent: options.transparent ? true : void 0,
|
|
761
|
-
input: options.input,
|
|
826
|
+
input: toInputFile(options.input),
|
|
762
827
|
reference_images: options.ref,
|
|
763
828
|
edit_mode: options.editMode,
|
|
764
829
|
session_id: options.session
|
|
@@ -1012,12 +1077,21 @@ function createGenerateCommand() {
|
|
|
1012
1077
|
})
|
|
1013
1078
|
);
|
|
1014
1079
|
command.addCommand(
|
|
1015
|
-
new Command3("world").description("Generate a 3D world/environment using WorldLabs Marble").
|
|
1080
|
+
new Command3("world").description("Generate a 3D world/environment using WorldLabs Marble").option("--prompt <text>", "Text prompt describing the environment").option("--input <path>", "Input image (local path or URL) for image-to-world").option("--image <path>", "Input image (local path or URL) for image-to-world").option("--panorama <path>", "360 panorama image path or URL").option("--video <path>", "Input video path or URL").option("--multi-image <path>", "Multi-view image path or URL (repeatable)", collectValue, []).option("--quality <quality>", "World quality: low, high").option("--model <model>", "Model: marble-1.0-draft, marble-1.0, marble-1.1, marble-1.1-plus", "marble-1.1").option("--display-name <name>", "Display name for the generated world").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
1016
1081
|
try {
|
|
1082
|
+
const prompt = options.prompt ?? "";
|
|
1083
|
+
const multiImage = options.multiImage.map((value) => toInputFile(value)).filter((value) => Boolean(value));
|
|
1084
|
+
if (!prompt && !options.input && !options.image && !options.panorama && !options.video && multiImage.length === 0) {
|
|
1085
|
+
throw new Error("Provide at least one of --prompt, --image, --input, --panorama, --video, or --multi-image");
|
|
1086
|
+
}
|
|
1017
1087
|
const ctx = createContext(this);
|
|
1018
|
-
const data = await ctx.client.world(
|
|
1019
|
-
input: toInputFile(options.input),
|
|
1088
|
+
const data = await ctx.client.world(prompt, {
|
|
1089
|
+
input: toInputFile(options.input ?? options.image),
|
|
1020
1090
|
model: options.model,
|
|
1091
|
+
panorama_url: toInputFile(options.panorama),
|
|
1092
|
+
video_url: toInputFile(options.video),
|
|
1093
|
+
multi_image_url: multiImage.length > 0 ? multiImage : void 0,
|
|
1094
|
+
quality: options.quality,
|
|
1021
1095
|
display_name: options.displayName
|
|
1022
1096
|
});
|
|
1023
1097
|
const localPath = await saveOutput(data, "world", options.outputDir);
|
|
@@ -1028,6 +1102,36 @@ function createGenerateCommand() {
|
|
|
1028
1102
|
}
|
|
1029
1103
|
})
|
|
1030
1104
|
);
|
|
1105
|
+
command.addCommand(
|
|
1106
|
+
createGeneratedAssetCommand("animation", "animation", "animation", "Generate a 3D animation clip with Meshy AI")
|
|
1107
|
+
);
|
|
1108
|
+
command.addCommand(
|
|
1109
|
+
createGeneratedAssetCommand("material", "material", "material", "Resolve a PBR material from library packs")
|
|
1110
|
+
);
|
|
1111
|
+
command.addCommand(
|
|
1112
|
+
createGeneratedAssetCommand("hdri", "hdri", "hdri", "Resolve an HDRI environment from library packs")
|
|
1113
|
+
);
|
|
1114
|
+
command.addCommand(
|
|
1115
|
+
createGeneratedAssetCommand("vfx", "vfx", "vfx", "Resolve a Three.js VFX bundle from library packs")
|
|
1116
|
+
);
|
|
1117
|
+
command.addCommand(
|
|
1118
|
+
createGeneratedAssetCommand("lut", "lut", "lut", "Resolve a LUT cube from library packs")
|
|
1119
|
+
);
|
|
1120
|
+
command.addCommand(
|
|
1121
|
+
createGeneratedAssetCommand("shader", "shader", "shader", "Resolve a GLSL shader from library packs")
|
|
1122
|
+
);
|
|
1123
|
+
command.addCommand(
|
|
1124
|
+
createGeneratedAssetCommand("font-typeface", "fontTypeface", "font_typeface", "Resolve a Three.js typeface font from library packs")
|
|
1125
|
+
);
|
|
1126
|
+
command.addCommand(
|
|
1127
|
+
createGeneratedAssetCommand("skybox", "skybox", "skybox", "Generate an equirectangular skybox image")
|
|
1128
|
+
);
|
|
1129
|
+
command.addCommand(
|
|
1130
|
+
createGeneratedAssetCommand("decal", "decal", "decal", "Generate a transparent decal image")
|
|
1131
|
+
);
|
|
1132
|
+
command.addCommand(
|
|
1133
|
+
createGeneratedAssetCommand("heightmap", "heightmap", "heightmap", "Generate a grayscale terrain heightmap")
|
|
1134
|
+
);
|
|
1031
1135
|
return command;
|
|
1032
1136
|
}
|
|
1033
1137
|
|
|
@@ -1075,21 +1179,34 @@ function createJobCommand() {
|
|
|
1075
1179
|
}
|
|
1076
1180
|
|
|
1077
1181
|
// src/commands/library.ts
|
|
1182
|
+
import { readFile, writeFile } from "fs/promises";
|
|
1183
|
+
import { AssetForgeError as AssetForgeError4 } from "@doufunao123/assetforge-sdk";
|
|
1078
1184
|
import { Command as Command5 } from "commander";
|
|
1079
1185
|
function createLibraryCommand() {
|
|
1080
1186
|
const command = new Command5("library").description(
|
|
1081
1187
|
"Search and manage the asset library"
|
|
1082
1188
|
);
|
|
1083
1189
|
command.addCommand(
|
|
1084
|
-
new Command5("search").description("Search the asset library").argument("[query]", "Search query").option("-t, --type <type>", "Filter by asset type (audio, music, image, etc.)").option("--tags <tags>", "Filter by tags (comma-separated)").option("--source <source>", "Filter by source (manual, generated, imported)").option("-n, --limit <limit>", "Max results", "20").option("--offset <offset>", "Offset for pagination", "0").action(async function(query) {
|
|
1190
|
+
new Command5("search").description("Search the asset library").argument("[query]", "Search query").option("-q, --query <query>", "Search query").option("-t, --type <type>", "Filter by asset type (audio, music, image, etc.)").option("--tags <tags>", "Filter by tags (comma-separated)").option("--source <source>", "Filter by source (manual, generated, imported)").option("--mode <mode>", "Search mode (fts, vector, hybrid)").option("--style <style>", "Filter by visual style").option("--composition <composition>", "Filter by composition").option("--lighting <lighting>", "Filter by lighting").option("--color-tone <tone>", "Filter by color tone").option("--mood <mood>", "Filter by mood (comma-separated)").option("--theme <theme>", "Filter by theme (comma-separated)").option("--era <era>", "Filter by era").option("--rig-name <rig>", "Filter by exact rig name").option("--compatible-rig <rig>", "Filter by compatible rig").option("--no-rerank", "Disable LLM reranking").option("-n, --limit <limit>", "Max results", "20").option("--offset <offset>", "Offset for pagination", "0").action(async function(query) {
|
|
1085
1191
|
const ctx = createContext(this);
|
|
1086
1192
|
const opts = this.opts();
|
|
1087
1193
|
try {
|
|
1088
1194
|
const data = await ctx.client.library.search({
|
|
1089
|
-
q: query,
|
|
1195
|
+
q: opts.query ?? query,
|
|
1090
1196
|
type: opts.type,
|
|
1091
1197
|
tags: opts.tags,
|
|
1092
1198
|
source: opts.source,
|
|
1199
|
+
mode: opts.mode,
|
|
1200
|
+
style: opts.style,
|
|
1201
|
+
composition: opts.composition,
|
|
1202
|
+
lighting: opts.lighting,
|
|
1203
|
+
color_tone: opts.colorTone,
|
|
1204
|
+
mood: opts.mood,
|
|
1205
|
+
theme: opts.theme,
|
|
1206
|
+
era: opts.era,
|
|
1207
|
+
rig_name: opts.rigName,
|
|
1208
|
+
compatible_rig: opts.compatibleRig,
|
|
1209
|
+
rerank: opts.rerank,
|
|
1093
1210
|
limit: Number(opts.limit),
|
|
1094
1211
|
offset: Number(opts.offset)
|
|
1095
1212
|
});
|
|
@@ -1099,6 +1216,88 @@ function createLibraryCommand() {
|
|
|
1099
1216
|
}
|
|
1100
1217
|
})
|
|
1101
1218
|
);
|
|
1219
|
+
command.addCommand(
|
|
1220
|
+
new Command5("related").description("Find rig-compatible related assets").argument("<id>", "Library item ID").option("-t, --type <type>", "Filter related assets by type").option("-n, --limit <limit>", "Max results", "20").action(async function(id) {
|
|
1221
|
+
const ctx = createContext(this);
|
|
1222
|
+
const opts = this.opts();
|
|
1223
|
+
try {
|
|
1224
|
+
const data = await ctx.client.library.related(id, {
|
|
1225
|
+
type: opts.type,
|
|
1226
|
+
limit: Number(opts.limit)
|
|
1227
|
+
});
|
|
1228
|
+
printSuccess("library.related", data, ctx);
|
|
1229
|
+
} catch (error2) {
|
|
1230
|
+
printError("library.related", error2, ctx.human);
|
|
1231
|
+
}
|
|
1232
|
+
})
|
|
1233
|
+
);
|
|
1234
|
+
command.addCommand(
|
|
1235
|
+
new Command5("bundle").description("Download a zip bundle of library assets").argument("<ids...>", "Library item IDs").requiredOption("-o, --output <path>", "Output zip path").action(async function(ids) {
|
|
1236
|
+
const ctx = createContext(this);
|
|
1237
|
+
const opts = this.opts();
|
|
1238
|
+
try {
|
|
1239
|
+
const blob = await ctx.client.library.bundle({ asset_ids: ids, format: "zip" });
|
|
1240
|
+
const buffer = Buffer.from(await blob.arrayBuffer());
|
|
1241
|
+
await writeFile(opts.output, buffer);
|
|
1242
|
+
printSuccess(
|
|
1243
|
+
"library.bundle",
|
|
1244
|
+
{ output: opts.output, bytes: buffer.length, asset_ids: ids },
|
|
1245
|
+
ctx
|
|
1246
|
+
);
|
|
1247
|
+
} catch (error2) {
|
|
1248
|
+
printError("library.bundle", error2, ctx.human);
|
|
1249
|
+
}
|
|
1250
|
+
})
|
|
1251
|
+
);
|
|
1252
|
+
command.addCommand(
|
|
1253
|
+
new Command5("ingest").description("Queue or run a library ingest job (admin only)").requiredOption("--source <source>", "Ingest source (manual, generated, pack, imported)").requiredOption("-t, --type <type>", "Asset type").option("--file-url <url>", "Public asset URL").option("--file <path>", "Local file to encode as base64").option("--thumbnail-url <url>", "Thumbnail URL").option("--name <name>", "Display name").option("--tag <tag>", "User tag (repeatable)", collect, []).option("--source-job-id <id>", "Source generate job ID").option("--pack-id <id>", "Pack ID").option("--pack-asset-key <key>", "Pack asset key").option("--sync", "Run ingest synchronously and return the library result").action(async function() {
|
|
1254
|
+
const ctx = createContext(this);
|
|
1255
|
+
const opts = this.opts();
|
|
1256
|
+
try {
|
|
1257
|
+
const request = {
|
|
1258
|
+
source: opts.source,
|
|
1259
|
+
asset_type: opts.type,
|
|
1260
|
+
file_url: opts.fileUrl,
|
|
1261
|
+
file_data_b64: opts.file ? await readBase64(opts.file) : void 0,
|
|
1262
|
+
thumbnail_url: opts.thumbnailUrl,
|
|
1263
|
+
name: opts.name,
|
|
1264
|
+
user_tags: opts.tag,
|
|
1265
|
+
source_job_id: opts.sourceJobId,
|
|
1266
|
+
pack_id: opts.packId,
|
|
1267
|
+
pack_asset_key: opts.packAssetKey
|
|
1268
|
+
};
|
|
1269
|
+
const data = opts.sync ? await ctx.client.library.ingestSync(request) : await ctx.client.library.ingest(request);
|
|
1270
|
+
printSuccess(opts.sync ? "library.ingest_sync" : "library.ingest", data, ctx);
|
|
1271
|
+
} catch (error2) {
|
|
1272
|
+
printError("library.ingest", error2, ctx.human);
|
|
1273
|
+
}
|
|
1274
|
+
})
|
|
1275
|
+
);
|
|
1276
|
+
command.addCommand(
|
|
1277
|
+
new Command5("ingest-status").description("Get a library ingest job status").argument("<id>", "Ingest job ID").action(async function(id) {
|
|
1278
|
+
const ctx = createContext(this);
|
|
1279
|
+
try {
|
|
1280
|
+
const data = await ctx.client.library.ingestStatus(id);
|
|
1281
|
+
printSuccess("library.ingest_status", data, ctx);
|
|
1282
|
+
} catch (error2) {
|
|
1283
|
+
printError("library.ingest_status", error2, ctx.human);
|
|
1284
|
+
}
|
|
1285
|
+
})
|
|
1286
|
+
);
|
|
1287
|
+
command.addCommand(
|
|
1288
|
+
new Command5("ingest-wait").description("Poll a library ingest job until completion").argument("<id>", "Ingest job ID").option("--interval-ms <ms>", "Polling interval", "1000").action(async function(id) {
|
|
1289
|
+
const ctx = createContext(this);
|
|
1290
|
+
const opts = this.opts();
|
|
1291
|
+
try {
|
|
1292
|
+
const data = await ctx.client.library.ingestWait(id, {
|
|
1293
|
+
intervalMs: Number(opts.intervalMs)
|
|
1294
|
+
});
|
|
1295
|
+
printSuccess("library.ingest_wait", data, ctx);
|
|
1296
|
+
} catch (error2) {
|
|
1297
|
+
printError("library.ingest_wait", error2, ctx.human);
|
|
1298
|
+
}
|
|
1299
|
+
})
|
|
1300
|
+
);
|
|
1102
1301
|
command.addCommand(
|
|
1103
1302
|
new Command5("add").description("Add an item to the asset library").requiredOption("--name <name>", "Display name").requiredOption("--url <url>", "File URL (public)").requiredOption("-t, --type <type>", "Asset type (audio, music, image, etc.)").option("-d, --description <desc>", "Description").option("--tags <tags>", "Comma-separated tags").option("--duration <seconds>", "Duration in seconds (for audio/video)").option("--source <source>", "Source (manual, generated, imported)", "manual").action(async function() {
|
|
1104
1303
|
const ctx = createContext(this);
|
|
@@ -1161,20 +1360,169 @@ function createLibraryCommand() {
|
|
|
1161
1360
|
}
|
|
1162
1361
|
})
|
|
1163
1362
|
);
|
|
1363
|
+
command.addCommand(
|
|
1364
|
+
new Command5("backfill").description("Queue library embedding/enrichment backfill jobs (admin)").option("-t, --asset-type <type>", "Filter by asset type").option("--since <date>", "Only backfill assets created after this RFC3339 date").option("-n, --limit <limit>", "Max items to enqueue", "100").option("--dry-run", "Return matching IDs without enqueueing jobs").action(async function() {
|
|
1365
|
+
const ctx = createContext(this);
|
|
1366
|
+
const opts = this.opts();
|
|
1367
|
+
try {
|
|
1368
|
+
const request = {
|
|
1369
|
+
asset_type: opts.assetType,
|
|
1370
|
+
since: opts.since,
|
|
1371
|
+
limit: Number(opts.limit),
|
|
1372
|
+
dry_run: Boolean(opts.dryRun)
|
|
1373
|
+
};
|
|
1374
|
+
const data = await ctx.client.library.backfill(request);
|
|
1375
|
+
printSuccess("library.backfill", data, ctx);
|
|
1376
|
+
} catch (error2) {
|
|
1377
|
+
printError("library.backfill", error2, ctx.human);
|
|
1378
|
+
}
|
|
1379
|
+
})
|
|
1380
|
+
);
|
|
1381
|
+
command.addCommand(
|
|
1382
|
+
new Command5("reenrich").description("Queue library re-enrichment jobs (admin)").option("--id <id>", "Library item ID (repeatable)", collect, []).option("-t, --asset-type <type>", "Filter by asset type").option("--taxonomy-version-lt <version>", "Only items below this taxonomy version").option("--force-visual", "Force visual/textual analysis", true).option("--no-force-visual", "Do not force visual/textual analysis").option("--recompute-embedding", "Recompute embedding vectors").option("-n, --limit <limit>", "Max items to enqueue", "100").action(async function() {
|
|
1383
|
+
const ctx = createContext(this);
|
|
1384
|
+
const opts = this.opts();
|
|
1385
|
+
try {
|
|
1386
|
+
const request = {
|
|
1387
|
+
ids: opts.id,
|
|
1388
|
+
asset_type: opts.assetType,
|
|
1389
|
+
taxonomy_version_lt: opts.taxonomyVersionLt ? Number(opts.taxonomyVersionLt) : void 0,
|
|
1390
|
+
force_visual: opts.forceVisual,
|
|
1391
|
+
recompute_embedding: Boolean(opts.recomputeEmbedding),
|
|
1392
|
+
limit: Number(opts.limit)
|
|
1393
|
+
};
|
|
1394
|
+
const data = await ctx.client.library.reenrich(request);
|
|
1395
|
+
printSuccess("library.reenrich", data, ctx);
|
|
1396
|
+
} catch (error2) {
|
|
1397
|
+
printError("library.reenrich", error2, ctx.human);
|
|
1398
|
+
}
|
|
1399
|
+
})
|
|
1400
|
+
);
|
|
1401
|
+
return command;
|
|
1402
|
+
}
|
|
1403
|
+
function collect(value, previous) {
|
|
1404
|
+
previous.push(value);
|
|
1405
|
+
return previous;
|
|
1406
|
+
}
|
|
1407
|
+
async function readBase64(filePath) {
|
|
1408
|
+
try {
|
|
1409
|
+
return (await readFile(filePath)).toString("base64");
|
|
1410
|
+
} catch (error2) {
|
|
1411
|
+
throw new AssetForgeError4(
|
|
1412
|
+
`Failed to read file ${filePath}: ${error2 instanceof Error ? error2.message : String(error2)}`,
|
|
1413
|
+
{ code: "CONFIG_ERROR" }
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
// src/commands/pack.ts
|
|
1419
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
1420
|
+
import { createInterface } from "readline/promises";
|
|
1421
|
+
import { stdin as input, stdout as output2 } from "process";
|
|
1422
|
+
import { AssetForgeError as AssetForgeError5 } from "@doufunao123/assetforge-sdk";
|
|
1423
|
+
import { Command as Command6 } from "commander";
|
|
1424
|
+
function createPackCommand() {
|
|
1425
|
+
const command = new Command6("pack").description("Manage library asset packs");
|
|
1426
|
+
command.addCommand(
|
|
1427
|
+
new Command6("list").description("List installed library packs").action(async function() {
|
|
1428
|
+
const ctx = createContext(this);
|
|
1429
|
+
try {
|
|
1430
|
+
const data = await ctx.client.library.packs();
|
|
1431
|
+
printSuccess("pack.list", data, ctx);
|
|
1432
|
+
} catch (error2) {
|
|
1433
|
+
printError("pack.list", error2, ctx.human);
|
|
1434
|
+
}
|
|
1435
|
+
})
|
|
1436
|
+
);
|
|
1437
|
+
command.addCommand(
|
|
1438
|
+
new Command6("install").description("Install a library pack").argument("[source]", "Pack source (builtin, url, upload)").option("--source <source>", "Pack source (builtin, url, upload)").option("--id <id>", "Builtin pack ID").option("--version <version>", "Pack version").option("--url <url>", "HTTP tarball URL").option("--file <tarball>", "Local tarball to upload as base64").action(async function(sourceArg) {
|
|
1439
|
+
const ctx = createContext(this);
|
|
1440
|
+
const opts = this.opts();
|
|
1441
|
+
try {
|
|
1442
|
+
const source = opts.source ?? sourceArg;
|
|
1443
|
+
if (!source) {
|
|
1444
|
+
throw new AssetForgeError5("Pack source is required", { code: "CONFIG_ERROR" });
|
|
1445
|
+
}
|
|
1446
|
+
const request = {
|
|
1447
|
+
source,
|
|
1448
|
+
id: opts.id,
|
|
1449
|
+
version: opts.version,
|
|
1450
|
+
url: opts.url,
|
|
1451
|
+
tarball_b64: opts.file ? await readBase642(opts.file) : void 0
|
|
1452
|
+
};
|
|
1453
|
+
const data = await ctx.client.library.packsInstall(request);
|
|
1454
|
+
printSuccess("pack.install", data, ctx);
|
|
1455
|
+
} catch (error2) {
|
|
1456
|
+
printError("pack.install", error2, ctx.human);
|
|
1457
|
+
}
|
|
1458
|
+
})
|
|
1459
|
+
);
|
|
1460
|
+
command.addCommand(
|
|
1461
|
+
new Command6("delete").description("Delete a library pack (admin only)").argument("<id>", "Pack ID").option("-y, --yes", "Skip confirmation prompt").action(async function(id) {
|
|
1462
|
+
const ctx = createContext(this);
|
|
1463
|
+
const opts = this.opts();
|
|
1464
|
+
try {
|
|
1465
|
+
if (!opts.yes) {
|
|
1466
|
+
await confirmDelete(id);
|
|
1467
|
+
}
|
|
1468
|
+
const data = await ctx.client.library.packsDelete(id);
|
|
1469
|
+
printSuccess("pack.delete", data, ctx);
|
|
1470
|
+
} catch (error2) {
|
|
1471
|
+
printError("pack.delete", error2, ctx.human);
|
|
1472
|
+
}
|
|
1473
|
+
})
|
|
1474
|
+
);
|
|
1475
|
+
command.addCommand(
|
|
1476
|
+
new Command6("refresh").description("Refresh an installed library pack (admin only)").argument("<id>", "Pack ID").action(async function(id) {
|
|
1477
|
+
const ctx = createContext(this);
|
|
1478
|
+
try {
|
|
1479
|
+
const data = await ctx.client.library.packsRefresh(id);
|
|
1480
|
+
printSuccess("pack.refresh", data, ctx);
|
|
1481
|
+
} catch (error2) {
|
|
1482
|
+
printError("pack.refresh", error2, ctx.human);
|
|
1483
|
+
}
|
|
1484
|
+
})
|
|
1485
|
+
);
|
|
1164
1486
|
return command;
|
|
1165
1487
|
}
|
|
1488
|
+
async function readBase642(filePath) {
|
|
1489
|
+
try {
|
|
1490
|
+
return (await readFile2(filePath)).toString("base64");
|
|
1491
|
+
} catch (error2) {
|
|
1492
|
+
throw new AssetForgeError5(
|
|
1493
|
+
`Failed to read file ${filePath}: ${error2 instanceof Error ? error2.message : String(error2)}`,
|
|
1494
|
+
{ code: "CONFIG_ERROR" }
|
|
1495
|
+
);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
async function confirmDelete(id) {
|
|
1499
|
+
if (!input.isTTY) {
|
|
1500
|
+
throw new AssetForgeError5("Refusing to delete pack without confirmation. Pass --yes to confirm.", {
|
|
1501
|
+
code: "CONFIG_ERROR"
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
1504
|
+
const rl = createInterface({ input, output: output2 });
|
|
1505
|
+
try {
|
|
1506
|
+
const answer = await rl.question(`Delete pack ${id}? Type the pack ID to confirm: `);
|
|
1507
|
+
if (answer !== id) {
|
|
1508
|
+
throw new AssetForgeError5("Pack deletion cancelled", { code: "CONFIG_ERROR" });
|
|
1509
|
+
}
|
|
1510
|
+
} finally {
|
|
1511
|
+
rl.close();
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1166
1514
|
|
|
1167
1515
|
// src/commands/process.ts
|
|
1168
1516
|
import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
1169
1517
|
import { existsSync as existsSync4 } from "fs";
|
|
1170
1518
|
import { join as join3 } from "path";
|
|
1171
|
-
import { Command as
|
|
1172
|
-
function readInputAsBase64(
|
|
1173
|
-
if (existsSync4(
|
|
1174
|
-
const bytes = readFileSync3(
|
|
1519
|
+
import { Command as Command7 } from "commander";
|
|
1520
|
+
function readInputAsBase64(input2) {
|
|
1521
|
+
if (existsSync4(input2)) {
|
|
1522
|
+
const bytes = readFileSync3(input2);
|
|
1175
1523
|
return `data:image/png;base64,${bytes.toString("base64")}`;
|
|
1176
1524
|
}
|
|
1177
|
-
return
|
|
1525
|
+
return input2;
|
|
1178
1526
|
}
|
|
1179
1527
|
function saveProcessOutput(data, outputDir) {
|
|
1180
1528
|
mkdirSync3(outputDir, { recursive: true });
|
|
@@ -1202,9 +1550,9 @@ function saveProcessOutput(data, outputDir) {
|
|
|
1202
1550
|
return filePath;
|
|
1203
1551
|
}
|
|
1204
1552
|
function createProcessCommand() {
|
|
1205
|
-
const command = new
|
|
1553
|
+
const command = new Command7("process").description("Post-process images (crop, resize, compose, remove-bg)");
|
|
1206
1554
|
command.addCommand(
|
|
1207
|
-
new
|
|
1555
|
+
new Command7("crop").description("Smart crop an image (trim transparent borders)").requiredOption("--input <path>", "Input image (file path or URL)").option("--mode <mode>", "Crop mode: tightest or power_of2", "tightest").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
1208
1556
|
try {
|
|
1209
1557
|
const ctx = createContext(this);
|
|
1210
1558
|
const data = await ctx.client.process({
|
|
@@ -1220,7 +1568,7 @@ function createProcessCommand() {
|
|
|
1220
1568
|
})
|
|
1221
1569
|
);
|
|
1222
1570
|
command.addCommand(
|
|
1223
|
-
new
|
|
1571
|
+
new Command7("resize").description("Resize an image to exact dimensions").requiredOption("--input <path>", "Input image (file path or URL)").requiredOption("--width <n>", "Target width").requiredOption("--height <n>", "Target height").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
1224
1572
|
try {
|
|
1225
1573
|
const ctx = createContext(this);
|
|
1226
1574
|
const data = await ctx.client.process({
|
|
@@ -1236,7 +1584,7 @@ function createProcessCommand() {
|
|
|
1236
1584
|
})
|
|
1237
1585
|
);
|
|
1238
1586
|
command.addCommand(
|
|
1239
|
-
new
|
|
1587
|
+
new Command7("compose").description("Compose multiple images into a sprite sheet").requiredOption("--input <paths...>", "Input images (files or URLs)").option("--direction <dir>", "Layout: horizontal, vertical, grid", "horizontal").option("--columns <n>", "Columns for grid layout").option("--padding <n>", "Padding between frames in px", "0").option("--frame-width <n>", "Normalize each frame to this width").option("--frame-height <n>", "Normalize each frame to this height").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
1240
1588
|
try {
|
|
1241
1589
|
const ctx = createContext(this);
|
|
1242
1590
|
const inputs = Array.isArray(options.input) ? options.input : [options.input];
|
|
@@ -1260,7 +1608,7 @@ function createProcessCommand() {
|
|
|
1260
1608
|
})
|
|
1261
1609
|
);
|
|
1262
1610
|
command.addCommand(
|
|
1263
|
-
new
|
|
1611
|
+
new Command7("remove-bg").description("Remove background from image(s)").requiredOption("--input <paths...>", "Input images (files or URLs)").option("--bg-color <color>", "Background color hint for fallback (e.g. white, black)").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
1264
1612
|
try {
|
|
1265
1613
|
const ctx = createContext(this);
|
|
1266
1614
|
const inputs = Array.isArray(options.input) ? options.input : [options.input];
|
|
@@ -1284,7 +1632,7 @@ function createProcessCommand() {
|
|
|
1284
1632
|
// src/commands/process3d.ts
|
|
1285
1633
|
import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
1286
1634
|
import { join as join4 } from "path";
|
|
1287
|
-
import { Command as
|
|
1635
|
+
import { Command as Command8 } from "commander";
|
|
1288
1636
|
function infer3dExtension2(format) {
|
|
1289
1637
|
const map = {
|
|
1290
1638
|
fbx: "fbx",
|
|
@@ -1335,9 +1683,9 @@ async function saveProcess3dOutput(data, operation, outputDir, format) {
|
|
|
1335
1683
|
return filePath;
|
|
1336
1684
|
}
|
|
1337
1685
|
function createProcess3dCommand() {
|
|
1338
|
-
const command = new
|
|
1686
|
+
const command = new Command8("process3d").description("3D model post-processing via Meshy AI");
|
|
1339
1687
|
command.addCommand(
|
|
1340
|
-
new
|
|
1688
|
+
new Command8("remesh").description("Remesh a model and optionally change format or polygon count").option("--task-id <id>", "Meshy task ID").option("--model-url <url>", "Model URL to remesh without an existing task").requiredOption("--format <fmt>", "Target format: glb, fbx, obj, usdz, stl, 3mf").option("--polycount <n>", "Target polygon count").option("--topology <type>", "Topology type: triangle or quad").option("--auto-size", "Estimate real-world size automatically").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
1341
1689
|
try {
|
|
1342
1690
|
if (!options.taskId && !options.modelUrl) {
|
|
1343
1691
|
throw new Error("Either --task-id or --model-url is required");
|
|
@@ -1364,7 +1712,7 @@ function createProcess3dCommand() {
|
|
|
1364
1712
|
})
|
|
1365
1713
|
);
|
|
1366
1714
|
command.addCommand(
|
|
1367
|
-
new
|
|
1715
|
+
new Command8("retexture").description("Regenerate textures for an existing Meshy model").requiredOption("--task-id <id>", "Meshy task ID").option("--prompt <text>", "Text style prompt for the new material pass").option("--style-image <input>", "Texture style reference image URL or local file path").option("--pbr", "Enable PBR materials").option("--hd-texture", "Request 4K texture output").option("--ai-model <name>", "Meshy model: meshy-5, meshy-6, latest").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
1368
1716
|
try {
|
|
1369
1717
|
const ctx = createContext(this);
|
|
1370
1718
|
const params = {};
|
|
@@ -1387,7 +1735,7 @@ function createProcess3dCommand() {
|
|
|
1387
1735
|
})
|
|
1388
1736
|
);
|
|
1389
1737
|
command.addCommand(
|
|
1390
|
-
new
|
|
1738
|
+
new Command8("rig").description("Rig a Meshy model for character animation").option("--task-id <id>", "Meshy task ID").option("--height <meters>", "Estimated character height in meters").option("--model-url <url>", "Model URL to rig without an existing task").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
1391
1739
|
try {
|
|
1392
1740
|
if (!options.taskId && !options.modelUrl) {
|
|
1393
1741
|
throw new Error("Either --task-id or --model-url is required");
|
|
@@ -1410,7 +1758,7 @@ function createProcess3dCommand() {
|
|
|
1410
1758
|
})
|
|
1411
1759
|
);
|
|
1412
1760
|
command.addCommand(
|
|
1413
|
-
new
|
|
1761
|
+
new Command8("animate").description("Apply a preset animation to a rigged Meshy character").requiredOption("--task-id <id>", "Meshy rigging task ID").requiredOption("--action-id <n>", "Animation preset ID (see docs for full list)").option("--fps <n>", "Target frame rate: 24, 25, 30, or 60").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
1414
1762
|
try {
|
|
1415
1763
|
const ctx = createContext(this);
|
|
1416
1764
|
const params = {
|
|
@@ -1433,7 +1781,7 @@ function createProcess3dCommand() {
|
|
|
1433
1781
|
})
|
|
1434
1782
|
);
|
|
1435
1783
|
command.addCommand(
|
|
1436
|
-
new
|
|
1784
|
+
new Command8("refine").description("Refine a Meshy preview model into a higher quality result").requiredOption("--task-id <id>", "Meshy preview task ID").option("--pbr", "Enable PBR materials").option("--hd-texture", "Request 4K texture output").option("--texture-prompt <text>", "Optional texture prompt for the refinement pass").option("--ai-model <name>", "Meshy model: meshy-5, meshy-6, latest").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
1437
1785
|
try {
|
|
1438
1786
|
const ctx = createContext(this);
|
|
1439
1787
|
const params = {};
|
|
@@ -1458,11 +1806,11 @@ function createProcess3dCommand() {
|
|
|
1458
1806
|
}
|
|
1459
1807
|
|
|
1460
1808
|
// src/commands/provider.ts
|
|
1461
|
-
import { Command as
|
|
1809
|
+
import { Command as Command9 } from "commander";
|
|
1462
1810
|
function createProviderCommand() {
|
|
1463
|
-
const command = new
|
|
1811
|
+
const command = new Command9("provider").description("Provider management");
|
|
1464
1812
|
command.addCommand(
|
|
1465
|
-
new
|
|
1813
|
+
new Command9("list").description("List available providers").action(async function() {
|
|
1466
1814
|
try {
|
|
1467
1815
|
const ctx = createContext(this);
|
|
1468
1816
|
const data = await ctx.client.providers.list();
|
|
@@ -1473,7 +1821,7 @@ function createProviderCommand() {
|
|
|
1473
1821
|
})
|
|
1474
1822
|
);
|
|
1475
1823
|
command.addCommand(
|
|
1476
|
-
new
|
|
1824
|
+
new Command9("health").description("Check provider health").argument("[name]", "Specific provider name").action(async function(name) {
|
|
1477
1825
|
try {
|
|
1478
1826
|
const ctx = createContext(this);
|
|
1479
1827
|
const data = name ? await ctx.client.providers.health(name) : await ctx.client.providers.health();
|
|
@@ -1487,14 +1835,14 @@ function createProviderCommand() {
|
|
|
1487
1835
|
}
|
|
1488
1836
|
|
|
1489
1837
|
// src/commands/upload.ts
|
|
1490
|
-
import { readFile } from "fs/promises";
|
|
1838
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
1491
1839
|
import { basename } from "path";
|
|
1492
|
-
import { AssetForgeError as
|
|
1493
|
-
import { Command as
|
|
1840
|
+
import { AssetForgeError as AssetForgeError6 } from "@doufunao123/assetforge-sdk";
|
|
1841
|
+
import { Command as Command10 } from "commander";
|
|
1494
1842
|
function createUploadCommand() {
|
|
1495
|
-
const command = new
|
|
1843
|
+
const command = new Command10("upload").description("Upload and manage assets");
|
|
1496
1844
|
command.addCommand(
|
|
1497
|
-
new
|
|
1845
|
+
new Command10("file").description("Upload a file and get a public URL").argument("<path>", "Path to file to upload").action(async function(filePath) {
|
|
1498
1846
|
const ctx = createContext(this);
|
|
1499
1847
|
try {
|
|
1500
1848
|
const content = await readLocalFile(filePath);
|
|
@@ -1506,7 +1854,7 @@ function createUploadCommand() {
|
|
|
1506
1854
|
})
|
|
1507
1855
|
);
|
|
1508
1856
|
command.addCommand(
|
|
1509
|
-
new
|
|
1857
|
+
new Command10("list").description("List uploaded assets").action(async function() {
|
|
1510
1858
|
const ctx = createContext(this);
|
|
1511
1859
|
try {
|
|
1512
1860
|
const data = await ctx.client.assets.list();
|
|
@@ -1517,7 +1865,7 @@ function createUploadCommand() {
|
|
|
1517
1865
|
})
|
|
1518
1866
|
);
|
|
1519
1867
|
command.addCommand(
|
|
1520
|
-
new
|
|
1868
|
+
new Command10("delete").description("Delete an uploaded asset (admin only)").argument("<filename>", "Filename to delete").action(async function(filename) {
|
|
1521
1869
|
const ctx = createContext(this);
|
|
1522
1870
|
try {
|
|
1523
1871
|
const data = await ctx.client.assets.delete(filename);
|
|
@@ -1531,9 +1879,9 @@ function createUploadCommand() {
|
|
|
1531
1879
|
}
|
|
1532
1880
|
async function readLocalFile(filePath) {
|
|
1533
1881
|
try {
|
|
1534
|
-
return await
|
|
1882
|
+
return await readFile3(filePath);
|
|
1535
1883
|
} catch (error2) {
|
|
1536
|
-
throw new
|
|
1884
|
+
throw new AssetForgeError6(
|
|
1537
1885
|
`Failed to read file ${filePath}: ${error2 instanceof Error ? error2.message : String(error2)}`,
|
|
1538
1886
|
{ code: "CONFIG_ERROR" }
|
|
1539
1887
|
);
|
|
@@ -1543,11 +1891,11 @@ async function readLocalFile(filePath) {
|
|
|
1543
1891
|
// src/commands/voice.ts
|
|
1544
1892
|
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
1545
1893
|
import { dirname as dirname3, extname as extname2 } from "path";
|
|
1546
|
-
import { Command as
|
|
1894
|
+
import { Command as Command11 } from "commander";
|
|
1547
1895
|
function createVoiceCommand() {
|
|
1548
|
-
const command = new
|
|
1896
|
+
const command = new Command11("voice").description("Design, clone, list, and delete voices");
|
|
1549
1897
|
command.addCommand(
|
|
1550
|
-
new
|
|
1898
|
+
new Command11("design").description("Generate a MiMo voice from a text description").requiredOption("--voice-prompt <text>", "Voice description / style prompt").requiredOption("--preview-text <text>", "Text to synthesize for preview").option("--style <text>", "Additional director/style instruction").option("--name <name>", "Save generated voice with this name").option("--save-as <name>", "Alias for --name").option("--output <path>", "Write preview WAV to this path").action(async function(options) {
|
|
1551
1899
|
const ctx = createContext(this);
|
|
1552
1900
|
try {
|
|
1553
1901
|
const request = {
|
|
@@ -1567,7 +1915,7 @@ function createVoiceCommand() {
|
|
|
1567
1915
|
})
|
|
1568
1916
|
);
|
|
1569
1917
|
command.addCommand(
|
|
1570
|
-
new
|
|
1918
|
+
new Command11("clone").description("Clone a MiMo voice from an mp3/wav sample").requiredOption("--audio <path-or-data-url>", "Voice sample mp3/wav file or data URL").requiredOption("--preview-text <text>", "Text to synthesize for preview").option("--audio-mime <mime>", "Audio MIME type when --audio is raw base64").option("--style <text>", "Director/style instruction").option("--name <name>", "Save cloned voice with this name").option("--save-as <name>", "Alias for --name").option("--output <path>", "Write preview WAV to this path").action(async function(options) {
|
|
1571
1919
|
const ctx = createContext(this);
|
|
1572
1920
|
try {
|
|
1573
1921
|
const sample = readVoiceSample(options.audio, options.audioMime);
|
|
@@ -1588,7 +1936,7 @@ function createVoiceCommand() {
|
|
|
1588
1936
|
})
|
|
1589
1937
|
);
|
|
1590
1938
|
command.addCommand(
|
|
1591
|
-
new
|
|
1939
|
+
new Command11("list").description("List saved voices").option("--type <type>", "Voice type: vc or vd").action(async function(options) {
|
|
1592
1940
|
const ctx = createContext(this);
|
|
1593
1941
|
try {
|
|
1594
1942
|
const data = await ctx.client.voice.list({ type: options.type });
|
|
@@ -1599,7 +1947,7 @@ function createVoiceCommand() {
|
|
|
1599
1947
|
})
|
|
1600
1948
|
);
|
|
1601
1949
|
command.addCommand(
|
|
1602
|
-
new
|
|
1950
|
+
new Command11("delete").description("Delete a saved voice").argument("<voice-id>", "Voice ID").option("--type <type>", "Voice type: vc or vd").action(async function(voiceId, options) {
|
|
1603
1951
|
const ctx = createContext(this);
|
|
1604
1952
|
try {
|
|
1605
1953
|
const data = await ctx.client.voice.delete(voiceId, { type: options.type });
|
|
@@ -1611,17 +1959,17 @@ function createVoiceCommand() {
|
|
|
1611
1959
|
);
|
|
1612
1960
|
return command;
|
|
1613
1961
|
}
|
|
1614
|
-
function readVoiceSample(
|
|
1615
|
-
if (
|
|
1616
|
-
return { sample_data_url:
|
|
1962
|
+
function readVoiceSample(input2, audioMime) {
|
|
1963
|
+
if (input2.startsWith("data:")) {
|
|
1964
|
+
return { sample_data_url: input2 };
|
|
1617
1965
|
}
|
|
1618
|
-
if (existsSync6(
|
|
1966
|
+
if (existsSync6(input2)) {
|
|
1619
1967
|
return {
|
|
1620
|
-
audio_base64: readFileSync5(
|
|
1621
|
-
audio_mime: audioMime ?? inferAudioMime(
|
|
1968
|
+
audio_base64: readFileSync5(input2).toString("base64"),
|
|
1969
|
+
audio_mime: audioMime ?? inferAudioMime(input2)
|
|
1622
1970
|
};
|
|
1623
1971
|
}
|
|
1624
|
-
return { audio_base64:
|
|
1972
|
+
return { audio_base64: input2, audio_mime: audioMime ?? "audio/wav" };
|
|
1625
1973
|
}
|
|
1626
1974
|
function inferAudioMime(filePath) {
|
|
1627
1975
|
const ext = extname2(filePath).toLowerCase();
|
|
@@ -1647,13 +1995,14 @@ function stripDataUri2(data) {
|
|
|
1647
1995
|
}
|
|
1648
1996
|
|
|
1649
1997
|
// src/index.ts
|
|
1650
|
-
var program = new
|
|
1998
|
+
var program = new Command12().name("asset-gateway").description("Universal asset generation gateway CLI").version(CLI_VERSION).option(
|
|
1651
1999
|
"--gateway-url <url>",
|
|
1652
2000
|
`Gateway URL (default: $ASSET_GATEWAY_URL, auth config, or ${DEFAULT_GATEWAY_URL})`
|
|
1653
2001
|
).option("--token <token>", "API token for authentication").option("--human", "Human-readable output instead of JSON").option("--fields <fields>", "Comma-separated list of output fields");
|
|
1654
2002
|
program.addCommand(createAuthCommand());
|
|
1655
2003
|
program.addCommand(createGenerateCommand());
|
|
1656
2004
|
program.addCommand(createLibraryCommand());
|
|
2005
|
+
program.addCommand(createPackCommand());
|
|
1657
2006
|
program.addCommand(createProcessCommand());
|
|
1658
2007
|
program.addCommand(createProcess3dCommand());
|
|
1659
2008
|
program.addCommand(createProviderCommand());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doufunao123/asset-gateway",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.2",
|
|
4
4
|
"description": "Universal asset generation gateway CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"node": ">=20"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@doufunao123/assetforge-sdk": "^0.
|
|
30
|
+
"@doufunao123/assetforge-sdk": "^0.8.0",
|
|
31
31
|
"commander": "^13.1.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|